学习《Redis使用手册》(上)

假期看完了《Redis学习手册》,这本书没有太多的大道理,从应用的角度讲解了Redis方方面面,推荐一读,简单做个笔记。

字符串

字符串应该是Redis数据结构中最简单的一种,基本上也掌握了,SETNX 命令可以实现一个简单的锁;而APPEND、SETRANGE等命令和编程语言中的字符串操作非常类似,所以学习起来很轻松;INCRBY、DECRBY命令实现计数器非常方便,它们还可用作ID生成器。

散列

散列数据结构我用的比较多,很方便。和STRING类型一样,它也有锁机制,也能进行数字和浮点数的递增递减;HKEYS、HVALS、HGETALL、HMAGET基本上能够遍历一个键值;

从应用上看,通过HASH能实现短网址生成器(将整型转换为36进制),而存储图数据(边与边)非常有创意。

相比字符串,散列比较节省内存,这个是比较大的优点。

列表

喜欢使用列表做消息队列,或者在秒杀的时候对秒杀用户进行排列(如果要求及时的响应,这种方式不适合);LRANGE对于实现分页比较有用;LTRIM用于排行榜比较有用(保持一定长度)。

BLPOP我以前没有用过,平时在使用LIST作为队列的时候,如果队列数据为空,如果不断循环LPOP会比较消耗性能(也可以使用sleep选择休眠),而通过BLPOP可以在客户端阻塞读操作,直到队列中有数据才进入非阻塞,比较有用,而阻塞超时时间可以实现一定程度的异步操作。

集合

集合和列表有两个显著的区别:

  • 列表可以存储重复元素,而集合不行。

  • 列表可以以有序的方式存储数据,而集合存储的数据是无须的。

从应用上看,唯一计数器(比如每天访问的UA)、打标签、点赞列表、投票、访客、抽奖(随机取出元素),感觉发挥的空间非常大,原因在于其内部能够保证元素是唯一的。

原生支持元素的交集、并集、差集运算,可以实现共同关注,推荐关注。

有序集合

它是集合的一种,但每个元素会有分值。

在实现排行榜非常方便,获取特点区间(分值、时间线)元素也很方便。

整体上看,有序集合的命令非常多,多使用才会有更多的体会。

书中列出一个自动补全的例子,觉得很有创意,在P187页,可以仔细体会,充分利用权重、权重排序的特定。

HyperLogLog

这个数据结构是第一次使用,使用集合计算每天访问的IP,但如果访问者特别多,则集合占用的内存非常大。

而HyperLogLog是一个专门为了计算集合的基数而创建的概率算法,注意是概率算法,不是特别精准,但也有一定的使用场景。

比如可以统计每天IP访问数量,重要的是节省内存,而且可以对多个HyperLogLog进行并集计算,比如计算出一周、一月的IP访问数量。

理解他需要记住HyperLogLog只能计数,不能知晓元素的值。

位图

位移操作非常方便,所以Redis也支持了,比如将来我们可以用一个key(文章+用户)存储某个用户是否赞、收藏、评论过一篇文章。

需要注意的是位图以字节作为偏移量,而非Bit。

使用位图,也可以存储用户每天的行为,比如某一天是否登陆、发文、发评论等各种行为,而且通过BITCOUNT可以知道用户执行了那些行为。

而BITFIELD命令很有意思,可以对指定的偏移量存储整数值:

#占一个字节
bitfield bitmap set u8 0 128
#第二个字节偏移量
bitfield bitmap set u8 8 256
bitfield bitmap get u8 0
bitfield bitmap get u8 8

从节省内存的角度看,以对齐的方式使用位图(只存储同一种类型的整数)。

如果是指定类型的位长度,可以使用索引对field进行设置:

bitfield bitmap2 set u8 #10 100
bitfield bitmap2 get u8 #10

地理位置

将来如果要实现简单的地理位置应用,使用Geo结构即可。

使用GETADD存储坐标,使用GETPOS获取指定位置的坐标,使用GEODIST计算两个位置之间的直线距离,使用GETRADIUS查找指定坐标半径范围内的其他位置(还可以排序和限制返回的数量)。

实际上GEO结构是使用有序集合存储数据的。

通过流可以实现可靠的消息队列,LIST弹出元素后就消失(处理程序突然中断怎么办?),有序集合没有阻塞操作源语,发布与订阅“发送即忘”。

流元素的ID由毫秒和顺序标号组成,流是一种真正意义上的追加写操作(有顺序要求),不能在中间插入元素。

使用XRANGE能够对流进行迭代操作,所谓迭代就是本次迭代的开始值=上个迭代返回值+1,比如:

XADD s1 * k1 v1
XADD s1 * k2 v2
XADD s1 * k3 v3

XRANGE s1 - + COUNT 1
1580385091842-0

XRANGE s1 1580385091842-1 + COUNT 1
1580385097906-0

XRANGE s1 1580385097906-1 + COUNT 1

另外一个很重要的命令就是XREAD操作,可以以阻塞或非阻塞的方式获取流元素,而且在迭代的方式更简单,它只能从一个方向对流进行迭代。

在迭代的时候,和XRANGE不同之处在于:

  • XRANGE接收ID区间作为输入,而XREAD只接收一个ID作为输入,而且XRANGE需要手动计算下一次迭代的其实ID,而XREAD使用上次返回的ID作为输入即可。

  • XREAD可以一次迭代多个流,而XRANGE每次只能迭代一个流。

  • XREAD具有阻塞和非阻塞特点,而XRANGE只能以同步的方式进行。

XREAD阻塞功能:如果给定的流不存在可读取的元素,命令就会进入阻塞状态,如果在给定的阻塞时长内有一个可读取的元素,Redis将把这个元素分发给所有被阻塞的客户端。

XREAD BLOCK  1000000 COUNT 2 STREAMS sx 0

XADD sx * msg "hello"

通过XREAD的阻塞功能,可以只获取新出现的元素:

XREAD BLOCK  1000000 COUNT 2 STREAMS sx1 sx2 $ $

XADD sx1 * k "v"

另外流结构还有消费组概念, 可还没看明白 ,以后再说。

我来评几句
登录后评论

已发表评论数()

相关站点

热门文章