Redis 中 List 数据结构详解

目录

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)。


应用场景

消息队列:可以利用 LPUSHBRPOP 命令实现一个简单的消息队列,生产者通过 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 条消息。

  • 17
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lpy2569

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值