redis命令詳解與使用情境舉例——List

來源:互聯網
上載者:User
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) 0redis> LPUSH command "update system..."  # 為command列表增加一個值(integer) 1redis> LPUSH request "visit page"        # 為request列表增加一個值(integer) 1redis> 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) 0redis> EXISTS command(integer) 0redis> BLPOP job command 300     # 因為key一開始不存在,所以操作會被阻塞,直到另一用戶端對 job 或者 command 列表進行 PUSH 操作。1) "job"                         # 這裡被 push 的是 job2) "do my home work"             # 被彈出的值(26.26s)                         # 等待的秒數redis> BLPOP job command 5       # 等待逾時的情況(nil)(5.66s)                          # 等待的秒數

相同的key被多個用戶端同時阻塞
相同的 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) 1redis> MULTIOKredis> BLPOP job 30QUEUEDredis> EXEC           # 不阻塞,立即返回1) 1) "job"   2) "programming" 對空列表進行操作redis> LLEN job      # 空列表(integer) 0redis> MULTIOKredis> BLPOP job 30QUEUEDredis> 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_keyEND

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

MULTI    SADD key element    LPUSH helper_key xEXEC
BRPOP key [key …] timeout

BRPOP 是列表的阻塞式(blocking)彈出原語。
它是 RPOP 命令的阻塞版本,當給定列表內沒有任何元素可供彈出的時候,串連將被 BRPOP 命令阻塞,直到等待逾時或發現可彈出元素為止。
當給定多個 key 參數時,按參數 key 的先後順序依次檢查各個列表,彈出第一個非空列表的尾部元素。
關於阻塞操作的更多資訊,請查看 BLPOP 命令, BRPOP 除了彈出元素的位置和 BLPOP 不同之外,其他表現一致。
可用版本:
2.0.0+
時間複雜度:
O(1)
傳回值:
假如在指定時間內沒有任何元素被彈出,則返回一個 nil 和等待時間長度。
反之,返回一個含有兩個元素的列表,第一個元素是被彈出元素所屬的 key ,第二個元素是被彈出元素的值。

redis> LLEN course(integer) 0redis> RPUSH course algorithm001(integer) 1redis> RPUSH course c++101(integer) 2redis> BRPOP course 301) "course"             # 彈出元素的 key2) "c++101"             # 彈出元素的值
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) 1redis> LRANGE reciver 0 01) "hello moto"

空列表

redis> BRPOPLPUSH msg reciver 1(nil)(1.34s)
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) 1redis> LPUSH mylist "Hello"(integer) 2redis> LINDEX mylist 0"Hello"redis> LINDEX mylist -1"World"redis> LINDEX mylist 3        # index不在 mylist 的區間範圍內(nil)
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) 1redis> RPUSH mylist "World"(integer) 2redis> LINSERT mylist BEFORE "World" "There"(integer) 3redis> LRANGE mylist 0 -11) "Hello"2) "There"3) "World"

對一個非空列表插入,尋找一個不存在的 pivot

redis> LINSERT mylist BEFORE "go" "let's"(integer) -1      
                          # 失敗

對一個空列表執行 LINSERT 命令

redis> EXISTS fake_list(integer) 0redis> LINSERT fake_list BEFORE "nono" "gogogog"(integer) 0  
LLEN key

返回列表 key 的長度。
如果 key 不存在,則 key 被解釋為一個空列表,返回 0 .
如果 key 不是清單類型,返回一個錯誤。
可用版本:
1.0.0
時間複雜度:
O(1)
傳回值:
列表 key 的長度。
空列表

redis> LLEN job(integer) 0

非空列表

redis> LPUSH job "cook food"(integer) 1redis> LPUSH job "have lunch"(integer) 2redis> LLEN job(integer) 2  
LPOP key

移除並返回列表 key 的頭元素。
可用版本:
1.0.0#
時間複雜度:
O(1)
傳回值:
列表的頭元素。
當 key 不存在時,返回 nil 。

redis> LLEN course(integer) 0redis> RPUSH course algorithm001(integer) 1redis> RPUSH course c++101(integer) 2redis> LPOP course  # 移除頭元素"algorithm001" 
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) 2redis> LRANGE languages 0 -1     # 列表允許重複元素1) "python"2) "python"加入多個元素redis> LPUSH mylist a b c(integer) 3redis> LRANGE mylist 0 -11) "c"2) "b"3) "a"   
LPUSHX key value

將值 value 插入到列表 key 的表頭,若且唯若 key 存在並且是一個列表。
和 LPUSH 命令相反,當 key 不存在時, LPUSHX 命令什麼也不做。
可用版本:
2.2.0+
時間複雜度:
O(1)
傳回值:
LPUSHX 命令執行之後,表的長度。
對空列表執行 LPUSHX

redis> LLEN greet                       # greet 是一個空列表(integer) 0redis> LPUSHX greet "hello"             # 嘗試 LPUSHX,失敗,因為列表為空白(integer) 0對非空列表執行 LPUSHXredis> LPUSH greet "hello"              # 先用 LPUSH 建立一個有一個元素的列表(integer) 1redis> LPUSHX greet "good morning"      # 這次 LPUSHX 執行成功(integer) 2redis> LRANGE greet 0 -11) "good morning"2) "hello"   
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 )還要大,那麼 LRANGE 返回一個空列表。
如果 stop 下標比 end 下標還要大,Redis將 stop 的值設定為 end 。
可用版本:
1.0.0+
時間複雜度:
O(S+N), S 為位移量 start , N 為指定區間內元素的數量。
傳回值:
一個列表,包含指定區間內的元素。

redis> RPUSH fp-language lisp(integer) 1redis> LRANGE fp-language 0 01) "lisp"redis> RPUSH fp-language scheme(integer) 2redis> LRANGE fp-language 0 11) "lisp"2) "scheme"
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) 1redis> LPUSH greet "hello"(integer) 2redis> LPUSH greet "morning"(integer) 3redis> LPUSH greet "hello"(integer) 4redis> LPUSH greet "morning"(integer) 5redis> 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) 3redis> LRANGE greet 0 21) "hello"2) "hello"3) "morning"redis> LREM greet -1 morning    # 移除從表尾到表頭,第一個 morning(integer) 1redis> LLEN greet               # 剩下兩個元素(integer) 2redis> LRANGE greet 0 11) "hello"2) "hello"redis> LREM greet 0 hello      # 移除表中所有 hello(integer) 2                    # 兩個 hello 被移除redis> LLEN greet(integer) 0
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) 0redis> LSET list 0 item(error) ERR no such key對非空列表進行 LSETredis> LPUSH job "cook food"(integer) 1redis> LRANGE job 0 01) "cook food"redis> LSET job 0 "play game"OKredis> LRANGE job  0 01) "play game"index 超出範圍redis> LLEN list                    # 列表長度為 1(integer) 1redis> LSET list 3 'out of range'(error) ERR index out of range
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 。
情況 1: 常見情況, start 和 stop 都在列表的索引範圍之內

redis> LRANGE alpha 0 -1       # alpha 是一個包含 5 個字串的列表1) "h"2) "e"3) "l"4) "l"5) "o"redis> LTRIM alpha 1 -1        # 刪除 alpha 清單索引為 0 的元素OKredis> LRANGE alpha 0 -1       # "h" 被刪除了1) "e"2) "l"3) "l"4) "o"

情況 2: stop 比列表的最大下標還要大

redis> LTRIM alpha 1 10086     # 保留 alpha 清單索引 1 至索引 10086 上的元素OKredis> LRANGE alpha 0 -1       # 只有索引 0 上的元素 "e" 被刪除了,其他元素還在1) "l"2) "l"3) "o"

情況 3: start 和 stop 都比列表的最大下標要大,並且 start < stop

redis> LTRIM alpha 10086 123321OKredis> LRANGE alpha 0 -1        # 列表被清空(empty list or set)

情況 4: start 和 stop 都比列表的最大下標要大,並且 start > stop

redis> RPUSH new-alpha "h" "e" "l" "l" "o"     # 重建立立一個新列表(integer) 5redis> LRANGE new-alpha 0 -11) "h"2) "e"3) "l"4) "l"5) "o"redis> LTRIM new-alpha 123321 10086    # 執行 LTRIMOKredis> LRANGE new-alpha 0 -1           # 同樣被清空(empty list or set)
RPOP key

移除並返回列表 key 的尾元素。
可用版本:
1.0.0+
時間複雜度:
O(1)
傳回值:
列表的尾元素。
當 key 不存在時,返回 nil 。

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

命令 RPOPLPUSH 在一個原子時間內,執行以下兩個動作:
● 將列表 source 中的最後一個元素(尾元素)彈出,並返回給用戶端。
● 將 source 彈出的元素插入到列表 destination ,作為 destination 列表的的頭元素。
舉個例子,你有兩個列表 source 和 destination , source 列表有元素 a, b, c , destination 列表有元素 x, y, z ,執行 RPOPLPUSH sourcedestination 之後, 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"

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.