Redis stream Java API實踐

最近工作中使用到了消息中間件,另外一個組的同事經過評估選擇了Redis stream作爲最終選擇。我自己寫的性能測試框架自然也需要接入這套消息系統。所以我也抓緊學習起來。

Redis Stream 是 Redis 5.0 版本新增加的數據結構。
Redis Stream 主要用於消息隊列(MQ,Message Queue),Redis 本身是有一個 Redis 發佈訂閱 (pub/sub) 來實現消息隊列的功能,但它有個缺點就是消息無法持久化,如果出現網絡斷開、Redis 宕機等,消息就會被丟棄。

之前還沒發現Redis還有這種使用方法,着實有點少見過怪了。照例我後面會進行一些基本功能的性能測試,下面分享基本功能的使用演示。

準備工作

依賴

如果想自己操作的話,請注意這個版本,因爲在我找資料的過程中發現,不同版本的API有不少的差異,算是踩了一些坑。如果你使用其他版本的redis.clients遇到代碼無法運行的時候,可以直接翻看源碼查看相關參數類型。

Maven依賴:

<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>4.2.3</version>
</dependency>

Gradle依賴:

// https://mvnrepository.com/artifact/redis.clients/jedis
implementation group: 'redis.clients', name: 'jedis', version: '4.2.3'

Redis server版本:Redis 6.2.5

XADD - 添加消息到末尾

如果key對應的隊列不存在,則會自動創建。

首先我們需要創建一個redis.clients.jedis.params.XAddParams,顧名思義就是查詢參數,這裏面有重要的參數:redis.clients.jedis.params.XAddParams#maxLen表示設置隊列的長度,但是不常用。語法如下:

def len = XAddParams.xAddParams()

xadd API使用方式如下:

    public static void main(String[] args) {
        def base = new RedisBase("127.0.0.1", 6379)
        Jedis jedis = base.getJedis()
        def len = XAddParams.xAddParams()
        def map = new HashMap<Integer, String>()
        map.put("FunTester", Time.getDate() + TAB + 325)
            jedis.xadd("fun", len, map)
        jedis.close()

    }

XTRIM - 對流進行修剪,限制長度

這個API就是設置隊列長度。使用方式也非常簡單。

    public static void main(String[] args) {
        def base = new RedisBase("127.0.0.1", 6379)
        Jedis jedis = base.getJedis()
        def xtrim = jedis.xtrim("fun", XTrimParams.xTrimParams().maxLen(10))
        output(xtrim)
        jedis.close()

    }

返回值是丟棄的消息的數量。

XDEL - 刪除消息

這個就是刪除某個消息,使用更簡單了。

    public static void main(String[] args) {
        def base = new RedisBase("127.0.0.1", 6379)
        Jedis jedis = base.getJedis()
        jedis.xdel("fun",new StreamEntryID(1653129389004,1))
        jedis.close()

    }

XLEN - 獲取流包含的元素數量,即消息長度

話不多說了,使用如下:

jedis.xlen("fun")

XREAD - 以阻塞或非阻塞方式獲取消息列表

這個要着重介紹一下,因爲我用的就是這個,首先我們需要創建一個redis.clients.jedis.params.XReadParams,這裏有兩個參數:redis.clients.jedis.params.XReadParams#countredis.clients.jedis.params.XReadParams#block。前者控制返回數量,後者控制阻塞時間,如果時間小於0則認爲不阻塞,等於0則一直會阻塞,小於0會報錯。不設置該參數責任無非阻塞模式。PS:數量不足不會造成阻塞。示例如下:

        def block = XReadParams.xReadParams().count(3).block(1000)

還有我們需要redis.clients.jedis.Jedis#xread(redis.clients.jedis.params.XReadParams, java.util.Map<java.lang.String,redis.clients.jedis.StreamEntryID>)第二個參數,這裏常用的兩種:

        Map<String, StreamEntryID> entry = ["fun": new StreamEntryID()]//獲取歷史消息
        Map<String, StreamEntryID> entry = ["fun": StreamEntryID.LAST_ENTRY]//獲取在請求之後添加的消息

遍歷消息:

        List<Map.Entry<String, List<StreamEntry>>> xread = jedis.xread(block, entry)
        output(xread.size())
        Map.Entry<String, List<StreamEntry>> get = xread.get(0)
        def value = get.getValue()
        value.each {
            println(it.getID())
            println(it.getFields().get("FunTester"))
        }

控制檯響應如下:

16:40:56.065 main redis連接池IP:127.0.0.1,端口:6379,超時設置:5000
16:40:56.280 main 1
1653725282325-0
2022-05-28 16:08:02	325
1653725282325-1
2022-05-28 16:08:02	325
1653725282325-2
2022-05-28 16:08:02	325

XRANGE - 獲取消息列表,會自動過濾已經刪除的消息

這個API獲取某個範圍內的消息,有個startend的參數,可以傳String類型的消息ID,也可以傳redis.clients.jedis.StreamEntryID,方法重載的比較多,有興趣可以翻一翻源碼。

jedis.xrange("fun", "1653129389045-0", "1653129389047-0")

後面會對Redis stream API進行性能測試,歡迎繼續關注FunTester。

Have Fun ~ Tester !

閱讀原文,跳轉我的倉庫地址

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