單執行緒的redis如何實現阻塞佇列

2021-10-01 12:08:08 字數 959 閱讀 8891

從redis的api可以了解到lpop,rpop可以實現乙個阻塞式佇列。那疑問就來了,redis不是單執行緒的嗎,如果阻塞了,那其他操作就執行不了呀。事實不是這樣的

redis的執行緒模型,是接收客戶端命令的執行緒時 i/o 多路復用的,再通過檔案事件分配器單執行緒執行的。如下圖,程式總是會將所有產生事件的套接字都入隊到乙個佇列裡面, 然後通過這個佇列, 以有序(sequentially)、同步(synchronously)、每次乙個套接字的方式向檔案事件分派器傳送套接字: 當上乙個套接字產生的事件被處理完畢之後(該套接字為事件所關聯的事件處理器執行完畢), i/o 多路復用程式才會繼續向檔案事件分派器傳送下乙個套接字

那實際上我們關心的blpop 命令的執行就是在檔案事件分派器分派後是怎麼執行的了。

對blpop命令的處理流程是這樣的:

redis先找到對應的key的list,如果list不為空則pop乙個資料返回給客戶端;

如果list為空,或者list不存在,就將該key新增到乙個blockling_keys的字典中,value就是想訂閱該key的client鍊錶。此時對應的client的為block狀態

當有push 型別的命令進來的時候,先從blocking_keys中查詢是否存在對應的key,如果存在就往ready_keys這個鍊錶中新增該key;同時將value插入到對應的list中,並響應客戶端。

每次處理完客戶端命令後都會遍歷ready_keys,並通過blocking_keys找到對應的client,依次將對應list的資料pop出來並響應對應的client;同時檢查是否需要再次block。

整個阻塞執行過程相當於是分散開的,每次請求結束後都判斷之前的阻塞列表是否滿足執行條件,類似我們用輪詢來實現長連線的功能。所以看似阻塞的命令對其他命令的執行時不會有影響的,它們依然是單執行緒的。

參考:

如何理解redis單執行緒

redis是以socket方式通訊,socket服務端可同時接受多個客戶端請求連線,也就是說,redis服務同時面對多個redis客戶端連線請求,而redis服務本身是單執行緒執行。推薦學習 redis 教程 假設,現在有a,b,c,d,e五個客戶端同時發起redis請求,a優先稍微一點點第乙個到達...

Redis單執行緒

redis 的單執行緒主要是指 redis 的網路 io 和鍵值對讀寫是由乙個執行緒來完成的,這也是 redis 對外提供鍵值儲存服務的主要流程。當多個客戶端發起命令,這些命令併發執行時,在redis內部,會排隊逐個執行,也就是執行命令的那個操作是由乙個執行緒執行的。但 redis 的其他功能,比如...

redis的單執行緒

1 完全基於記憶體,絕大部分請求是純粹的記憶體操作,非常快速。資料存在記憶體中,類似於hashmap,hashmap的優勢就是查詢和操作的時間複雜度都是o 1 2 資料結構簡單,對資料操作也簡單,redis中的資料結構是專門進行設計的 3 採用單執行緒,避免了不必要的上下文切換和競爭條件,也不存在多...