1. Redis 6.0 新特性篇:Client Side Cache 是嘛玩意?

        共 3400字,需瀏覽 7分鐘

         ·

        2021-09-22 20:32

        為啥需要客戶端緩存

        RedisTracking Feature 的實現(xiàn)代碼在: https://github.com/antirez/redis/blob/unstable/src/tracking.c。

        很多公司使用 Redis 做緩存系統(tǒng),并且很好的提高了數(shù)據(jù)訪問的性能,為了進一步應(yīng)對熱點數(shù)據(jù),還是會在 Redis 的 Client 端緩存一部分熱點數(shù)據(jù),用來應(yīng)對「吃瓜事件」。

        比如,「這該死的 996 福報」、「吳亦凡之大方牢房」、「時間管理大師」、「思聰舔我不得就錘我」、「吳秀波之談戀愛么,能坐牢的那種」……

        除了使用 Redis 緩存避免直接訪問數(shù)據(jù)庫以外,還會加更多的cache 層,比如采用 Memcachced 作為熱點數(shù)據(jù)的本地緩存:

        1. 先去 Memcachced中查詢數(shù)據(jù),命中直接返回。

        2. Memcachced 未命中,則再從 Redis 查詢,命中則返回數(shù)據(jù),并在 Memcachced 保存這個數(shù)據(jù)。

        3. Redis 未命中,則去 MySQL中查詢,并依次設(shè)置到 Redis 和 Memcachced中。

        訪問本地內(nèi)存的的性能必然比通過網(wǎng)絡(luò)訪問 Redis 快,所以這種模式可以極大地減少獲取數(shù)據(jù)的延遲,并且可以減少 Redis 的負載,提高性能。

        1. 訪問 Redis 獲取數(shù)據(jù),服務(wù)器響應(yīng)。

        查詢Redis
        1. 使用客戶端緩存,應(yīng)用程序?qū)@取的熱門的數(shù)據(jù)存儲在應(yīng)用程序中,無需再次通過網(wǎng)絡(luò)訪問 Redis。
        應(yīng)該緩存什么
        • 我們不應(yīng)該緩存不斷變化的鍵。
        • 我們不該緩存很少請求的鍵。
        • 我們希望緩存經(jīng)常請求并以合理速率更改的鍵。對于沒有穩(wěn)定變化速度的例子,比如不斷被INCR修改的全局計數(shù)器,就不應(yīng)該緩存。

         

        客戶端緩存實現(xiàn)原理

        Redis 實現(xiàn)的是一個服務(wù)端協(xié)助的客戶端緩存,叫做tracking??蛻舳司彺娴拿钍?

        CLIENT TRACKING ON|OFF [REDIRECT client-id] [PREFIX prefix] [BCAST] [OPTIN] [OPTOUT] [NOLOOP]

        Redis 6.0 實現(xiàn) Tracking 功能提供了兩種模式解決這個問題,分別是使用RESP3 協(xié)議版本的普通模式和廣播模式,以及使用 RESP2 協(xié)議版本的轉(zhuǎn)發(fā)模式。

        普通模式

        tracking開啟時, Redis會「記住」每個客戶端請求的 key,當 key的值發(fā)現(xiàn)變化時會發(fā)送失效信息給客戶端 (invalidation message)。
        失效信息可以通過 RESP3協(xié)議發(fā)送給請求的客戶端,或者轉(zhuǎn)發(fā)給一個不同的連接 (支持 RESP2 + Pub/Sub) 的客戶端。
        • Server 端將 Client 訪問的 key以及該 key 對應(yīng)的客戶端 ID 列表信息存儲在全局唯一的表(TrackingTable),當表滿了,回移除最老的記錄,同時觸發(fā)該記錄已過期的通知給客戶端。
        • 每個 Redis 客戶端又有一個唯一的數(shù)字 ID,TrackingTable 存儲著每一個 Client ID,當連接斷開后,清除該 ID 對應(yīng)的記錄。
        • TrackingTable 表中記錄的 Key 信息不考慮是哪個 database 的,雖然訪問的是 db1 的 key,db2 同名 key 修改時會客戶端收到過期提示,但這樣做會減少系統(tǒng)的復(fù)雜性,以及表的存儲數(shù)據(jù)量。
        ?這個 TrackingTable 原理是什么?
        Redis 服務(wù)端使用 TrackingTable存儲普通模式的客戶端數(shù)據(jù),它的數(shù)據(jù)類型是基數(shù)樹 ( radix tree)。
        基數(shù)樹是針對稀疏的長整型數(shù)據(jù)查找的多叉搜索樹,能快速且節(jié)省空間的完映射。
        Redis 用它存儲鍵的指針客戶端 ID 的映射關(guān)系。因為鍵對象的指針就是內(nèi)存地址,也就是長整型數(shù)據(jù)??蛻舳司彺娴南嚓P(guān)操作就是對該數(shù)據(jù)的增刪改查:
        圖片來源-程序員厲小冰
        注意
        服務(wù)端對于記錄的 key 只會報告一次 invalidate 消息,也就是說,服務(wù)端在給客戶端發(fā)送過一次 invalidate 消息后,如果 key 再被修改,此時,服務(wù)端就不會再次給客戶端發(fā)送 invalidate 消息。
        只有下次客戶端再次執(zhí)行只讀命令被 track,才會進行下一次消息通知 。
        客戶端默認不開啟 track 模式,我們需要在獲取執(zhí)行指令之前執(zhí)行開啟命令:

        CLIENT TRACKING ON|OFF
        +OK
        GET user:211
        $3

        廣播模式(BCAST)

        當廣播模式 (broadcasting) 開啟時,服務(wù)器不會記住給定客戶端訪問了哪些鍵,因此這種模式在服務(wù)器端根本不消耗任何內(nèi)存。
        在這個模式下,服務(wù)端會給客戶端廣播所有 key 的失效情況,如果 key 被頻繁修改,服務(wù)端會發(fā)送大量的失效廣播消息,這就會消耗大量的網(wǎng)絡(luò)帶寬資源。
        所以,在實際應(yīng)用中,我們設(shè)置讓客戶端注冊只跟蹤指定前綴的 key,當注冊跟蹤的 key 前綴匹配被修改,服務(wù)端就會把失效消息廣播給所有關(guān)注這個 key前綴的客戶端。

        client tracking on bcast prefix user

        這種監(jiān)測帶有前綴的 key 的廣播模式,和我們對 key 的命名規(guī)范非常匹配。我們在實際應(yīng)用時,會給同一業(yè)務(wù)下的 key 設(shè)置相同的業(yè)務(wù)名前綴,所以,我們就可以非常方便地使用廣播模式。
        圖片來源-程序員厲小冰
        廣播模式與普通模式類似,Redis 使用 PrefixTable 存儲廣播模式下的客戶端數(shù)據(jù),它存儲**前綴字符串指針和(需要通知的 key 和客戶端 ID)**的映射關(guān)系。

        轉(zhuǎn)發(fā)模式

        普通模式與廣播模式,需要客戶端使用 RESP 3 協(xié)議,他是 Redis 6.0 新啟用的協(xié)議。
        對于使用 RESP 2 協(xié)議的客戶端來說,實現(xiàn)客戶端緩存則需要另一種模式:重定向模式(redirect)。
        RESP 2 無法直接 PUSH 失效消息,所以 需要另一個支持 RESP 3 協(xié)議的客戶端 告訴 Server 將失效消息通過 Pus/Sub 通知給 RESP 2 客戶端。
        在重定向模式下,想要獲得失效消息通知的客戶端,就需要執(zhí)行訂閱命令 SUBSCRIBE,專門訂閱用于發(fā)送失效消息的頻道 _redis_:invalidate
        同時,再使用另外一個客戶端,執(zhí)行 CLIENT TRACKING 命令,設(shè)置服務(wù)端將失效消息轉(zhuǎn)發(fā)給使用 RESP 2 協(xié)議的客戶端。
        圖片來源-程序員厲小冰
        假設(shè)客戶端 B 想要獲取失效消息,但是客戶端 B 只支持 RESP 2 協(xié)議,客戶端 A 支持 RESP 3 協(xié)議。我們可以分別在客戶端 B 和 A 上執(zhí)行 SUBSCRIBE 和 CLIENT TRACKING,如下所示:

        //客戶端B執(zhí)行,客戶端 B 的 ID 號是 606
        SUBSCRIBE _redis_:invalidate

        //客戶端 A 執(zhí)行
        CLIENT TRACKING ON BCAST REDIRECT 606

        B 客戶端就可以通過 _redis_:invalidate 頻道獲取失效消息了。
        參考文檔
        https://redis.io/topics/client-side-caching https://colobu.com/2020/05/02/redis-client-side-caching/ https://time.geekbang.org/column/article/310838 https://juejin.cn/post/6844904153827786760

        有道無術(shù),術(shù)可成;有術(shù)無道,止于術(shù)

        歡迎大家關(guān)注Java之道公眾號


        好文章,我在看??

        瀏覽 76
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
          
          

            1. 国产黄色电影网 | 日本wwwwxxxx泡妞下课 | 激情肏屄网 | 欧美激情中出 | 一男一女啪啪 |