天天看點

Redis Stream——作為消息隊列的典型應用場景Redis StreamRedis Stream實戰——IRC系統Redis Stream實戰——IoT資料采集作者簡介

Redis Stream

Redis最新的大版本5.0已經

RC1

了,其中最重要的Feature莫過于

Redis Stream

了,關于Redis Stream的基本使用介紹和設計理念可以看我之前的一篇文章(

Redis Stream簡介

)。

Redis Stream

本質上是在Redis核心上(非Redis Module)實作的一個消息釋出訂閱功能元件。相比于現有的

PUB/SUB

BLOCKED LIST

,其雖然也可以在簡單的場景下作為消息隊列來使用,但是

Redis Stream

無疑要完善很多。

Redis Stream

提供了消息的持久化和主備複制功能、新的RadixTree資料結構來支援更高效的記憶體使用和消息讀取、甚至是類似于

Kafka

Consumer Group

功能。今天我們重點關注怎麼在實際業務場景下去使用

Redis Stream

Redis Stream實戰——IRC系統

相信大家對IRC都比較了解了(還記得被和諧掉的xx聊天室嗎:-)),很多知名的開源項目(包括Redis)都有自己的IRC頻道,友善開發者和使用者實時的進行思想火花的碰撞,我們今天介紹的主角——Redis Stream,本身就是起源于IRC中一個使用者的idea。IRC的模型如下,

Redis Stream——作為消息隊列的典型應用場景Redis StreamRedis Stream實戰——IRC系統Redis Stream實戰——IoT資料采集作者簡介

在某個IRC頻道中的使用者,既可以向所有的其他使用者自由的發送消息,也可以接收其他所有使用者發送的消息。如果要基于Redis來建構一個IRC系統,那我們不由自主的會想到使用Redis的

PUB/SUB

功能,

Redis Stream——作為消息隊列的典型應用場景Redis StreamRedis Stream實戰——IRC系統Redis Stream實戰——IoT資料采集作者簡介
Redis Stream——作為消息隊列的典型應用場景Redis StreamRedis Stream實戰——IRC系統Redis Stream實戰——IoT資料采集作者簡介

可以看到,基于

PUB/SUB

,隻需要所有的使用者(client)都訂閱(

subscribe

)同一個IRC頻道(channel1),就可以接收所有使用者發出的消息了。發出消息時,隻需使用釋出指令(

publish

)指令即可。整個業務邏輯非常的清晰簡單,這也是Redis強大和流行的重要原因——提供的功能和資料結構能盡可能提升開發者的開發效率。

但是基于

PUB/SUB

建構的IRC,有一個問題是

PUB/SUB

的消息模型是

Fire and Forgot

。也就是說Redis本身并不儲存任何曆史消息,如果IRC中某個使用者的網絡連接配接出現異常,重新加入IRC後,他是看不到斷鍊期間的聊天記錄的,新加入的使用者同樣也看不到最近一段時間的曆史記錄,這個對使用者迅速的了解目前讨論的問題非常不便。此外,如果Redis發生了重新開機,所有的使用者也需要重新訂閱頻道。

那如果基于Redis Stream來建構IRC呢?

  • 建立頻道
# 目前Redis還不支援建立空的stream,是以我們可以添加一個特殊消息,
# 來建立一個新的stream(頻道)
ip:7000> xadd channel1 * create-channel null
1528702126345-0           
  • 發送消息
# 發送一條消息,隻需要使用xadd指令即可,我們可以給每條消息命名,順便帶上消息來源,友善業務邏輯處理。
# 我們也可以一次發送多條消息,可以作為優化網絡開銷的一種手段。
ip:7000> xadd channel1 * msg1-tony "Hello everyone."
1528702503377-0
ip:7000> xadd channel1 * msg2-tony "I am a big Redis fan." msg3-tony "Hope we can learn from each other.:-)"
1528702573546-0           
  • 接收消息
# 新使用者初次加入頻道時,指定'$'作為一個特殊起始ID讀取消息,表示隻接收最新的頻道消息
# 之後如果新消息,隻需從上一次的傳回結果ID繼續讀取即可
# 當沒有新消息時,xread指令傳回空集
ip:7000> xread BLOCK 100 STREAMS channel1 $
1) 1) "channel1"
   2) 1) 1) 1528703048021-0
         2) 1) "msg1-tony"
            2) "Hello everyone."
ip:7000> xread BLOCK 100 STREAMS channel1 1528703048021-0
1) 1) "channel1"
   2) 1) 1) 1528703061087-0
         2) 1) "msg2-tony"
            2) "I am a big Redis fan."
            3) "msg3-tony"
            4) "Hope we can learn from each other.:-)"
ip:7000> xread BLOCK 100 STREAMS channel1 1528703061087-0
(nil)           
  • 擷取曆史消息

    前面我們提到了,

    Redis Stream

    PUB/SUB

    相比,一個重要的差別是,

    Redis Stream

    可以擷取曆史發送的消息,是以當一個使用者斷開連接配接重新加入IRC時,可以通過如下方式擷取曆史消息:
# 1528703061087-0 為使用者記錄的最後接收的消息的ID
ip:7000> xrange channel1 1528703061087-0 +
1) 1) 1528706457462-0
   2) 1) "msg1-andy"
      2) "Nice to meet you guys."
2) 1) 1528706497200-0
   2) 1) "msg4-tony"
      2) "When will Redis 5.0 GA comes out?"
3) 1) 1528706601973-0
   2) 1) "msg1-antirez"
      2) "I think it will arrive in the second half of 2018."           

Redis Stream實戰——IoT資料采集

Redis除了強大而且豐富的資料結構支援,還有一個很重要的能力是跨平台,甚至是作為一個嵌入式的存儲系統跑在基于ARM的平台上,比如作者之前就宣稱,

Redis成功的跑在了“樹莓派”上

試想一下,在IoT時代,會有無數随時随地可以接入網際網路的智能裝置,你家裡的冰箱會實時的彙報,冰箱裡面有哪些食物,數量多少,新鮮程度如何,空調會彙報現在溫度多少,空氣品質如何,你的車會不斷的彙報發動機的各項資料,變速箱的各項資料,車内空氣的各項資料。這麼多的IoT裝置會形成巨大的資料洪流,采集完成後在雲端進行分析,産生巨大的使用者價值。

這些資料雖然内容各個不同,但是都有一個共同的特點,都是一種時序資料。看到這裡,你可能會突然發現,Redis Stream從設計初就是為了支援時間序列資料而生(見第一部分Redis Stream介紹),Redis又成功的跑在了ARM平台,而未來物聯網會有

萬億級的裝置基于ARM平台

。是以,我們不由自主的可以猜想,除了現在在各種網際網路服務中作為Cache和KV存儲廣泛應用,Redis下一個大放異彩的領域也許就在物聯網。

Redis Stream——作為消息隊列的典型應用場景Redis StreamRedis Stream實戰——IRC系統Redis Stream實戰——IoT資料采集作者簡介

上面這個圖,就是一個典型的物聯網裝置資訊采集,分析,展示的架構。Redis作為一個嵌入式的存儲系統跑在各個IoT裝置上,各個裝置使用

Redis Stream

暫存産生的時序資料,然後再異步的推送到雲端。雲上部署的各個業務程式,會讀取推送的原始資料,基于一定的規則進行分析,然後将結果寫入可靠的資料存儲系統。使用者讀取結果,在APP或者web頁面上進行展示,進而整個系統形成一個閉環。

作者簡介

夏德軍,花名夏周,阿裡雲Redis技術專家,負責阿裡雲Redis核心開發和維護。活躍于開源社群,Redis Contributor,設計并實作了阿裡雲Redis開源項目ApsaraCache的部分核心feature,如時間點恢複,binlog同步等。

招聘:

阿裡雲-技術專家-KVstore

繼續閱讀