Redis 实用技术——消息发布和订阅
引言
發布訂閱模型是redis的重要功能,它可以像網站動態一樣,將消息發送到多個訂閱者的主頁里。
一、常用命令
二、消息格式
消息是一個有三個元素的多塊響應:
如上圖,發布者向 mysub 頻道發送了一條消息,redis會返回當前訂閱者數量。
而訂閱者這邊,當第一次訂閱時,響應塊分為 3 行,
第一行表示消息類型,subscribe :訂閱成功 ;unsubscribe:表示取消訂閱;message :表示這個響應塊是一個發布的消息
第二行表示頻道名稱
第三行根據消息類型不同,subscribe/unsubscribe 時會響應目前訂閱頻道數量,message 時會響應具體消息內容。
注意:發布訂閱與key所在空間沒有任何關系,它不受任何級別的干擾,例如,db1可以訂閱db10的發布消息。如果需要區分某些頻道,只能使用頻道名稱來區分,比如在頻道名稱前加上環境信息:dev-xxx,test-xxx,prod-xxxx等等。
三、模式匹配訂閱
psubscribe 配合通配符來匹配多個頻道,如下命令可以匹配到 dev.msg 、dev.tag.other 等符合 dev.* 模式的全部頻道:
PSUBSCRIBE dev.*當作模式匹配結果的消息會以不同的格式發送:
消息類型是pmessage,這是另一客戶端發出的PUBLISH命令的結果,匹配一個模式匹配訂閱。第一個元素是原匹配的模式,第三個元素是原頻道名稱,最后一個元素是實際消息內容。
如果既使用了模式匹配,又使用了普通的訂閱方式,例如:
subscribe foo psubscribe f*那么如果一個消息被發布到 foo,客戶端會接收到兩條消息:一條是 message 類型,另一條是 pmessage類型。
四、發布訂閱的使用場景與注意事項
Redis的發布訂閱功能可以應用到哪些場景?聊天室?網站用戶的動態發布?
首先,需要注意一個問題,當客戶端訂閱了一個頻道后,那么它只能接收到訂閱之后發布的消息,也就是說,發布的消息是實時的。
因此,我們可以用它來做一個簡易聊天室,或彈幕功能。但面對更復雜一些的場景,例如,如果想在客戶端加載以前發布的消息又該如何解決這個問題呢?
這里的需求是,客戶端即可以接受實時消息,又可以通過某些操作獲取到訂閱前的歷史消息,如何實現?
這時,我們就可以結合redis的其他緩存功能,例如 ZSet 來存儲 3天內的發布消息,再往前的數據就持久化到數據庫。
這樣,我們即實現了實時的訂閱發布,也細分了歷史數據——三天內和更久的數據:
對于三天內的數據,如何存放在ZSet中?有兩種方案,需要根據業務具體考慮,要么是根據時間,要么是根據數據數量,比如某些數據就是只需要存100條。
按時間緩存,如上圖中的 3 天,是比較常見的常見,我們可以在 socre 中標記日期,以此來維持數據的容量,參考使用 zremrangebyscore(按分數,即時間戳)或zremrangebyrank(按數據量,如最后100條)。
那么具體一點的實現模型就可以是這樣:
?
總結
以上是生活随笔為你收集整理的Redis 实用技术——消息发布和订阅的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 项目部署服务器 jstl,Springb
- 下一篇: MySQL 优化 —— MySQL 如何