【考點】Redis sharding切片常見方式

轉載:http://www.open-open.com/lib/view/open1427337394074.html

Redis集羣的目的是實現數據的橫向伸縮,把一塊數據分片保存到多個機器,可以橫向擴展數據庫大小,擴展帶寬,計算能力等。 

實現數據分片(集羣)方式大致有三種: 

(1)客戶端實現數據分片 

即客戶端自己計算數據的key應該在哪個機器上存儲和查找,此方法的好處是降低了服務器集羣的複雜度,客戶端實現數據分片時,服務器是獨立的,服務器之前沒有任何關聯。多數redis客戶端庫實現了此功能,也叫sharding,這種方式的缺點是客戶端需要實時知道當前集羣節點的聯繫信息,同時,當添加一個新的節點時,客戶端要支持動態sharding.,多數客戶端實現不支持此功能,需要重啓redis。另一個弊端是redis的HA需要額外考慮。

 

(2)服務器實現數據分片 

其理論是,客戶端隨意與集羣中的任何節點通信,服務器端負責計算某個key在哪個機器上,當客戶端訪問某臺機器時,服務器計算對應的key應該存儲在哪個機器,然後把結果返回給客戶端,客戶端再去對應的節點操作key,是一個重定向的過程,此方式是redis3.0正在實現,目前處於beta版本, Redis 3.0的集羣同時支持HA功能,某個master節點掛了後,其slave會自動接管。

服務器端實現集羣需要客戶端語言實現服務器集羣的協議,目前java,php,ruby語言多數有redis-cluster客戶端實現版本。 

Redis Cluster原理http://www.cnblogs.com/foxmailed/p/3630875.html

 

Redis Cluster 是Redis的集羣實現,內置數據自動分片機制,集羣內部將所有的key映射到16384個Slot中,集羣中的每個Redis Instance負責其中的一部分的Slot的讀寫。集羣客戶端連接集羣中任一Redis Instance即可發送命令,當Redis Instance收到自己不負責的Slot的請求時,會將負責請求Key所在Slot的Redis Instance地址返回給客戶端,客戶端收到後自動將原請求重新發往這個地址,對外部透明。一個Key到底屬於哪個Slot由crc16(key) % 16384 決定。

 

關於負載均衡,集羣的Redis Instance之間可以遷移數據,以Slot爲單位,但不是自動的,需要外部命令觸發。 

 

關於集羣成員管理,集羣的節點(Redis Instance)和節點之間兩兩定期交換集羣內節點信息並且更新,從發送節點的角度看,這些信息包括:集羣內有哪些節點,IP和PORT是什麼,節點名字是什麼,節點的狀態(比如OK,PFAIL,FAIL,後面詳述)是什麼,包括節點角色(master 或者 slave)等。 

 

關於可用性,集羣由N組主從Redis Instance組成。主可以沒有從,但是沒有從 意味着主宕機後主負責的Slot讀寫服務不可用。 

一個主可以有多個從,主宕機時,某個從會被提升爲主,具體哪個從被提升爲主,協議類似於Raft,參見這裏。如何檢測主宕機?Redis Cluster採用quorum+心跳的機制。從節點的角度看,節點會定期給其他所有的節點發送Ping,cluster-node-timeout(可配置,秒級)時間內沒有收到對方的回覆,則單方面認爲對端節點宕機,將該節點標爲PFAIL狀態。通過節點之間交換信息收集到quorum個節點都認爲這個節點爲PFAIL,則將該節點標記爲FAIL,並且將其發送給其他所有節點,其他所有節點收到後立即認爲該節點宕機。從這裏可以看出,主宕機後,至少cluster-node-timeout時間內該主所負責的Slot的讀寫服務不可用。 

Redis Cluster Slots是什麼?http://www.zhizhihu.com/html/y2014/4590.html

舉個栗子,Redis Cluster下,三個master,三個slave,即每個master有一個slave,那麼slots是如何劃分的呢?

>>> Performing hash slots allocation on 6 nodes... 

Using 3 masters: 

127.0.0.1:7000 

127.0.0.1:7001 

127.0.0.1:7002 

Adding replica 127.0.0.1:7003 to 127.0.0.1:7000 

Adding replica 127.0.0.1:7004 to 127.0.0.1:7001 

Adding replica 127.0.0.1:7005 to 127.0.0.1:7002 

M: 09a89f7e08b7c00707e3507bea8016e9b4719d78 127.0.0.1:7000 

slots:0-5460 (5461 slots) master 

M: ddb8a2bc9b93b56a84d8e4c964af24e317767028 127.0.0.1:7001 

slots:5461-10922 (5462 slots) master 

M: 77335ea34c3d9fcff3a9bf55c1a73490a7153c29 127.0.0.1:7002 

slots:10923-16383 (5461 slots) master 

S: 67ebdad9de818b13267c1779a941553e88798525 127.0.0.1:7003 

replicates 09a89f7e08b7c00707e3507bea8016e9b4719d78 

S: a3f6c70725c25f92c35816966aee9ee7248e4a33 127.0.0.1:7004 

replicates ddb8a2bc9b93b56a84d8e4c964af24e317767028 

S: 2a58a4ca50e0ad733e83be3eb4cbbc8d9103fbbe 127.0.0.1:7005 


注意這裏, 

M: 09a89f7e08b7c00707e3507bea8016e9b4719d78 127.0.0.1:7000 

slots:0-5460 (5461 slots) master

M: ddb8a2bc9b93b56a84d8e4c964af24e317767028 127.0.0.1:7001 

slots:5461-10922 (5462 slots) master

M: 77335ea34c3d9fcff3a9bf55c1a73490a7153c29 127.0.0.1:7002 

slots:10923-16383 (5461 slots) master

好了,可以看到slots就是這樣分配的。 

如果一個key經過crc16後,如果他的slot爲16381,那麼他就在id爲77335ea34c3d9fcff3a9bf55c1a73490a7153c29 的master上。

 

(3)通過代理服務器實現數據分片 

此方式是藉助一個代理服務器實現數據分片,客戶端直接與proxy聯繫,proxy計算集羣節點信息,並把請求發送到對應的集羣節點。降低了客戶端的複雜度,需要proxy收集集羣節點信息。Twemproxy是twitter開源的,實現這一功能的proxy。這個實現方式在客戶端和服務器之間加了一個proxy,但這是在redis 3.0穩定版本出來之前官方推薦的方式。結合redis-sentinel的HA方案,是個不錯的組合。

 

參考:http://www.zhizhihu.com/html/y2014/4590.html

http://www.cnblogs.com/foxmailed/p/3630875.html

http://itindex.net/detail/51037-redis-%E9%9B%86%E7%BE%A4

 

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