代码改变世界

Redis常用特性

2018-11-04 04:12  DoPeter  阅读(1021)  评论(0编辑  收藏  举报

发布订阅

·服务器状态在pubsub_channels字典保存了所有频道的订阅关系:SUBSCRIBE命令负责将客户端和被订阅的频道关联到这个字典里面,而UNSUBSCRIBE命令则负责解除客户端和被退订频道之间的关联。

·服务器状态在pubsub_patterns链表保存了所有模式的订阅关系:PSUBSCRIBE命令负责将客户端和被订阅的模式记录到这个链表中,而PUNSUBSCRIBE命令则负责移除客户端和被退订模式在链表中的记录。

·PUBLISH命令通过访问pubsub_channels字典来向频道的所有订阅者发送消息,通过访问pubsub_patterns链表来向所有匹配频道的模式的订阅者发送消息。

·PUBSUB命令的三个子命令都是通过读取pubsub_channels字典和pubsub_patterns链表中的信息来实现的。

 

更多命令

http://www.runoob.com/redis/redis-pub-sub.html

 

事务

Redis通过MULTI、EXEC、WATCH等命令来实现事务(transaction)功能。事务提供了一种将多个命令请求打包,然后一次性、按顺序地执行多个命令的机制,并且在事务执行期间,服务器不会中断事务而改去执行其他客户端的命令请求,它会将事务中的所有命令都执行完毕,然后才去处理其他客户端的命令请求。‘

·事务提供了一种将多个命令打包,然后一次性、有序地执行的机制。

·多个命令会被入队到事务队列中,然后按先进先出(FIFO)的顺序执行。

·事务在执行过程中不会被中断,当事务队列中的所有命令都被执行完毕之后,事务才会结束。

·带有WATCH命令的事务会将客户端和被监视的键在数据库的watched_keys字典中进行关联,当键被修改时,程序会将所有监视被修改键的客户端的REDIS_DIRTY_CAS标志打开。

·只有在客户端的REDIS_DIRTY_CAS标志未被打开时,服务器才会执行客户端提交的事务,否则的话,服务器将拒绝执行客户端提交的事务。

·Redis的事务总是具有ACID中的原子性、一致性和隔离性,当服务器运行在AOF持久化模式下,并且appendfsync选项的值为always时,事务也具有耐久性。

 

排序

Redis的SORT命令可以对列表键、集合键或者有序集合键的值进行排序。

SORT<key>命令的实现

这个命令可以对一个包含数字值的键key进行排序。

redis> RPUSH numbers 3 1 2
(integer) 3
redis> SORT numbers
1) "1"
2) "2"
3) "3"

 

1)创建一个和numbers列表长度相同的数组,该数组的每个项都是一个redis.h/redisSortObject结构

2)遍历数组,将各个数组项的obj指针分别指向numbers列表的各个项,构成obj指针和列表项之间的一对一关系

 

3)遍历数组,将各个obj指针所指向的列表项转换成一个double类型的浮点数,并将这个浮点数保存在相应数组项的u.score属性里面

 

4)根据数组项u.score属性的值,对数组进行数字值排序,排序后的数组项按u.score属性的值从小到大排列

 

5)遍历数组,将各个数组项的obj指针所指向的列表项作为排序结果返回给客户端,程序首先访问数组的索引0,返回u.score值为1.0的列表项"1";然后访问数组的索引1,返回u.score值为2.0的列表项"2";最后访问数组的索引2,返回u.score值为3.0的列表项"3"

 

BY选项的实现

redis> SADD fruits "apple" "banana" "cherry"
(integer) 3
redis> SORT fruits ALPHA
1) "apple"
2) "banana"
3) "cherry"

redis> MSET apple-price 8 banana-price 5.5 cherry-price 7
OK
redis> SORT fruits BY *-price
1) "banana"
2) "cherry"
3) "apple"

1)创建一个redisSortObject结构数组,数组的长度等于fruits集合的大小。

2)遍历数组,将各个数组项的obj指针分别指向fruits集合的各个元素。

3)遍历数组,根据各个数组项的obj指针所指向的集合元素,以及BY选项所给定的模式*-price,查找相应的权重键:

·对于"apple"元素,查找程序返回权重键"apple-price"。

·对于"banana"元素,查找程序返回权重键"banana-price"。

·对于"cherry"元素,查找程序返回权重键"cherry-price"。

4)将各个权重键的值转换成一个double类型的浮点数,然后保存在相应数组项的u.score属性里面:

·"apple"元素的权重键"apple-price"的值转换之后为8.0。

·"banana"元素的权重键"banana-price"的值转换之后为5.5。

·"cherry"元素的权重键"cherry-price"的值转换之后为7.0。

5)以数组项u.score属性的值为权重,对数组进行排序,得到一个按u.score属性的值从小到大排序的数组:

·权重为5.5的"banana"元素位于数组的索引0位置上。

·权重为7.0的"cherry"元素位于数组的索引1位置上。

·权重为8.0的"apple"元素位于数组的索引2位置上。

6)遍历数组,依次将数组项的obj指针所指向的集合元素返回给客户端。

 

GET选项

通过使用GET选项,我们可以让SORT命令在对键进行排序之后,根据被排序的元素,以及GET选项所指定的模式,查找并返回某些键的值。

STORE选项

通过使用STORE选项,我们可以将排序结果保存在指定的键里面,并在有需要时重用这个排序结果。

多个选项执行顺序

1)排序:在这一步,命令会使用ALPHA、ASC或DESC、BY这几个选项,对输入键进行排序,并得到一个排序结果集。

2)限制排序结果集的长度:在这一步,命令会使用LIMIT选项,对排序结果集的长度进行限制,只有LIMIT选项指定的那部分元素会被保留在排序结果集中。

3)获取外部键:在这一步,命令会使用GET选项,根据排序结果集中的元素,以及GET选项指定的模式,查找并获取指定键的值,并用这些值来作为新的排序结果集。

4)保存排序结果集:在这一步,命令会使用STORE选项,将排序结果集保存到指定的键上面去。

5)向客户端返回排序结果集:在最后这一步,命令遍历排序结果集,并依次向客户端返回排序结果集中的元素。

SORT <key> ALPHA DESC BY <by-pattern> LIMIT <offset> <count> GET <get-pattern> STORE <store_key>

 

如果命令包含了多个GET选项,那么在调整选项的位置时,我们必须保证多个GET选项的摆放顺序不变,这才可以让排序结果集保持不变。

SORT <key> GET <pattern-a> GET <pattern-b> STORE <store_key>

 

重点

·SORT命令通过将被排序键包含的元素载入到数组里面,然后对数组进行排序来完成对键进行排序的工作。

·在默认情况下,SORT命令假设被排序键包含的都是数字值,并且以数字值的方式来进行排序。

·如果SORT命令使用了ALPHA选项,那么SORT命令假设被排序键包含的都是字符串值,并且以字符串的方式来进行排序。

·SORT命令的排序操作由快速排序算法实现。

·SORT命令会根据用户是否使用了DESC选项来决定是使用升序对比还是降序对比来比较被排序的元素,升序对比会产生升序排序结果,被排序的元素按值的大小从小到大排列,降序对比会产生降序排序结果,被排序的元素按值的大小从大到小排列。

·当SORT命令使用了BY选项时,命令使用其他键的值作为权重来进行排序操作。

·当SORT命令使用了LIMIT选项时,命令只保留排序结果集中LIMIT选项指定的元素。

·当SORT命令使用了GET选项时,命令会根据排序结果集中的元素,以及GET选项给定的模式,查找并返回其他键的值,而不是返回被排序的元素。

·当SORT命令使用了STORE选项时,命令会将排序结果集保存在指定的键里面。

·当SORT命令同时使用多个选项时,命令先执行排序操作(可用的选项为ALPHA、ASC或DESC、BY),然后执行LIMIT选项,之后执行GET选项,再之后执行STORE选项,最后才将排序结果集返回给客户端。

·除了GET选项之外,调整选项的摆放位置不会影响SORT命令的排序结果。

 

二进制位数组

Redis提供了SETBIT、GETBIT、BITCOUNT、BITOP四个命令用于处理二进制位数组(bit array,又称“位数组”)。

 

SETBIT命令用于为位数组指定偏移量上的二进制位设置值,位数组的偏移量从0开始计数,而二进制位的值则可以是0或者1。

redis> SETBIT bit 0 1  # 0000 0001 
(integer) 0     
redis> SETBIT bit 3 1        # 0000 1001 
(integer) 0     
redis> SETBIT bit 0 0        # 0000 1000 
(integer) 1 
redis> GETBIT bit 0 # 0000 1000
(integer) 0
redis> GETBIT bit 3 # 0000 1000
(integer) 1

 

BITCOUNT命令用于统计位数组里面,值为1的二进制位的数量。

redis> BITCOUNT bit  # 0000 1000
(integer) 1
redis> SETBIT bit 0 1        # 0000 1001
(integer) 0
redis> BITCOUNT bit
(integer) 2
redis> SETBIT bit 1 1        # 0000 1011
(integer) 0
redis> BITCOUNT bit
(integer) 3

 

BITOP命令既可以对多个位数组进行按位与(and)、按位或(or)、按位异或(xor)运算。

redis> SETBIT x 3 1        # x = 0000 1011
(integer) 0
redis> SETBIT x 1 1
(integer) 0
redis> SETBIT x 0 1
(integer) 0
redis> SETBIT y 2 1  # y = 0000 0110
(integer) 0
redis> SETBIT y 1 1
(integer) 0
redis> SETBIT z 2 1  # z = 0000 0101
(integer) 0
redis> SETBIT z 0 1
(integer) 0
redis> BITOP AND and-result x y z    # 0000 0000
(integer) 1
redis> BITOP OR or-result x y z              # 0000 1111
(integer) 1
redis> BITOP XOR xor-result x y z    # 0000 1000
(integer) 1

 

慢查询日志

·Redis的慢查询日志功能用于记录执行时间超过指定时长的命令。

·Redis服务器将所有的慢查询日志保存在服务器状态的slowlog链表中,每个链表节点都包含一个slowlogEntry结构,每个slowlogEntry结构代表一条慢查询日志。

·打印和删除慢查询日志可以通过遍历slowlog链表来完成。

·slowlog链表的长度就是服务器所保存慢查询日志的数量。

·新的慢查询日志会被添加到slowlog链表的表头,如果日志的数量超过slowlog-max-len选项的值,那么多出来的日志会被删除。

 

引用

《Redis 设计与实现》