Redis学习之旅 List篇
Redis学习之旅 List篇
List可以组装成队列、栈等容器,还可以拿来实现消息队列
有几个前提要知道,list内的元素是可重复的,每一个元素其实还是一个String类型的对象
命令学习
redis-cli模式下键入 help @list 就可以快速相关的命令集合
在学习Redis命令时,有些东西需要知道,L开头的命令,有些是指的Left ,有些指的是List
1.0时代
命令 | 起始版本 | 作用 | 示例 |
---|---|---|---|
LINDEX | 1.0.0 | list index 从左侧0起,按索引查找对应位置的元素 | LINDEX key index |
LLEN | 1.0.0 | list length获取列表长度 | LLEN key |
LPOP | 1.0.0 | left pop左侧弹出 | LPOP key |
LPUSH | 1.0.0 | left push左侧压入 | LPUSH key element [element …] |
LRANGE | 1.0.0 | list range从对应的索引获得元素 | LRANGE key start stop |
LREM | 1.0.0 | list remove删除 | LREM key count element |
LSET | 1.0.0 | list set 向指定索引赋值 | LSET key index element |
LTRIM | 1.0.0 | list trim 指定位置清掉范围外的内容 | LTRIM key start stop |
RPOP | 1.0.0 | right pop右侧弹出 | RPOP key |
RPUSH | 1.0.0 | right push右侧压入 | RPUSH key element [element …] |
RPOPLPUSH | 1.0.0 | right pop left push 左入右出队列 | RPOPLPUSH source destination |
关注点
一、左右怎么区分?
从测试结果来看,
- 同向pop和push命令结合,可以达到栈结构
- 反向pop和push命令结合,可以达到队列结构
- index的索引计算与string中计算字符是一致的,存在正向与反向索引
二、LREM
字面意思 list remove,删除元素,但是它的里面很神奇的有一个count,这个count是干啥的呢?
实测结果来看,因为list可以存放重复数据,因此redis提供的命令可以删除相同个数的元素,计算规则是从正向索引0开始,找到一个删一个
三、LSET
将指定index位置上的元素向右侧压
四、LTRIM
看到trim就想到Java 里的String.trim(),和这个方法类似 ,List trim也是做了一样的事,将指定范围外的内容删除
五、RPOPLPUSH
right pop left push ,左进入出,啥意思呢?看下它的参数 RPOPLPUSH source destination,一个源头,一个目标。
就是说,它将你给定的队列,右侧弹出一个元素,并使用LPUSH把这个元素扔到另一个队列里
2.0时代
命令 | 起始版本 | 作用 | 示例 |
---|---|---|---|
BLPOP | 2.0.0 | blocking left pop,阻塞式左侧弹出 | BLPOP key [key …] timeout |
BRPOP | 2.0.0 | blocking right pop,阻塞式右侧弹出 | BRPOP key [key …] timeout |
BRPOPLPUSH | 2.2.0 | blocking right pop left push ,阻塞式的RPOPLPUSH命令 | BRPOPLPUSH source destination timeout |
LINSERT | 2.2.0 | list insert 列表的插入 | LINSERT key BEFORE |
LPUSHX | 2.2.0 | 向左侧头添加元素 | LPUSHX key element [element …] |
RPUSHX | 2.2.0 | 向右侧头添加元素 | RPUSHX key element [element …] |
关注点
BLPOP/BRPOP
前面的B就是Blocking的意思,阻塞式的弹出压入
如果队列中有元素,那么就立即弹出此元素,否则在那里等待
看起来就是一个活生生的生产/消费者的模型呐
BRPOPLPUSH
同普通的RPOPLPUSH逻辑是一样的,只是在弹出时,如果原始队列为空,会阻塞在那里等待
LINSERT
向指定的元素 前/后插入,如果有重复元素,只能插入到左数起第一个匹配元素上
LPUSHX/RPUSHX
LPUSHX 向列表左侧头添加某个元素
RPUSHX 向列表右侧头添加某个元素
向空队列操作无效
消息队列运用
- 可以使用以下两种方式实现
- LPUSH + BRPOP
- RPUSH + BLPOP
因为list是有序的,且Redis请求是单线程处理的,因此可以保证消息处理的有序性。
消费者线程过来后,去列表里获取任务,发现有任务,就会立即触发pop操作,删除排在队列头部的任务并将数据返回给消费者线程。
如果消费者线程发现任务队列已经空了,那么就会阻塞在那里,等候有新任务进入队列,有新任务进入队列后,等待线程就被唤醒
- 优点:
- 响应快,实现简单,延迟很低
- 缺点:
- 如果线程阻塞过久,可能会被Redis释放掉连接,导致消费报错,需要自己实现重试策略
- 需要处理消息处理异常,不好实现ack模式
- 不好实现广播模式
- 任务被弹出后,可能因网络抖动导致消费者业务没有收到数据,此时Redis上数据已经删除,导致数据丢失