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