?
Dieses Dokument verwendet PHP-Handbuch für chinesische Websites Freigeben
BLPOP key [key ...] timeout
自2.0.0起可用。
時間復雜度: O(1)
BLPOP是一個阻塞列表pop元素。它是LPOP的阻塞版本,因為它在沒有任何元素從給定列表中彈出時阻塞連接。一個元素從第一個非空列表的頭部彈出,并按給定的順序檢查給定的鍵。
當調用BLPOP時,如果至少有一個指定鍵包含非空列表,則會從列表頭部彈出一個元素,并將其從彈出的列表中彈出并返回給調用者key
。
按照它們給出的順序檢查密鑰。假設該鍵list1
不存在list2
并且list3
保存非空列表。考慮下面的命令:
BLPOP list1 list2 list3 0
BLPOP保證從列表中存儲的列表中返回一個元素list2
(因為它是檢查時的第一個非空列表list1
,list2
并按此list3
順序)。
如果沒有指定的密鑰存在,則BLPOP將阻止該連接,直到另一個客戶端對其中一個密鑰執(zhí)行LPUSH或RPUSH操作。
一旦在其中一個列表上出現(xiàn)新數(shù)據(jù),客戶端將返回解鎖它的密鑰名稱和彈出的值。
當BLPOP導致客戶端阻塞且指定了非零超時時,客戶端將nil
在指定超時過期時解除阻止返回多批量值,而不對至少一個指定鍵執(zhí)行推送操作。
超時參數(shù)被解釋為指定要阻止的最大秒數(shù)的整數(shù)值??梢允褂昧愠瑫r來無限期地阻塞。
如果客戶端試圖阻塞多個密鑰,但至少有一個密鑰包含元素,則返回的密鑰/元素對是從左到右具有一個或多個元素的第一個密鑰。在這種情況下,客戶端不會被阻止。因此,舉例來說BLPOP key1 key2 key3 key4 0
,假設兩key2
和key4
非空,將總是返回從一個元素key2
。
如果同一個密鑰阻塞了多個客戶端,則要服務的第一個客戶端是等待更多時間的客戶端(為該密鑰阻塞的第一個客戶端)。一旦客戶端被解除封鎖,它不保留任何優(yōu)先權,當它再次阻止下一次BLPOP調用時,它將被相應地服務于已經(jīng)被相同密鑰阻塞的客戶端的數(shù)量,這將在它之前被服務(從第一個到最后被阻止)。
當客戶端同時阻塞多個密鑰并且多個密鑰中同時有元素時(由于事務或Lua腳本向多個列表添加元素),客戶端將使用第一個密鑰解除阻塞(假設它有足夠的元素為我們的客戶提供服務,因為可能有其他客戶也在等待此密鑰)。基本上,在執(zhí)行每條命令之后,Redis將運行接收數(shù)據(jù)并且至少有一個客戶端被阻止的所有密鑰的列表。該列表按新元素到達時間排序,從接收數(shù)據(jù)的第一個密鑰到最后一個密鑰。對于每個已處理的密鑰,只要該密鑰中包含元素,Redis將以FIFO方式為所有等待該密鑰的客戶端提供服務。當密鑰為空或者不再有客戶端等待該密鑰時,
BLPOP
的行為。有時候,一個列表可以在相同的概念性命令的上下文中接收多個元素:
Variadic推送操作LPUSH mylist a b c
。
在對同一列表執(zhí)行多個推動操作的MULTI塊的EXEC后。
使用Redis 2.6或更新版本執(zhí)行Lua腳本。
當有多個客戶端阻塞的列表中推入多個元素時,Redis 2.4和Redis 2.6或更新版本的行為是不同的。
對于Redis 2.6來說,執(zhí)行多次推送的命令會被執(zhí)行,并且只有在被阻止的客戶端執(zhí)行命令后才會執(zhí)行??紤]這個命令序列。
Client A: BLPOP foo 0Client B: LPUSH foo a b c
如果使用Redis 2.6或更高版本的服務器發(fā)生上述情況,則客戶端A將與該c
元素一起提供服務,因為在該列表包含LPUSH命令之后c,b,a
,因此從左邊取一個元素意味著返回c
。
相反,Redis 2.4以不同的方式工作:客戶端在推送操作的上下文中服務,因此只要LPUSH foo a b c
開始將第一個元素推送到列表中,它就會被傳送到客戶端A,客戶端A將接收a
(第一個元素被推送)。
Redis 2.4的行為在將數(shù)據(jù)復制或保存到AOF文件時產(chǎn)生了很多問題,因此在Redis 2.6中引入了更通用和語義更簡單的行為,以防止出現(xiàn)問題。
請注意,出于同樣的原因,Lua腳本或MULTI/EXEC
塊可能會將元素推入列表中,然后刪除列表。在這種情況下,只要在執(zhí)行單個命令,事務或腳本后沒有數(shù)據(jù)出現(xiàn)在列表中,被阻止的客戶端根本就不會被服務,并且將繼續(xù)被阻止。
BLPOP
在MULTI
/ EXEC
交易中BLPOP可以與流水線一起使用(發(fā)送多個命令并批量讀取響應),但是這種設置幾乎完全在它是流水線的最后一個命令時才有意義。
在MULTI / EXEC模塊中使用BLPOP沒有多大意義,因為它需要阻塞整個服務器以便以原子方式執(zhí)行該模塊,而這又不允許其他客戶端執(zhí)行推送操作。出于這個原因,當列表為空時,MULTI / EXEC中的BLPOP行為是返回一個nil
多批量回復,這與達到超時的時候發(fā)生的情況是一樣的。
如果你喜歡科幻小說,想想在MULTI / EXEC塊內以無限速度流動的時間......
陣列回復:具體為:
nil
當沒有元件可以被彈出多批量和超時過期。
第一個元素是元素被彈出的鍵的名稱,第二個元素是彈出元素的值的兩元素的多塊。
redis> DEL list1 list2(integer) 0redis> RPUSH list1 a b c(integer) 3redis> BLPOP list1 list2 01) "list1"2) "a"
當BLPOP向客戶端返回一個元素時,它也從列表中刪除該元素。這意味著該元素只存在于客戶端的上下文中:如果客戶端在處理返回的元素時崩潰,它將永遠丟失。
對于某些需要更可靠的消息傳遞系統(tǒng)的應用程序,這可能會造成問題。當出現(xiàn)這種情況時,請檢查BRPOPLPUSH命令,這是BLPOP的一種變體,它在將返回元素返回給客戶機之前將其返回的元素添加到目標列表中。
使用阻塞列表操作可以掛載不同的阻塞原語。例如,對于某些應用程序,您可能需要阻止將元素等待到Redis集中,以便只要將新元素添加到Set中,就可以檢索它,而無需通過輪詢。這將需要SPOP的阻止版本不可用,但使用阻止列表操作,我們可以輕松完成此任務。
使用者會這樣做:
LOOP forever WHILE SPOP(key) returns elements ... process elements ... END BRPOP helper_key END
在生產(chǎn)者方面,我們將簡單地使用:
MULTI SADD key element LPUSH helper_key x EXEC