目录
List
用法
1. 增
2. 删
3. 查
内部编码
应用场景
前言
Redis 中的 List 和 Set 数据结构各有特点,适用于不同的应用场景。List 提供了有序的列表结构,适合用于消息队列和任务列表等场景;Set 提供了无序且不重复的集合结构,适合用于标签系统和唯一性检测等场景。通过合理选择和使用 Redis 的数据结构,可以有效提升系统的性能和扩展能力。
List
用法
List 是一个简单的链表,支持从两端进行插入和删除操作。
常见命令:
1. 增
插入一个或多个元素到列表的左端。
lpush key value [value ...]
lpushx key value [value ...]( key存在时插入 )
返回值 :list 的长度
插入一个或多个元素到列表的右端。
rpush key value [value ...]
rpushx key value [value ...]( key存在时插入 )
返回值: list的长度
在指定位置插入元素
linsert key <before | after> pivot element
进行插入的时候,从左往右找到第一个基准值进行插入
返回值:新的 list 的长度
2. 删
删除并返回列表的左端元素。
lpop key
lpop key [count]( 6.2版本在后面可以设置删除的个数)
返回值: 被删除的元素/nil(空)
删除并返回列表的右端元素。
rpop key
返回值: 被删除的元素/nil(空)
删除指定的元素
lrem key count(要删除的数量) element(要删除的值)
count > 0 : 从左往右找,删除
count < 0 : 从右往左找,删除
count = 0 : 删除所有的
删除范围外的元素
ltrim key start stop(前闭后闭)
阻塞删除
brpop / blpop key [key ...] timeout(秒)
当 list 为空的时候,会进行阻塞(等待),但是这个期间 Redis 可以执行其他命令!!!返回值:
1. 非空时,会返回删除的是哪个key的哪个值
eg:blpop key 0
(1)"key"
(2)"1"
2. 为空时,会进行阻塞,当有数据的时候,进行 pop
3. 查
返回列表中指定范围内的元素。
lrange key start stop(前闭后闭)
超过范围的话,只会返回范围内的元素,不会报错。
返回列表的长度。
llen key
根据下标获取元素
lindex key index
内部编码
以前的Redis编码
ziplist:当列表中的元素数量较少且每个元素都比较小时,Redis 使用紧凑的 ziplist 结构。ziplist 是一种连续内存块,存储在一个数组中,可以有效减少内存占用。
linkedlist:当列表变大或元素变复杂时,Redis 会自动切换到 linkedlist 编码。这是一种双向链表,适合频繁的插入和删除操作。
如今的Redis编码
quicklist:取其精华,去其糟粕!!!整体是一个链表,但是每个节点是一个不是很大的压缩列表(ziplist)。
应用场景
消息队列:可以利用 LPUSH
和 BRPOP
命令实现一个简单的消息队列,生产者通过 LPUSH
插入消息,消费者通过 BRPOP
获取消息。
微博Timeline:每个用户都有属于⾃⼰的 Timeline(微博列表),现需要分页展示文章列表。此时可以考虑使⽤列表,因为列表不但是有序的,同时⽀持按照索引范围获取元素。
1. 每篇微博使⽤哈希结构存储,例如微博中 3 个属性:title、timestamp、content:
hmset mblog:1 title xx timestamp 1476536196 content xxxxx
2. 向用户 Timeline 添加微博,user:<uid>:mblogs 作为微博的键:
lpush user:1:mblogs mblog:1 mblog:3
3. 分页获取用户的 Timeline,例如获取用户 1 的前 10 篇微博:
keylist = lrange user:1:mblogs 0 9
for key in keylist {hgetall key
}
问题:
1. 当每次分页过多的时候,需要进行多次 hgetall 操作,这是可以考虑进行 pipeline (流水线)进行批量进行提交命令。
2. 分裂获取文章时,lrange 在列表两端表现比较好,但是中间比较差,此时可以考虑进行拆分。
同侧存取(lpush + lpop 或者 rpush + rpop)为栈异侧存取(lpush + rpop 或者 rpush + lpop)为队列
任务列表:在任务处理系统中,可以使用 List 存储待处理的任务,工作线程从列表中获取任务进行处理。
最新消息:将最新消息存储在 List 中,通过 LRANGE
命令获取最新的 N 条消息。