Redis深度歷險記(四)作爲MQ

PubSub

簡單隊列

在Pub成功後進行Sub有時得不到消息,需要延遲以下
在沒有消息時Sub直接返回空而不會阻塞,也有阻塞的方法
要先啓動Sub,否則啓動前的Pub發的信息收不到,另外如果Sub掛了Redis是不會補推的
Redis重啓時所有消息都會丟失,畢竟這時Redis認爲所有Sub都沒了

模式訂閱

這個和RabbitMQ的TopicExchange類似,通過*來做匹配

Stream

Stream相對於PubSub的兩點,一個是重啓不會丟失數據,另外一個是有了Consumer Group(通過xgroup create顯式創建,創建時需指定從哪個消息開始消費)

消費者內部會有一個狀態變量pending_ids,它記錄了當前已經被客戶端讀取,但是還沒有ack的消息.如果客戶端沒有ack,這個變量裏面的消息ID就會越來越多,一旦某個消息被ack,它就開始減少.這個pending_ids變量在Redis官方被稱爲PEL,也就是Pending Entries List,這是一個核心的數據結構,它用來確保客戶端至少消費了消息一次,而不會在網絡傳輸的中途丟失了而沒被處理.

id

消息ID的形式是timestampInMillis-sequence

id也可以通過xadd手工指定,但是必須比前面的id大,否則報錯,這也意味着如果使用了手工,就不能再自動了.按照官方說明,這個一般用來一些小衆場景,例如要和DB的id保持一致

隊列指令

xadd

向Stream追加消息,語法如下,其中*表示id自動產生

XADD mystream * field1 value1 field2 value2 field3 value3

maxlen

可以通過這個參數控制消息隊列長度,示例如下

xadd codehole maxlen 3 * name xiaorui age 1

上面指令執行後,長度不會超過3

xdel

按照官網說法給消息設置標誌位,不影響消息總長度.真正的刪除發生在整個macro-node裏所有entry都被標記
官網給出的這一指令的用處:

This may be useful, for instance, in order to comply with certain privacy policies.

xrange

這裏使用的是closed interval,不會包括刪除消息(這不是顯然麼),使用下面語法返回所有

XRANGE somestream - +

另外如果參數有自動補全功能,官方說明如下

XRANGE will auto-complete the start interval with -0 and end interval with -18446744073709551615, in order to return all the entries that were generated between a given millisecond and the end of the other specified millisecond.

count

可以通過count來指定數量,官網例子如下:
XRANGE somestream 1526985054069-0 + COUNT 1
1) 1) 1526985054069-0
   2) 1) "duration"
      2) "72"
      3) "event-id"
      4) "9"
      5) "user-id"
      6) "839248"

xlen

這裏有一個坑,就是如果隊列不存在會返回0,所以還需要進一步使用type或者exists來明確是空隊列還是不存在,另外根據我的測試,當xdel後長度會減少

消費指令

無組

xread

這個命令把Stream當做一個list看待,從一個指定的地方向後讀取
完整語法如下

XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key …] id [id …]

count

指出需要消費多少消息

block

阻塞多少毫秒,0表示一直阻塞

xgroup

完整語法如下

XGROUP [CREATE key groupname id-or-][SETIDkeygroupnameidor] [SETID key groupname id-or-] [DESTROY key groupname] [DELCONSUMER key groupname consumername]

create

一般用0-0表示從頭消費,而**$**表示結尾

xreadgroup

和xread類似,只是有了讀組內消息

xinfo

可以使用xinfo groups key來查看group消息,也可以通過xinfo consumers key consumer來讀取消費者信息,其中consumer來自於前一個指令

高可用

不過鑑於Redis的指令複製是異步的,在failover發生時,Redis可能會丟失極小部分數據,這一點Redis的的其他數據結構也是一樣的

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