redis筆記5 stream消息隊列

基礎

Stream結構相當於一個消息隊列。消息是存儲在磁盤上的,而且是鏈式結構。每個stream都有自己的唯名稱,是redis的key。stream在集羣情況下,也是異步複製的。

每個stream上可以有多個消費組,每個消費組都可以有自己的遊標last_delivered_id在Stream上往前移動,表示當前消費組消費到了那條消息。

消費組有Stream內的唯一的名稱,使用xgroup_create創建消費組並指定名稱,創建的時候,需要指定某個消息的ID,該ID用於初始化last_delivered_id變量。

同一個消費組的各個Consumer是競爭關係,只要有一個效消費了消息,那麼就會移動last_derivered_id

消費者內部有一個狀態變量pending_ids ,記錄了當前已經被客戶端讀取但是還沒有ack的消息。如果當前客戶端沒有ack,則其內部的消息ID越來越多,一旦某個消息被ack,則變量減少。該變量成爲PEL (pending ertries list),該變量用來保證客戶端至少消費了一次,並且不會在網絡中途丟失了而沒被處理。PEL內部存儲的是已經發出去的消息的ID。客戶端在重連redis之後,可以再次收到PEL中的ID列表。xreadgroup的起始消息必須是任意有效的消息ID,一般參數設置爲0-0,表示讀取所有PEL的消息以及last_delivered_id之後的新消息。

如果消息一直沒有ack,則會導致PEL過大,消耗內存。

消息的ID是timeStampInMillis-sqquence,表示當前毫秒的消息序列;消息的內容是鍵值對,形如Hash結構的鍵值對。

基本操作方式

操作Stream

  • xadd:向Stream追加消息
  • xdel:從Stream中刪除消息,刪除僅僅是設置標誌位,不影響消息總長度。
  • xrange:獲取Stream中的消息列表,自動過濾已經刪除的消息。-表示最小值,+表示最大值。
  • xlen:獲取Stream的消息長度,所有在鏈表中存在的消息
  • del:刪除整個Stream中的所有消息。

xadd命令,可以指定最長的長度,幹掉舊的消息:

xadd myStream maxlen 1000  aaa bb ccc # 新增aaa bb ccc消息,同時鏈表不超過1000長度

獨立消費:使用xread指令,把Stream當作普通的鏈表使用,此時我們可以忽略消費組的存在。注意,使用xread指令,一定要記得當前消費到的ID,下次調用xread時,需要傳入該ID作爲參數。可以進行阻塞操作:

xread block 1000 count 1 streams myStream $

myStream隊尾讀取1個消息,不存在時阻塞1s

創建消費組
使用xgroup create創建效費組,需要提供其實消息的ID來初始化last_delivered_id變量。
比如:

xgroup create myStream cg1 0-0  # 從頭部開始消費
xgroup create myStream cg2 $ # 從尾部開始消費

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-uONW3ZH0-1574302168977)(en-resource://database/2763:1)]

消費消息
客戶端使用xreadgroup命令對組內消息進行消費,提供:消費組名稱、消費者名稱和啓示消息ID,可以阻塞等待新的消息。消費者讀取消息後,對一個的消息ID進入PEL中,消費者消費完畢後,需要發送XACK,此時PEL中的結構會刪除對應的消息。注意,消費完消息後,一定要執行XACK !!!!
比如:

xreadgroup GROUP cg1 c1 count 1 streams myStream
xreadgroup GROUP cg1 c1 block 0 count 1 streams myStream

Redis的Stream不支持分區,需要使用多個Stream纔可以執行分區。

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