doc: 阅读redis list文档

This commit is contained in:
asahi
2025-09-05 17:22:26 +08:00
parent 39f792e911
commit 20578b535e

View File

@@ -40,6 +40,16 @@
- [json object操作](#json-object操作) - [json object操作](#json-object操作)
- [format output](#format-output) - [format output](#format-output)
- [Limitation](#limitation) - [Limitation](#limitation)
- [Redis lists](#redis-lists)
- [Blocking commands](#blocking-commands)
- [Queue(first in, first out)](#queuefirst-in-first-out)
- [Stack(first in, last out)](#stackfirst-in-last-out)
- [check length of list](#check-length-of-list)
- [Atomically pop one element from one list and push to another](#atomically-pop-one-element-from-one-list-and-push-to-another)
- [trim the list](#trim-the-list)
- [Redis List Impl](#redis-list-impl)
- [`LPUSH, RPUSH`](#lpush-rpush)
- [`LRANGE`](#lrange)
# redis # redis
@@ -589,3 +599,104 @@ $ redis-cli --raw
#### Limitation #### Limitation
传递给command的json值最大深度只能为128如果嵌套深度大于128那么command将返回错误。 传递给command的json值最大深度只能为128如果嵌套深度大于128那么command将返回错误。
### Redis lists
Redis lists为string values的链表redis list通常用于如下场景
- 实现stack和queue
- 用于backgroup worker system的队列管理
#### Blocking commands
redis lists中支持阻塞命令
- `BLPOP`: 从`head of a list`移除并且返回一个element如果list为空该command会阻塞直至list被填充元素或发生超时
- `BLMOVE`: 从source list中pop一个element并且将其push到target list中。如果source list为空那么command将会被阻塞直到source list中出现new element
> 在上述文档描述中,`阻塞`实际指的是针对客户端的阻塞。该`Blocking Command`命令的调用会实际的阻塞客户端直到redis server返回结果。
>
> 但是,`server并不会被blocking command所阻塞`。redis server为单线程模型当用户发送blocking command给server并且该command无法立即被执行而导致客户端阻塞时`server会挂起该客户端的连接`,并且转而处理其他请求,直至该客户端的阻塞命令满足执行条件时,才会将挂起的连接唤醒重新执行。
>
> 故而,`Blocking Command`并不会对server造成阻塞而是会阻塞客户端的调用。
#### Queue(first in, first out)
依次调用`LPUSH`后再依次调用`RPOP`,可模拟队列行为,元素的弹出顺序和元素的添加顺序相同:
```redis-cli
> LPUSH bikes:repairs bike:1
(integer) 1
> LPUSH bikes:repairs bike:2
(integer) 2
> RPOP bikes:repairs
"bike:1"
> RPOP bikes:repairs
"bike:2"
```
#### Stack(first in, last out)
依次调用`LPUSH`后再依次调用`LPOP`,可模拟栈的行为,元素的移除顺序和添加顺序相反:
```redis-cli
> LPUSH bikes:repairs bike:1
(integer) 1
> LPUSH bikes:repairs bike:2
(integer) 2
> LPOP bikes:repairs
"bike:2"
> LPOP bikes:repairs
"bike:1"
```
#### check length of list
可通过`LLEN`命令来检查list的长度
```redis-cli
> LLEN bikes:repairs
(integer) 0
```
#### Atomically pop one element from one list and push to another
通过`lmove`命令能够实现原子的`从srclist移除并添加到dstlist`的操作
```redis-cli
> LPUSH bikes:repairs bike:1
(integer) 1
> LPUSH bikes:repairs bike:2
(integer) 2
> LMOVE bikes:repairs bikes:finished LEFT LEFT
"bike:2"
> LRANGE bikes:repairs 0 -1
1) "bike:1"
> LRANGE bikes:finished 0 -1
1) "bike:2"
```
#### trim the list
可以通过`LTRIM`命令来完成对list的裁剪操作
```redis-cli
> LPUSH bikes:repairs bike:1
(integer) 1
> LPUSH bikes:repairs bike:2
(integer) 2
> LMOVE bikes:repairs bikes:finished LEFT LEFT
"bike:2"
> LRANGE bikes:repairs 0 -1
1) "bike:1"
> LRANGE bikes:finished 0 -1
1) "bike:2"
```
#### Redis List Impl
redis lists是通过Linked List来实现的其元素的添加操作并开销永远是常量的并不会和Array一样因扩容而可能导致内存的复制。
#### `LPUSH, RPUSH`
`LPUSH`会将元素添加到list的最左端头部而`RPUSH`则会将新元素添加奥list的最右端尾部
LPUSH和RPUSH接收的参数都是可变的在单次调用中可以向list中添加多个元素。
例如向空list中调用`lpush 1 2 3`时,其等价于`lpush 1; lpush 2; lpush3`即调用后list中元素为`3,2,1`
#### `LRANGE`
`LRANGE`命令能够从list中解析范围内的数据其接收两个indexes为range中开始和结束元素的位置。index可以是负的负数代表从尾端开始计数
- `-1`代表最后的元素
- `-2`代表倒数第二个元素
```redis-cli
> RPUSH bikes:repairs bike:1
(integer) 1
> RPUSH bikes:repairs bike:2
(integer) 2
> LPUSH bikes:repairs bike:important_bike
(integer) 3
> LRANGE bikes:repairs 0 -1
1) "bike:important_bike"
2) "bike:1"
3) "bike:2"
```