link(链表):
Redis 的列表相当于 Java 语言里面的 LinkedList,注意它是链表而不是数组。这意味着 list 的插入和删除操作非常快,时间复杂度为 O(1),但是索引定位很慢,时间复杂度为 O(n),这点让人非常意外。
当列表弹出了最后一个元素之后,该数据结构自动被删除,内存被回收。
Redis 的列表结构常用来做异步队列使用。将需要延后处理的任务结构体序列化成字符串塞进 Redis 的列表,另一个线程从这个列表中轮询数据进行处理。
右边进左边出:队列
右边进右边出:栈(后进先出)
快速列表:
如果再深入一点,你会发现 Redis 底层存储的还不是一个简单的 linkedlist,而是称之为快速链表 quicklist 的一个结构。
首先在列表元素较少的情况下会使用一块连续的内存存储,这个结构是 ziplist,也即是压缩列表。它将所有的元素紧挨着一起存储,分配的是一块连续的内存。当数据量比较多的时候才会改成 quicklist。因为普通的链表需要的附加指针空间太大,会比较浪费空间,而且会加重内存的碎片化。比如这个列表里存的只是 int 类型的数据,结构上还需要两个额外的指针 prev 和 next 。所以 Redis 将链表和 ziplist 结合起来组成了 quicklist。也就是将多个 ziplist 使用双向指针串起来使用。这样既满足了快速的插入删除性能,又不会出现太大的空间冗余。
lpush key value1 value2 value3
左侧插入
rpush key value1 value2 value3
右侧插入
lrange list 0 -1
查看链表 左侧 0 , 右侧-1
rpop value
删除最右边的元素,并弹出
lrem count value
链表删除,删除count个value
count > 0 从表头删除,count < 0 从表尾删除
ltrim key start stop
截取一段链表
lindex key index
返回下标index上的值。index=-1表示倒数第一个元素,同样index=-2表示倒数第二个元素。
llist key
返回链表的长度
linsert key after | before serach value
开始搜索serach值,找到第一个serach值后,在第一个search值前|后插入value
rpoplpush source destination(双向链表)
把source的尾部拿出放在destination的头部,形成一个安全的双向链表
假设一个应用程序正在执行lpush操作向链表中添加新的元素,我们通常将这样的程序称之为”生产者,而另外一个应用程序正在执行rpop操作从链表中取出元素,我们称这样的程序为”消费者”。如果消费者程序在取出消息元素后崩溃了,由于该消息已经被取出且没有被正常处理,那么我们就可以认为该消息已经丢失,由此可能会导致业务数据丢失,或业务状态的不一致等现象的发生。
然而通过使用rpoplpush 命令,消费者程序在从主消息队列中取出消息之后再将其插入到备份队列中,直到消费者程序完成正常的处理逻辑后再将该消息从备份队列中删除。同时我们还可以提供一个守护进程,当发现备份队列中的消息过期时,可以重新将其再放回到主消息队列中,以便其它的消费者程序继续处理。
bitop and res key [key ...]
对一个或多个 key 求逻辑并,并将结果保存到res
bitop or destkey key [key ...]
对一个或多个 key 求逻辑或,并将结果保存到res
bitop xor destkey key [key ...]
对一个或多个 key 求逻辑异或,并将结果保存到res
bitop not destkey key
对给定 key 求逻辑非,并将结果保存到res
setbit key offset value(位图法统计活跃用户)
定义一个字符串 setbit monday 10000000000000 0
如下图所示,第1位表示uid为0的用户,其中第15位表示uid为15的用户
我们可以如下图所示,周一,uid为2的用户,1表示登录0表示未登录
最终我们可以通过逻辑并来统计有哪些用户周一周三周四都登录了
bitop and time monday wednesday thurday
优点:①节约空间,统计一亿人每天的登录情况,用一亿bit,约1200WByte,约10M的字符就能表示(因为bitop命令的返回值是保存到 time中的字符串的长度(以字节byte为单位),和输入 key 中最长的字符串长度相等。即1亿除以8bit=1250万Byte)②计算方便
bitcount key
当然也可以统计当天有多少用户登录
bitcount monday
getbit key offset
也可以看某用户当天有没有登录
getbit monday 8