06.21 百度,京東,阿里等IT大廠如何做Redis集群方案

為什麼集群

Redis是一個內存數據庫,也就是說存儲數據的容量不能超過主機內存大小。普通主機服務器的內存一般幾十G,但是我們需要存儲大容量的數據(比如上百G的數據)怎麼辦? 由於內存大小的限制,使用一臺 Redis 實例顯然無法滿足需求,這時就需要使用 多臺 Redis (集群)作為緩存數據庫,才能在用戶請求時快速的進行響應。

百度,京東,阿里等IT大廠如何做Redis集群方案

Redis集群作為面試官經常問到的問題,可見其重要性。之前在逛博客的時候看到一位作者為“大cc”的一篇博文,詳細解析了大廠的 Redis 集群方案。現在轉載出來,給各位同學參考,拋磚引玉,希望可以加深同學對Redis的理解,更希望同學們可以順利的通過面試。

Redis集群的兩種方式

redis 集群方案主要有兩類,一是使用類 codis 的架構,按組劃分,實例之間互相獨立; 另一套是基於官方的 redis cluster 的方案;

類 codis 的架構

百度,京東,阿里等IT大廠如何做Redis集群方案

這套架構的特點:

分片算法:基於 slot hash 桶;

分片實例之間相互獨立,每組 一個 master 實例和多個 slave;

路由信息存放到第三方存儲組件,如 zookeeper 或 etcd

旁路組件探活

使用這套方案的公司:阿里雲: ApsaraCache, RedisLabs、京東、百度等

codis

slots 方案:劃分了 1024 個 slot, slots 信息在 proxy 層感知; redis 進程中維護本實例上的所有 key 的一個 slot map;

遷移過程中的讀寫衝突處理:最小遷移單位為 key; 訪問邏輯都是先訪問 src 節點,再根據結果判斷是否需要進一步訪問 target 節點;

訪問的 key 還未被遷移:讀寫請求訪問 src 節點,處理後訪問:

訪問的 key 正在遷移:讀請求訪問 src 節點後直接返回; 寫請求無法處理,返回 retry

訪問的 key 已被遷移 (或不存在):讀寫請求訪問 src 節點,收到 moved 回覆,繼續訪問 target 節點處理

阿里雲

AparaCache 的單機版已開源 (開源版本中不包含 slot 等實現),集群方案細節未知; ApsaraCache

主要組件:proxy,基於 twemproxy 改造,實現了動態路由表; redis 內核: 基於 2.x 實現的 slots 方案; metaserver:基於 redis 實現,包含的功能:拓撲信息的存儲 & 探活; 最多支持 1000 個節點;

slot 方案:redis 內核中對 db 劃分,做了 16384 個 db; 每個請求到來,首先做 db 選擇;

數據遷移實現:數據遷移的時候,最小遷移單位是 slot,遷移中整個 slot 處於阻塞狀態,只支持讀請求,不支持寫請求; 對比 官方 redis cluster/ codis 的按 key 粒度進行遷移的方案:按 key 遷移對用戶請求更為友好,但遷移速度較慢; 這個按 slot 進行遷移的方案速度更快;

京東

主要組件:proxy: 自主實現,基於 golang 開發; redis 內核:基於 redis 2.8configServer(cfs) 組件:配置信息存放; scala 組件:用於觸發部署、新建、擴容等請求; mysql:最終所有的元信息及配置的存儲; sentinal(golang 實現):哨兵,用於監控 proxy 和 redis 實例,redis 實例失敗後觸發切換;

slot 方案實現:在內存中維護了 slots 的 map 映射表;

數據遷移:基於 slots 粒度進行遷移; scala 組件向 dst 實例發送命令告知會接受某個 slot;dst 向 src 發送命令請求遷移,src 開啟一個線程來做數據的 dump,將這個 slot 的數據整塊 dump 發送到 dst(未加鎖,只讀操作) 寫請求會開闢一塊緩衝區,所有的寫請求除了寫原有數據區域,同時雙寫到緩衝區中。當一個 slot 遷移完成後,把這個緩衝區的數據都傳到 dst,當緩衝區為空時,更改本分片 slot 規則,不再擁有該 slot,後續再請求這個 slot 的 key 返回 moved; 上層 proxy 會保存兩份路由表,當該 slot 請求目標實例得到 move 結果後,更新拓撲;

跨機房:跨機房使用主從部署結構; 沒有多活,異地機房作為 slave;

基於官方redis cluster的方案

百度,京東,阿里等IT大廠如何做Redis集群方案

和上一套方案比,所有功能都集成在 redis cluster 中,路由分片、拓撲信息的存儲、探活都在 redis cluster 中實現; 各實例間通過 gossip 通信; 這樣的好處是簡單,依賴的組件少,應對 400 個節點以內的場景沒有問題 (按單實例 8w read qps 來計算,能夠支持 200 * 8 = 1600w 的讀多寫少的場景); 但當需要支持更大的規模時,由於使用 gossip 協議導致協議之間的通信消耗太大,redis cluster 不再合適;

使用這套方案的有:AWS, 百度貼吧

官方 redis cluster

數據遷移過程:基於 key 粒度的數據遷移; 遷移過程的讀寫衝突處理:從 A 遷移到 B;

訪問的 key 所屬 slot 不在節點 A 上時,返回 MOVED 轉向,client 再次請求 B;

訪問的 key 所屬 slot 在節點 A 上,但 key 不在 A 上, 返回 ASK 轉向,client 再次請求 B;

訪問的 key 所屬 slot 在 A 上,且 key 在 A 上,直接處理;(同步遷移場景:該 key 正在遷移,則阻塞)

AWS ElasticCache

ElasticCache 支持主從和集群版、支持讀寫分離; 集群版用的是開源的 Redis Cluster,未做深度定製;

基於 redis cluster + twemproxy 實現; 後被 BDRP 吞併; twemproxy 實現了 smart client 功能; 使用 redis cluster 後還加一層 proxy 的好處:

對 client 友好,不需要 client 都升級為 smart client;(否則,所有語言 client 都需要支持一遍)

加一層 proxy 可以做更多平臺策略; 比如在 proxy 可做 大 key、熱 key 的監控、慢查詢的請求監控、以及接入控制、請求過濾等;

即將發佈的 redis 5.0 中有個 feature,作者計劃給 redis cluster 加一個 proxy。

ksarch-saas 對 twemproxy 的改造已開源:https://github.com/ksarch-saas/r3proxy

為了幫助同學們更好的瞭解Redis,小編為同學們準備了Redis的學習教程。

領取方式

1.關注“黑馬程序員” 評論轉發後臺回覆:rd


分享到:


相關文章: