Redis开发与运维读书笔记之五——列表

列表List

 

List类型用来存储多个有序的字符串,列表中每个字符串成为元素(element);

一个List最多可以存储2^32-1个元素;

可以对List两端插入(push)或弹出(pop);

List可以充当栈和队列的角色

List的特点:

  • List中的Element是有序的,可以通过索引下标获取某个Element或某个范围内的Element List
  • List中的Element是可以重复的

 

 

常用命令

添加

从右边插入元素:rpush key value [value …]

从左边插入元素:lpush key value [value …]

向某个元素前或后插入元素:linsert key before|after pivot value (pivot为指定的某个元素 )

从左到右列出列表的所有元素:lrange listkey 0 -l

 

查找

获取指定范围的元素列表:lrange key start end,索引下标从左到右为从0到N-1,从右到左是-1到-N,end包含了自身

获取列表指定索引下标的元素: lindex key index

获取列表长度:llen key

 

删除

从列表左侧弹出元素:lpop key

从列表右侧弹出元素:rpop key

删除指定元素:lrem key count value,从列表中找到值为value的元素删除,根据count不同分为三种情况:

count>0:从左到右,删除最多count个元素

count<0:从右到左,删除最多count绝对值个元素

count=0:删除所有

 

修改

修改指定索引下标的元素:lset key index newValue

 

阻塞

blpop key [key …] timeout

brpop key [key …] timeout

blpop和brpop是lpop和rpop的阻塞版本,除了弹出方向不同,使用方法基本相同。

timeout的单位是秒

  • 列表为空:timeout=0,客户端会一直阻塞;timeout=3,会等待3秒返回
  • 列表不为空,timeout=0,客户端立即返回

 

使用brpop时需要注意两点:

  • 如果是多个键,brpop会从左到右遍历所有键,一旦有一个键能弹出元素,客户端立即返回
  • 如果多个客户端对同一个键执行brpop,最先执行brpop命令的客户端可以获取到弹出的值

 

 

列表类型的命令及对应的时间复杂度

 

命令

  时间复杂度

rpush key value [value …]

O(k) k 是元素个数

lpush key value [value….]

O(k) k 是元素个数

linsert ket before|after pivot value

O(n) n pivot 距离列表头或尾的距离

lrange key start end

O(s+n),s start 偏移量, n start end 的范围

lindex key index

O(n) n 是索引的偏移量

llen key

O(1)

lpop key

O(1)

rpop key

O(1)

lrem key count value

O(n) n 是列表长度

ltrim key start end

O(n) n 是要裁剪的元素总数

lset key index newvalue

O(n) n 是索引的偏移量

blpop key [key …] timeout

O(1)

brpop key [key…] timeout

O(1)

 

内部编码

  • ziplist:压缩列表,当列表的元素个数小于list-max-ziplist-entries配置(默认512个),同时列表中每个元素的值都小于list-max-ziplist-value配置(默认64个字节),Redis会选用ziplist作为列表的内部实现来减少内存的使用
  • linkedlist:链表,当列表类型无法满足ziplist的条件,Redis会选用linkedlist作为List的内部实现
  • quicklist:Redis3.2提供,是一个以ziplist为节点的linkedlist,结合了两者的优势

 

使用场景:

  • 消息队列:lpush+brpop组合可以实现阻塞队列,生产者客户端使用lrpush从列表左侧插入元素,多个消费者客户端使用brpop命令阻塞式“抢”列表右侧的元素,多个客户端保证了消费的负载均衡和高可用
  • 文章列表:每个用户都有属于自己的文章列表,需要分页展示文章列表,可以使用List,因为List不但是有序的,还支持按照索引范围获取元素。

(1)、 每篇文章使用Hash结果存储

(2)、向用户文章列表添加文章使用lpush

(3)、分页获取用户文章列表使用lrange

 

注意:如果每次分页获取文章个数较多,使用hgetall效率较低,可以考虑使用pipeline批量获取,或者将文章数据序列化成字符串,使用mget批量获取。

lrange在列表两端性能较好,中间性能较差,可以将列表做二级拆分,或者使用Redis3.2的quicklist内部编码实现,效率较高。

 

场景选择时可以参考一下口诀

lpush + lpop = Stack(栈)

lpush + rpop = Queue(队列)

lpush + ltrim = Capped Collection(有限集合)

lpush + brpop = Message Queue(消息队列)

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇