Redis命令參考手冊——List(列表)

Redis命令參考手冊——List(列表)

1、LPUSH

格式:lpush key value [value …]
將一個或多個值 value 插入到列表 key 的表頭
如果有多個 value 值,那麼各個 value 值按從左到右的順序依次插入到表頭:比如說,對空列表 mylist 執行命令 LPUSH mylist a b c ,列表的值將是 c b a ,這等同於原子性地執行 LPUSH mylist a 、 LPUSH mylist b 和 LPUSH mylist c 三個命令。
如果 key 不存在,一個空列表會被創建並執行 LPUSH 操作。
當 key 存在但不是列表類型時,返回一個錯誤。
注: 在 Redis 2.4 版本以前的 LPUSH 命令,都只接受單個 value 值。
可用版本:

>=1.0.0

時間複雜度:
O(1)
返回值:
執行 LPUSH 命令後,列表的長度。
示例代碼:

# 加入單個元素
redis> LPUSH languages python
(integer) 1
# 加入重複元素
redis> LPUSH languages python
(integer) 2
redis> LRANGE languages 0 -1 # 列表允許重複元素
1) "python"
2) "python"
# 加入多個元素
redis> LPUSH mylist a b c
(integer) 3
redis> LRANGE mylist 0 -1
1) "c"
2) "b"
3) "a"

2、LPUSHX

格式:lpushx key value
將值 value 插入到列表 key 的表頭,當且僅當 key 存在並且是一個列表。
和 LPUSH 命令相反,當 key 不存在時, LPUSHX 命令什麼也不做。
可用版本:

>=2.2.0

時間複雜度:
O(1)
返回值:
LPUSHX 命令執行之後,表的長度。
示例代碼:

# 對空列表執行 LPUSHX
redis> LLEN greet # greet 是一個空列表
(integer) 0
redis> LPUSHX greet "hello" # 嘗試 LPUSHX,失敗,因爲列表爲空
(integer) 0
# 對非空列表執行 LPUSHX
redis> LPUSH greet "hello" # 先用 LPUSH 創建一個有一個元素的列表
(integer) 1
redis> LPUSHX greet "good morning" # 這次 LPUSHX 執行成功
(integer) 2
redis> LRANGE greet 0 -1
1) "good morning"
2) "hello"

3、RPUSH

格式:rpush key value [value …]
將一個或多個值 value 插入到列表 key 的表尾(最右邊)。
如果有多個 value 值,那麼各個 value 值按從左到右的順序依次插入到表尾:比如對一個空列表 mylist 執行 RPUSH mylist a b c ,得出的結果列表爲 a b c ,等同於執行命令 RPUSH mylist a 、 RPUSH mylist b 、 RPUSH mylist c 。
如果 key 不存在,一個空列表會被創建並執行 RPUSH 操作。
當 key 存在但不是列表類型時,返回一個錯誤。
注:在 Redis 2.4 版本以前的 RPUSH 命令,都只接受單個 value 值。
可用版本:

>=1.0.0

時間複雜度:
O(1)
返回值:
執行 RPUSH 操作後,表的長度。
示例代碼:

# 添加單個元素
redis> RPUSH languages c
(integer) 1
# 添加重複元素
redis> RPUSH languages c
(integer) 2
redis> LRANGE languages 0 -1 # 列表允許重複元素
1) "c"
2) "c"
# 添加多個元素
redis> RPUSH mylist a b c
(integer) 3
redis> LRANGE mylist 0 -1
1) "a"
2) "b"
3) "c"

4、RPUSHX

格式:rpushx key value
將值 value 插入到列表 key 的表尾,當且僅當 key 存在並且是一個列表。
和 RPUSH 命令相反,當 key 不存在時, RPUSHX 命令什麼也不做。
可用版本:

>=2.2.0

時間複雜度:
O(1)
返回值:
RPUSHX 命令執行之後,表的長度。
示例代碼:

# key 不存在
redis> LLEN greet
(integer) 0
redis> RPUSHX greet "hello" # 對不存在的 key 進行 RPUSHX,PUSH 失敗。
(integer) 0
# key 存在且是一個非空列表
redis> RPUSH greet "hi" # 先用 RPUSH 插入一個元素
(integer) 1
redis> RPUSHX greet "hello" # greet 現在是一個列表類型,RPUSHX 操作
成功。
(integer) 2
redis> LRANGE greet 0 -1
1) "hi"
2) "hello"

5、LPOP

格式:lpop key
移除並返回列表 key 的頭元素。
可用版本:

>=1.0.0

時間複雜度:
O(1)
返回值:
列表的頭元素。 當 key 不存在時,返回 nil 。
示例代碼:

redis> LLEN course
(integer) 0
redis> RPUSH course algorithm001
(integer) 1
redis> RPUSH course c++101
(integer) 2
redis> LPOP course # 移除頭元素
"algorithm001"

6、RPOP

格式:rpop key
移除並返回列表 key 的尾元素。
可用版本:

>=1.0.0

時間複雜度:
O(1)
返回值:
列表的尾元素。 當 key 不存在時,返回 nil 。
示例代碼:

redis> RPUSH mylist "one"
(integer) 1
redis> RPUSH mylist "two"
(integer) 2
redis> RPUSH mylist "three"
(integer) 3
redis> RPOP mylist # 返回被彈出的元素
"three"
redis> LRANGE mylist 0 -1 # 列表剩下的元素
1) "one"
2) "two"

7、BLPOP

格式:blpop key [key …] timeout
BLPOP 是列表的阻塞式(blocking)彈出原語。
它是 LPOP 命令的阻塞版本,當給定列表內沒有任何元素可供彈出的時候,連接將被BLPOP 命令阻塞,直到等待超時或發現可彈出元素爲止。
當給定多個 key 參數時,按參數 key 的先後順序依次檢查各個列表,彈出第一個非空列表的頭元素。
非阻塞行爲
當 BLPOP 被調用時,如果給定 key 內至少有一個非空列表,那麼彈出遇到的第一個非空列表的頭元素,並和被彈出元素所屬的列表的名字一起,組成結果返回給調用者。
當存在多個給定 key 時, BLPOP 按給定 key 參數排列的先後順序,依次檢查各個列表。
假設現在有 job 、 command 和 request 三個列表,其中 job 不存在, command 和request 都持有非空列表。考慮以下命令: BLPOP job command request 0
BLPOP 保證返回的元素來自 command ,因爲它是按”查找 job -> 查找 command -> 查找 request “這樣的順序,第一個找到的非空列表。

redis> DEL job command request # 確保 key 都被刪除
(integer) 0
redis> LPUSH command "update system..." # 爲 command 列表增加一個值
(integer) 1
redis> LPUSH request "visit page" # 爲 request 列表增加一個值
(integer) 1
redis> BLPOP job command request 0 # job 列表爲空,被跳過,緊接着
command 列表的第一個元素被彈出。
1) "command" # 彈出元素所屬的列表
2) "update system..." # 彈出元素所屬的值

阻塞行爲
如果所有給定 key 都不存在或包含空列表,那麼 BLPOP 命令將阻塞連接,直到等待超時,或有另一個客戶端對給定 key 的任意一個執行 LPUSH 或 RPUSH 命令爲止。
超時參數 timeout 接受一個以秒爲單位的數字作爲值。超時參數設爲 0 表示阻塞時間可以無限期延長(block indefinitely) 。

redis> EXISTS job # 確保兩個 key 都不存在
(integer) 0
redis> EXISTS command
(integer) 0
redis> BLPOP job command 300 # 因爲 key 一開始不存在,所以操作會被阻塞,
直到另一客戶端對 job 或者 command 列表進行 PUSH 操作。
1) "job" # 這裏被 push 的是 job
2) "do my home work" # 被彈出的值
(26.26s) # 等待的秒數
redis> BLPOP job command 5 # 等待超時的情況
(nil)
(5.66s) # 等待的秒數

相同的可用被多個客戶端同時阻塞
相同的 key 可以被多個客戶端同時阻塞。
不同的客戶端被放進一個隊列中,按『先阻塞先服務』(first-BLPOP,first-served)的順序爲 key 執行 BLPOP 命令。
在MULTI/EXEC事務中的BLPOP
BLPOP 可以用於流水線(pipline,批量地發送多個命令並讀入多個回覆),但把它用在MULTI / EXEC 塊當中沒有意義。因爲這要求整個服務器被阻塞以保證塊執行時的原子性,該行爲阻止了其他客戶端執行 LPUSH 或 RPUSH 命令。
因此,一個被包裹在 MULTI / EXEC 塊內的 BLPOP 命令,行爲表現得就像 LPOP 一樣,對空列表返回 nil ,對非空列表彈出列表元素,不進行任何阻塞操作。

# 對非空列表進行操作
redis> RPUSH job programming
(integer) 1
redis> MULTI
OK
redis> BLPOP job 30
QUEUED
redis> EXEC # 不阻塞,立即返回
1) 1) "job"
2) "programming"
# 對空列表進行操作
redis> LLEN job # 空列表
(integer) 0
redis> MULTI
OK
redis> BLPOP job 30
QUEUED
redis> EXEC # 不阻塞,立即返回
1) (nil)

可用版本:

>=2.0.0

時間複雜度:
O(1)
返回值:
如果列表爲空,返回一個 nil 。 否則,返回一個含有兩個元素的列表,第一個元素是被彈出元素所屬的 key ,第二個元素是被彈出元素的值。
模式:事件提醒
有時候,爲了等待一個新元素到達數據中,需要使用輪詢的方式對數據進行探查。
另一種更好的方式是,使用系統提供的阻塞原語,在新元素到達時立即進行處理,而新元素還沒到達時,就一直阻塞住,避免輪詢佔用資源。
對於 Redis ,我們似乎需要一個阻塞版的 SPOP 命令,但實際上,使用 BLPOP 或者BRPOP 就能很好地解決這個問題。
使用元素的客戶端(消費者)可以執行類似以下的代碼:

LOOP forever
WHILE SPOP(key) returns elements
... process elements ...
END
BRPOP helper_key
END

添加元素的客戶端(消費者)則執行以下代碼:

MULTI
SADD key element
LPUSH helper_key x
EXEC

8、BRPOP

格式:brpop key [key …] timeout
BRPOP 是列表的阻塞式(blocking)彈出原語。
它是 RPOP 命令的阻塞版本,當給定列表內沒有任何元素可供彈出的時候,連接將被BRPOP 命令阻塞,直到等待超時或發現可彈出元素爲止。
當給定多個 key 參數時,按參數 key 的先後順序依次檢查各個列表,彈出第一個非空列表的尾部元素。
關於阻塞操作的更多信息,請查看 BLPOP 命令, BRPOP 除了彈出元素的位置和 BLPOP不同之外,其他表現一致。
可用版本:

>=2.0.0

時間複雜度:
O(1)
返回值:
假如在指定時間內沒有任何元素被彈出,則返回一個 nil 和等待時長。
反之,返回一個含有兩個元素的列表,第一個元素是被彈出元素所屬的 key ,第二個元素是被彈出元素的值。
示例代碼

redis> LLEN course
(integer) 0
redis> RPUSH course algorithm001
(integer) 1
redis> RPUSH course c++101
(integer) 2
redis> BRPOP course 30
1) "course" # 彈出元素的 key
2) "c++101" # 彈出元素的值

9、LLEN

格式:llen key
返回列表 key 的長度。 如果 key 不存在,則 key 被解釋爲一個空列表,返回 0 . 如果 key 不是列表類型,返回一個錯誤。
可用版本:

>=1.0.0

時間複雜度:
O(1)
返回值:
列表 key 的長度。
示例代碼

# 空列表
redis> LLEN job
(integer) 0
# 非空列表
redis> LPUSH job "cook food"
(integer) 1
redis> LPUSH job "have lunch"
(integer) 2
redis> LLEN job
(integer) 2

10、LRANGE

格式:lrange key start stop
返回列表 key 的長度。 如果 key 不存在,則 key 被解釋爲一個空列表,返回 0 . 如果 key 不是列表類型,返回一個錯誤。
可用版本:

>=1.0.0

時間複雜度:
O(1)
返回值:
列表 key 的長度。
示例代碼

# 空列表
redis> LLEN job
(integer) 0
# 非空列表
redis> LPUSH job "cook food"
(integer) 1
redis> LPUSH job "have lunch"
(integer) 2
redis> LLEN job
(integer) 2

11、LRANGE

格式:lrange key start stop
返回列表 key 中指定區間內的元素,區間以偏移量 start 和 stop 指定。 下標(index)參數 start 和 stop 都以 0 爲底,也就是說,以 0 表示列表的第一個元素,以 1 表示列表的第二個元素,以此類推。 你也可以使用負數下標,以 -1 表示列表的最後一個元素, -2 表示列表的倒數第二個元素,以此類推。
注意LRANGE命令和編程語言區間函數的區別
假如你有一個包含一百個元素的列表,對該列表執行 LRANGE list 0 10 ,結果是一個包含 11 個元素的列表,這表明 stop 下標也在 LRANGE 命令的取值範圍之內(閉區間),這和某些語言的區間函數可能不一致,比如 Ruby 的 Range.new 、 Array#slice 和 Python的 range() 函數。
超出範圍的下標
超出範圍的下標值不會引起錯誤。 如果 start 下標比列表的最大下標 end ( LLEN list 減去 1 )還要大,或者 start > stop , LRANGE 返回一個空列表。 如果 stop 下標比 end 下標還要大,Redis 將 stop 的值設置爲 end 。
可用版本:

>=1.0.0

時間複雜度:
O(S+N), S 爲偏移量 start , N 爲指定區間內元素的數量。
返回值:
一個列表,包含指定區間內的元素。
示例代碼

redis> RPUSH fp-language lisp
(integer) 1
redis> LRANGE fp-language 0 0
1) "lisp"
redis> RPUSH fp-language scheme
(integer) 2
redis> LRANGE fp-language 0 1
1) "lisp"
2) "scheme"

12、LREM

格式:lrem key count value
根據參數 count 的值,移除列表中與參數 value 相等的元素。 count 的值可以是以下幾種: count > 0 : 從表頭開始向表尾搜索,移除與 value 相等的元素,數量爲 count 。 count < 0 : 從表尾開始向表頭搜索,移除與 value 相等的元素,數量爲 count 的絕對值。 count = 0 : 移除表中所有與 value 相等的值。
可用版本:

>=1.0.0

時間複雜度:
O(N), N 爲列表的長度。
返回值:
被移除元素的數量。 因爲不存在的 key 被視作空表(empty list),所以當 key 不存在時, LREM 命令總是返回 0 。
示例代碼

# 先創建一個表,內容排列是
# morning hello morning helllo morning
redis> LPUSH greet "morning"
(integer) 1
redis> LPUSH greet "hello"
(integer) 2
redis> LPUSH greet "morning"
(integer) 3
redis> LPUSH greet "hello"
(integer) 4
redis> LPUSH greet "morning"
(integer) 5
redis> LRANGE greet 0 4 # 查看所有元素
1) "morning"
2) "hello"
3) "morning"
4) "hello"
5) "morning"
redis> LREM greet 2 morning # 移除從表頭到表尾,最先發現的兩個 morning
(integer) 2 # 兩個元素被移除
redis> LLEN greet # 還剩 3 個元素
(integer) 3
redis> LRANGE greet 0 2
1) "hello"
2) "hello"
3) "morning"
redis> LREM greet -1 morning # 移除從表尾到表頭,第一個 morning
(integer) 1
redis> LLEN greet # 剩下兩個元素
(integer) 2
redis> LRANGE greet 0 1
1) "hello"
2) "hello"
redis> LREM greet 0 hello # 移除表中所有 hello
(integer) 2 # 兩個 hello 被移除
redis> LLEN greet
(integer) 0

13、LSET

格式:lset key index value
將列表 key 下標爲 index 的元素的值設置爲 value 。 當 index 參數超出範圍,或對一個空列表( key 不存在)進行 LSET 時,返回一個錯誤。 關於列表下標的更多信息,請參考 LINDEX 命令。
可用版本:

>=1.0.0

時間複雜度:
對頭元素或尾元素進行 LSET 操作,複雜度爲 O(1)。 其他情況下,爲 O(N), N 爲列表的長度。
返回值:
操作成功返回 ok ,否則返回錯誤信息。
示例代碼

# 對空列表(key 不存在)進行 LSET
redis> EXISTS list
(integer) 0
redis> LSET list 0 item
(error) ERR no such key
# 對非空列表進行 LSET
redis> LPUSH job "cook food"
(integer) 1
redis> LRANGE job 0 0
1) "cook food"
redis> LSET job 0 "play game"
OK
redis> LRANGE job 0 0
1) "play game"
# index 超出範圍
redis> LLEN list # 列表長度爲 1
(integer) 1
redis> LSET list 3 'out of range'
(error) ERR index out of range

14、LTRIM

格式:ltrim key start stop
對一個列表進行修剪(trim),就是說,讓列表只保留指定區間內的元素,不在指定區間之內的元素都將被刪除。 舉個例子,執行命令 LTRIM list 0 2 ,表示只保留列表 list 的前三個元素,其餘元素全部刪除。 下標(index)參數 start 和 stop 都以 0 爲底,也就是說,以 0 表示列表的第一個元素,以 1 表示列表的第二個元素,以此類推。 你也可以使用負數下標,以 -1 表示列表的最後一個元素, -2 表示列表的倒數第二個元素,以此類推。 當 key 不是列表類型時,返回一個錯誤。 LTRIM 命令通常和 LPUSH 命令或 RPUSH 命令配合使用,舉個例子:

LPUSH log newest_log
LTRIM log 0 99

這個例子模擬了一個日誌程序,每次將最新日誌 newest_log 放到 log 列表中,並且只保留最新的 100 項。注意當這樣使用LTRIM 命令時,時間複雜度是 O(1),因爲平均情況下,每次只有一個元素被移除。
注意LTRIM命令和編程語言區間函數的區別
假如你有一個包含一百個元素的列表 list ,對該列表執行 LTRIM list 0 10 ,結果是一個包含 11 個元素的列表,這表明 stop 下標也在 LTRIM 命令的取值範圍之內(閉區間),這和某些語言的區間函數可能不一致,比如 Ruby 的 Range.new 、 Array#slice 和 Python的 range() 函數。
超出範圍的下標
超出範圍的下標值不會引起錯誤。 如果 start 下標比列表的最大下標 end ( LLEN list 減去 1 )還要大,或者 start > stop , LTRIM 返回一個空列表(因爲 LTRIM 已經將整個列表清空)。 如果 stop 下標比 end 下標還要大,Redis 將 stop 的值設置爲 end 。
可用版本:

>=1.0.0

時間複雜度:
O(N), N 爲被移除的元素的數量。
返回值:
命令執行成功時,返回 ok 。
示例代碼

# 一般情況下標
redis> LRANGE alpha 0 -1 # 建立一個 5 元素的列表
1) "h"
2) "e"
3) "l"
4) "l"
5) "o"
redis> LTRIM alpha 1 -1 # 刪除索引爲 0 的元素
OK
redis> LRANGE alpha 0 -1 # "h" 被刪除
1) "e"
2) "l"
3) "l"
4) "o"
# stop 下標比元素的最大下標要大
redis> LTRIM alpha 1 10086
OK
redis> LRANGE alpha 0 -1
1) "l"
2) "l"
3) "o"
# start 和 stop 下標都比最大下標要大,且 start < sotp
redis> LTRIM alpha 10086 200000
OK
redis> LRANGE alpha 0 -1 # 整個列表被清空,等同於 DEL alpha
(empty list or set)
# start > stop
redis> LRANGE alpha 0 -1 # 在新建一個列表
1) "h"
2) "u"
3) "a"
4) "n"
5) "g"
6) "z"
redis> LTRIM alpha 10086 4
OK
redis> LRANGE alpha 0 -1 # 列表同樣被清空
(empty list or set)

15、LINDEX

格式:lindex key index
返回列表 key 中,下標爲 index 的元素。 下標(index)參數 start 和 stop 都以 0 爲底,也就是說,以 0 表示列表的第一個元素,以 1 表示列表的第二個元素,以此類推。 你也可以使用負數下標,以 -1 表示列表的最後一個元素, -2 表示列表的倒數第二個元素,以此類推。 如果 key 不是列表類型,返回一個錯誤。
可用版本:

>=1.0.0

時間複雜度:
O(N), N 爲到達下標 index 過程中經過的元素數量。 因此,對列表的頭元素和尾元素執行 LINDEX 命令,複雜度爲 O(1)。
返回值:
列表中下標爲 index 的元素。 如果 index 參數的值不在列表的區間範圍內(out of range),返回 nil 。
示例代碼

redis> LPUSH mylist "World"
(integer) 1
redis> LPUSH mylist "Hello"
(integer) 2
redis> LINDEX mylist 0
"Hello"
redis> LINDEX mylist -1
"World"
redis> LINDEX mylist 3 # index 不在 mylist 的區間範圍內
(nil)

16、LINSERT

格式:linsert key BEFORE|AFTER pivot value
將值 value 插入到列表 key 當中,位於值 pivot 之前或之後。 當 pivot 不存在於列表 key 時,不執行任何操作。 當 key 不存在時, key 被視爲空列表,不執行任何操作。 如果 key 不是列表類型,返回一個錯誤。
可用版本:

>=2.2.0

時間複雜度:
O(N), N 爲尋找 pivot 過程中經過的元素數量。
返回值:
如果命令執行成功,返回插入操作完成之後,列表的長度。 如果沒有找到 pivot ,返回 -1 。 如果 key 不存在或爲空列表,返回 0 。
示例代碼

redis> RPUSH mylist "Hello"
(integer) 1
redis> RPUSH mylist "World"
(integer) 2
redis> LINSERT mylist BEFORE "World" "There"
(integer) 3
redis> LRANGE mylist 0 -1
1) "Hello"
2) "There"
3) "World"
# 對一個非空列表插入,查找一個不存在的 pivot
redis> LINSERT mylist BEFORE "go" "let's"
(integer) -1 # 失敗
# 對一個空列表執行 LINSERT 命令
redis> EXISTS fake_list
(integer) 0
redis> LINSERT fake_list BEFORE "nono" "gogogog"
(integer) 0

17、RPOPLPUSH

格式:rpoplpush source destination
命令 RPOPLPUSH 在一個原子時間內,執行以下兩個動作: 1.將列表 source 中的最後一個元素(尾元素)彈出,並返回給客戶端。 2.將 source 彈出的元素插入到列表 destination ,作爲 destination 列表的的頭元素。 舉個例子,你有兩個列表 source 和 destination , source 列表有元素 a, b, c ,destination 列表有元素 x, y, z ,執行 RPOPLPUSH source destination 之後, source列表包含元素 a, b , destination 列表包含元素 c, x, y, z ,並且元素 c 會被返回給客戶端。 如果 source 不存在,值 nil 被返回,並且不執行其他動作。 如果 source 和 destination 相同,則列表中的表尾元素被移動到表頭,並返回該元素,可以把這種特殊情況視作列表的旋轉(rotation)操作。
可用版本:

>=1.2.0

時間複雜度:
O(1)
返回值:
被彈出的元素。
示例代碼

# source 和 destination 不同
redis> LRANGE alpha 0 -1 # 查看所有元素
1) "a"
2) "b"
3) "c"
4) "d"
redis> RPOPLPUSH alpha reciver # 執行一次 RPOPLPUSH 看看
"d"
redis> LRANGE alpha 0 -1
1) "a"
2) "b"
3) "c"
redis> LRANGE reciver 0 -1
1) "d"
redis> RPOPLPUSH alpha reciver # 再執行一次,證實 RPOP 和 LPUSH 的位置
正確
"c"
redis> LRANGE alpha 0 -1
1) "a"
2) "b"
redis> LRANGE reciver 0 -1
1) "c"
2) "d"
# source 和 destination 相同
redis> LRANGE number 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
redis> RPOPLPUSH number number
"4"
redis> LRANGE number 0 -1 # 4 被旋轉到了表頭
1) "4"
2) "1"
3) "2"
4) "3"
redis> RPOPLPUSH number number
"3"
redis> LRANGE number 0 -1 # 這次是 3 被旋轉到了表頭
1) "3"
2) "4"
3) "1"
4) "2"

模式:安全的隊列
Redis 的列表經常被用作隊列(queue),用於在不同程序之間有序地交換消息(message)。一個客戶端通過 LPUSH 命令將消息放入隊列中,而另一個客戶端通過 RPOP 或者 BRPOP 命令取出隊列中等待時間最長的消息。 不幸的是,上面的隊列方法是『不安全』的,因爲在這個過程中,一個客戶端可能在取出一個消息之後崩潰,而未處理完的消息也就因此丟失。 使用 RPOPLPUSH 命令(或者它的阻塞版本 BRPOPLPUSH )可以解決這個問題:因爲它不僅返回一個消息,同時還將這個消息添加到另一個備份列表當中,如果一切正常的話,當一個客戶端完成某個消息的處理之後,可以用 LREM 命令將這個消息從備份表刪除。 最後,還可以添加一個客戶端專門用於監視備份表,它自動地將超過一定處理時限的消息重新放入隊列中去(負責處理該消息的客戶端可能已經崩潰),這樣就不會丟失任何消息了。
模式:循環列表
通過使用相同的 key 作爲 RPOPLPUSH 命令的兩個參數,客戶端可以用一個接一個地獲取列表元素的方式,取得列表的所有元素,而不必像 LRANGE 命令那樣一下子將所有列表元素都從服務器傳送到客戶端中(兩種方式的總複雜度都是 O(N))。 以上的模式甚至在以下的兩個情況下也能正常工作: 1.有多個客戶端同時對同一個列表進行旋轉(rotating),它們獲取不同的元素,直到所有元素都被讀取完,之後又從頭開始。 2.有客戶端在向列表尾部(右邊)添加新元素。這個模式使得我們可以很容易實現這樣一類系統:有 N 個客戶端,需要連續不斷地對一些元素進行處理,而且處理的過程必須儘可能地快。一個典型的例子就是服務器的監控程序:它們需要在儘可能短的時間內,並行地檢查一組網站,確保它們的可訪問性。 注意,使用這個模式的客戶端是易於擴展(scala)且安全(reliable)的,因爲就算接收到元素的客戶端失敗,元素還是保存在列表裏面,不會丟失,等到下個迭代來臨的時候,別的客戶端又可以繼續處理這些元素了。

18、BRPOPLPUSH

格式:brpoplpush source destination timeout
BRPOPLPUSH 是 RPOPLPUSH 的阻塞版本,當給定列表 source 不爲空時, BRPOPLPUSH的表現和 RPOPLPUSH 一樣。 當列表 source 爲空時, BRPOPLPUSH 命令將阻塞連接,直到等待超時,或有另一個客戶端對 source 執行 LPUSH 或 RPUSH 命令爲止。 超時參數 timeout 接受一個以秒爲單位的數字作爲值。超時參數設爲 0 表示阻塞時間可以無限期延長(block indefinitely) 。 更多相關信息,請參考 RPOPLPUSH 命令。
可用版本:

>=2.2.0

時間複雜度:
O(1)
返回值:
假如在指定時間內沒有任何元素被彈出,則返回一個 nil 和等待時長。 反之,返回一個含有兩個元素的列表,第一個元素是被彈出元素的值,第二個元素是等待時長。
示例代碼

# 非空列表
redis> BRPOPLPUSH msg reciver 500
"hello moto" # 彈出元素的值
(3.38s) # 等待時長
redis> LLEN reciver
(integer) 1
redis> LRANGE reciver 0 0
1) "hello moto"
# 空列表
redis> BRPOPLPUSH msg reciver 1
(nil)
(1.34s)

模式:安全隊列
參考 RPOPLPUSH 命令的『安全隊列』模式。
模式:循環列表
參考 RPOPLPUSH 命令的『循環列表』模式。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章