Redis笔记1--Redis快速入门

来源:互联网 发布:windows live下载地址 编辑:程序博客网 时间:2024/04/28 01:17

前言:

redis-benchmark           检测redis性能

通过redis客户端远程连接服务: redis-cli  -h xxx.xxx.xxx.xxx -p 6379

数据库

与关系型数据库概念一样,redis中一个数据库包含一组数据。典型的数据库应用案例就是将一个程序的所有数据组织起来,与另一个程序的数据保持独立。
redis中,数据库简单使用一个数字编号来进行辨认,默认数据库编号为0.通过select来进行切换。

关键字和值(keys and values)

  • 关键字(keys):用来标识数据块,如:user:leto  表示名为leto的用户。冒号没有任何特殊含义,在redis中常用分隔符来组织关键字
  • 值(values):与关键字对应的实际值,可以是任何东西,如:字符串,整数,序列化对象(JSON,XML或其他格式)。redis会把值看做是一个字节序列。

查询(Querying)

在redis中,关键字就是一切,值是没有任何意义的,redis不允许通过值来进行查询

存储器和持久化(Memory and Persistence)

默认情况下,redis根据已变更的关键字数量来进行判断,然后在磁盘里创建数据库的快照(snapshot)。如果x个关键字变更,那么每隔Y秒存储数据库一次。默认情况下,如果1000个或更多的关键字已变更,redis会每隔60秒存储数据库,如果9个或更少的关键字已变更,redis会每隔15min存储数据库。
redis会将所有数据都保留在存储器(内存)中。
redis测试,使用redis-benchmark.exe

数据结构

5种redis数据结构,string,list,set,hash,zset。都有公用的一些命令如:DEL,TYPE,RENAME等等
flushdb    清空数据库中的所有值

字符串(String)

字符串是最基本的数据结构。存储string,int,float三种数据类型

set:向redis添加key-value值

get:获取key的值

del:删除指定key的值

strlen:获取关键字对应值的长度

append:将value附加在已存在的关键字对应值中(关键字不存在就新建)

incr:值增加,字符串中保存的必须是integer类型

incrby:

decr:

decrby:值减少,字符串中保存的必须是integer类型


setrange:从指定偏移量开始替换值


getrange:返回指定范围内的关键字对应值,start  end



进阶用例:使用setbit和getbit。来解决web中常见的问题“今天有多少用户访问”。spool,bitmaps

由于通过关键字来获取一个值非常快,字符串数据结构常被用来缓存数据。


setbit:对key所存储的字符串值,设置或清除指定偏移量上的位(bit),0或1。


bittop:

bitcount:

散列(Hashes)

散列数据结构很像字符串数据结构。区别 在于,散列数据结构提供了一个额外的间接层:一个域(Field)。hset  user:lvss  age  9000。age就是Field域
相关操作还包括在同一时间设置多个域,同一时间获取多个域,获取所有的域和值,列出所有的域后者删除指定的一个域

hset       添加值
hget       获取值
hmset   设置多个值
hmget   获取多个值
hgetall   获取所有值
hkeys     列出所有的field域
hdel         删除指定的值
在应用中一般可以通过hash来保存一个对象的数据信息
散列数据结构比普通的字符串数据结构具有更多的可操作性。可以使用散列数据结构去获得更精确的描述,是存储一个用户,而不是一个序列化对象。好处就是能够操作具体的数据片段,不必获取或写入整个值。

列表(List)

对于一个给定的关键字,列表数据结构可以存储和处理一组值。可以添加一个值到列表里,获取列表的第一个值或最后一个值以及用给的索引来处理值。列表数据结构维护了值的顺序,提供了基于索引的高效操作。如:为了跟踪在网站里注册的最新用户,可以维护一个newusers的列表。


底层是链表结构(Linked-list),存储有序的值

lpush         向列表头添加值

rpush        向列表尾添加值

lpop          从列表头弹出值

rpop          从列表尾弹出值

lindex        从指定索引的位置获取值

ltrim          清除列表指定范围外的所有值

lrange      获取列表指定范围的所有值


可以使用列表数据结构去存储日志,也可以用来跟踪用户浏览网站时的路径。

常用来记录工作队列,最近浏览的文章,常用联系人等信息。


blpop:列表的阻塞式弹出原语,从列表删除并返回第一个元素,没有任何元素可以弹出便阻塞
brpop:阻塞式,弹出列表中的尾部元素

rpoplpush:

brpoplpush:


集合(Sets)

使用哈希表(hash table)结构存储,存储唯一的值。没有对值进行排序。


sadd       向集合中添加值

srem       从集合中删除值

sismember      快速查询集合中是否包含某值

smembers       获取集合中所有值,对大数据量的列表操作会慢,慎用

sinter         查看集合的值,返回多个集合的交集

sinterstore         在指定集合中存储sinter的结果

sunion         查看并集

sdiff             查看差集


scard        :查看集合中元素的数量

srandmember : 获取集合中的随机元素

spop        :移除并返回集合中的一个随机元素

smove   a   b  member : 将member元素从集合a移到集合b


对于需要用到集合操作的地方(如,交集intersection和并集union,差集difference),推荐使用集合数据结构


分类集合(Sorted Sets)

最强大的数据结构。如果说散列数据结构类似于字符串数据结构,主要是区分域(Field)的概念;那么分类集合数据结构就是类似域集合数据结构,主要区分是标记(score)的概念。


存储的也是key-value形式的值,key(member)唯一,value(score)限制为float类型

标记提供了排序(sorting)和秩划分(ranking)的功能。如果我们想要一个秩划分类的朋友名单,如:


zadd              向集合添加值

zrange          返回指定区间内的值,按score值从小到大排序,相同score按字典顺序排序

zrangebyscore     返回指定score区间内的值

zrem          删除值

zcount           计算指定范围内的值数量

zrank            获取集合中指定值的排行,由小到大从0开始排

zrevrank        获取排行,由大到小从0开始排


zinterstore :将指定的多个zset进行交集,分数默认相加。


zunionstore:将指定的多个zset进行并集,分数默认相加。


使用数据结构

  • 常数时间复杂度O(1)被认为是最快速的。如sismember命令
  • 对数时间复杂度O(log(N))被认为是第二快速的,通过使需扫描的区间不断皱缩来快速完成处理。如zadd
  • 线性时间复杂度O(N),在表格的非索引列里进行查找就需要O(N)次操作。如ltrim
  • O(log(N)+M),如zremrangebyscore移除集合中所有score值介于min和max之间的值(包括等于)

仿多关键字查询(Pseudo MultiKey Queries)

场景:通过不同的关键字去查询相同的值,如:根据用户id或用户邮件去查询用户信息。最直接的方法就是根据两个关键字存两次用户数据(数据量翻倍,管理麻烦)。

使用hashes散列表来解决,通过域(Field)来作为一个二级索引,然后 去引用单个用户对象。

使用散列表来保存一个查询的索引,key是用户邮箱,value是 对象的唯一标识(如,id,用户名等)。
查询时,根据邮箱去散列表中查询出用户名,然后根据用户名去查询具体的用户信息。

引用和索引(References and Indexes)

如上所示,对于那些值与值间的索引和引用,我们都必须手动去管理。
集合数据结构常被用来实现这类索引,如:

其中每个值:zhangsan,lisi,wangwu,zhaoilu都是redis字符串数据结构的引用,每个引用的值都是一个用户的具体信息。

由于建立了索引,所以需要额外的索引值的处理和内存的消耗,这些开销可以进一步优化。由此可见在redis中手动管理引用确实很棘手。

数据交互和流水线(Round  Trips  and Pipelining)

与服务器频繁交互是Redis的一种常见模式。
许多命令能够接受一个或更多的参数,也有一种关联命令(sister-command)可以接受多个参数,如mget返回给定key(一个或多个key)的值

sadd       可以添加一个或多个成员到集合中。

流水线功能

当客户端发送请求到Redis后,在发送下一个请求之前必须等待redis的答复。使用流水线功能,可以发送多个请求,而不需要等待redis的响应。不但减少网络开销,还能获得性能上的显著提高

redis会使用存储器去排列命令,如果要执行的命令需要大概50个字符的关键字,则大概可以对此进行数千或数万的批量操作。

事务(Transactions)

redis命令都具有原子性,包括一次处理多项事情的命令。对于使用多个命令,redis支持事务功能。
redis实际上是单线程运行的,这就是为什么每个redis命令都能够保证具有原子性。当一个命令在执行的时候没有其他命令会运行(Scaling)

inrc  实际上是一个get命令然后紧随一个set命令
getset     设置一个新的值然后返回原始值
setnx    (set   if   not   exists) 先测试关键字是否存在,只有当关键字不存在时才设置值。

实际开发时,往往需要运行具有原子性的一组命令。
  1. 首先执行multi命令,标记一个事务块的开始。事务块内的多条命令会按照先后顺序被放进一个队列中
  2. 然后执行exec,执行事务块中的所有命令
  3. 或者执行discard,取消事务,放弃执行事务块中的所有命令
事务功能特点:
  • 事务中的命令将会按顺序的执行
  • 事务中的命令将会如单个原子操作般被执行(中途不会有其他客户端命令被执行)
  • 事务中的命令要么全部被执行,要么不会执行

虽然redis是单线程运行的,但是我们可以同时运行多个redis客户端。如此,多个客户端进程操作用一个数据就会有问题。

通过添加watch来解决:监视一个(或多个)key,如果在事务执行之前这个(或这些)key被其他命令所改动,那么事务将被打断。

在调用watch后,如果另一个客户端改变了zhangsan的值,事务将会运行失败。

关键字反例(Keys Anti-Pattern)

keys命令,查找所有符合给定模式pattern的key
这个命令看起来很适合一些任务,但不应该在实际的产品代码里面。因为这个命令通过线性扫描所有的关键字来进行匹配,可能照成性能问题。
实际应用中使用散列结构或集合来替代。

实际应用中通过散列结构解决:

数据使用期限(Expiration)

redis允许标记一个关键字的使用期限。可以给予一个Unix时间戳形式(自1970-01-01 起)的绝对时间,或者一个基于秒的存活时间。是一个基于关键字的命令。

expire            设定key的生存时间,以秒为单位
expire   zhangsan  13
ttl     查看key的剩余生存时间
persist                      删除关键字的生存时间

setex        是一个原子性操作,在同一时间完成关联值和生存时间的设置。非常实用

发布和订阅(publish/subscribe)

监听者去订阅(subscribe)指定的频道(channel)。消息发布者(publishers)向指定的频道(channel)发布消息。所有监听指定频道的人,在连接期间,将会接收到发给这个频道的所有消息。

subscribe:订阅指定的一个或多个频道
unsubscribe:取消对指定的频道的订阅
publish:将信息发布到指定频道
psubscribe:将匹配指定模式的频道,如  news.*,就是匹配以news.开头的所有频道
punsubscribe:取消对匹配的频道的订阅



问题:
一.老的redis版本中,客户端订阅频道后,读取信息不够快,导致redis自己会缓存这些信息。如果这些信息多了后,就会造成系统变慢或崩溃。
二.数据传输可靠性,客户端订阅频道断开连接了,然后在客户端重连期间发布了消息,客户端再也接收不到这个消息了。

监控和延迟日志

monitor          实时打印出redis服务器接收到的命令,调试用(实际生产环境谨慎使用)。
slowlog
slow  log是redis用来记录查询执行时间的日志系统,该时间不包括像客户端响应(talking),发送回复等IO操作,单单是执行一个查询命令所耗费的时间。slow log保存在内存里面,读写速度非常快,不必担心因开启slow log 而损害redis的速度。
配置slow log参数:
slowlog-log-slower-than  100        记录所有查询时间>=100微秒的查询
slowlog-max-len 1000        slow log 最多保存1000条记录,slow log 是一个FIFO队列,记录数量超出时,最旧的一条日志被删除,新的日志加入队列。

默认记录1024条日志

slowlog  get                获取slow log 日志队列中的信息

slowlog     get  4     获取队列中编号为4及以后的记录,从0开始编号


排序(Sort)

sort 允许我们对list,set,zset集合根据key进行排序。sort就像sql语句中的 order  by 条件。

对字符串和数字排序是有区别的,如: 对"110","12"排序和对 110,12排序就不一样。


sort   返回给定列表,集合,有序集合key中经过排序的元素(有序集合是通过标记来进行排序,而不是集合里的成员),排序默认以数字作为对象,不会改变原来的集合

sort  desc    降序排序

limit  offset count     分页,该修饰符限制返回结果,offset:要跳过的元素数量,count跳过  offset指定个元素后,要返回多少个对象

alpha           表示根据字典顺序排序,而不是根据数值


sort   命令的正真厉害之处是基于引用对象进行排序的能力。

0 0