Redis分区/分片详解
分區/分片詳解
分區是分割數據到多個Redis實例的處理過程,因此每個實例只保存key的一個子集。
如果只使用一個redis實例時,其中保存了服務器中全部的緩存數據,這樣會有很大風險,如果單臺redis服務宕機了將會影響到整個服務。解決的方法就是我們可以采用分片/分區的技術,將原來一臺服務器維護的整個緩存,現在換為由多臺服務器共同維護內存空間。
為什么要分區?
-
在大數據高并發場景下,單個redis實例往往不足以應付。首先體現在內存上,單個redis的內存不宜過大,內存太大會導致rdb文件過大,進一步導致主從同步時全量同步時間過長,在實例重啟恢復時也會消耗很長的數據加載時間,特別是在云環境下,單個實例內存大小往往都是受限的。其次體現在CPU的利用率上,單個redis實例只能利用單個核心,單個核心要完成海量數據的存取和管理工作,壓力會非常大。
-
正是在這樣的大數據高并發的需求之下,redis集群方案應運而生。它可以將眾多小內存的redis實例整合起來,將分布在多臺機器上的眾多CPU核心的計算能力聚集在一起,完成海量數據存儲和高并發讀寫操作。
Redis的分區方案
-
客戶端分區
在客戶端就已經決定數據會被存儲到哪個redis節點或者從哪個redis節點讀取。大多數客戶端已經實現了客戶端分區。
系統架構
實現方案
客戶端分區方案 的代表為 Redis Sharding,Redis Sharding 是 Redis Cluster 出來之前,業界普遍使用的 Redis 多實例集群 方法。Java 的 Redis 客戶端驅動庫 Jedis,支持 Redis Sharding 功能,即 ShardedJedis 以及 結合緩存池 的 ShardedJedisPool。
優點:
客戶端分片的好處就是所有的邏輯都是可控的,不依賴于第三方分布式中間件。開發人員清除怎么實現分片、路由的規則,不用擔心踩坑。
缺點:
-
這是一種靜態的分片方案,需要增加或者減少redis實例的數量,需要手動調整分片的程序
-
可運維性差。集群的數據出了任何問題都需要運維人員和開發人員一起合作,減緩了解決問題的速度,增加了跨部門溝通的成本
-
在不同的客戶端程序中,維護相同的分片邏輯成本巨大。比如,系統中有兩套業務系統共用一套redis集群,一套業務系統用java實現,另一套業務系統用php實現。為了保持分片邏輯的一致性,在java客戶端中實現的分片邏輯也需要在php客戶端實現一次。相同的邏輯在不同的系統中分別實現,這種設備本來就非常糟糕,而且需要耗費巨大的開發成本保證兩套業務系統分片邏輯的一致性
-
-
范圍分區
映射一定范圍的對象到特定的Redis實例。比如,ID從0到10000的用戶會保存到實例R0,ID從10001到 20000的用戶會保存到R1,以此類推
hash一致算法實現分區
hash一致算法實現分區,對key值進行hash一致性計算后得到結果,最終將數據保存到某一臺redis實例中 -
代理分區
實現方案:
Twemproxy 也叫 nutcraker,是 twitter 開源的一個 redis 和 memcache 的 中間代理服務器 程序。Twemproxy 作為 代理,可接受來自多個程序的訪問,按照 路由規則,轉發給后臺的各個 Redis 服務器,再原路返回。Twemproxy 存在 單點故障 問題,需要結合 Lvs 和 Keepalived 做 高可用方案。
基本原理:
-
redis客戶端把請求發送到Twemproxy
-
Twemproxy根據路由規則發送到正確的redis實例
-
最后Twemproxy把結果匯集返回給客戶端
客戶端將請求發送給代理,然后代理決定去哪個節點寫數據或者讀數據。根據分區規則決定請求哪些Redis實例,然后根據Redis的響應結果返回給客戶端。redis和memcached的一種代理實現就是Twemproxy
-
-
查詢路由
是客戶端隨機地請求任意一個redis實例,然后由Redis將請求轉發給正確的Redis節點。Redis Cluster實現了一種混合形式的查詢路由,但并不是直接將請求從一個redis節點轉發到另一個redis節點,而是在客戶端的幫助下直接redirected到正確的redis節點
Redis分區不足:
分區是多臺redis共同作用,如果一臺宕機,其實是整個分片故障。雖然緩解了內存壓力,但是沒有實現高可用。
涉及多個key的操作就會不支持。比如當兩個set映射到不同的redis實例時,因為他們可能被存儲到不同的實例上,所有就無法完成交集操作。
涉及到多個key的redis事務就不被支持。
分區對于動態擴容,其實是非常復雜的。因為需要修改客戶端代碼。
當兩個set映射到不同的redis實例上時,因為他們可能被存儲到不同的Redis實例,你就不能對這兩個set執行交集操作
Redis一種推薦做法:
例子:
我們Redis容量變動在實際應用中是非常常見的,比如今天我需要10臺Redis機器,明天可能就需要50臺機器了。
-
我們可以開啟多個Redis實例,盡管是一臺物理機器,我們在剛開始的時候也可以開啟多個實例。
-
我們可以從中選擇一些實例,比如32或64個實例來作為我們的工作集群。
-
當一臺物理機器存儲不夠的時候,我們可以將一般的實例移動到我們的第二臺物理機上,依次類對,我們可以保證集群中Redis的實例數不變,又可以達到擴充機器的目的。
怎么移動Redis實例呢?當需要將Redis實例移動到獨立的機器上的時候,我們可以通過下面步驟實現:
-
在新的物理機上啟動一個新的Redis實例。
-
將新的物理機作為要移動的那臺的slave機器。
-
停止客戶端。
-
更新將要被移動的那臺Redis實例的IP地址。
-
對于slave機器發送SLAVEOF ON ONE命令。
-
使用新的IP啟動Redis客戶端。
-
關閉不再使用的那個Redis實例。
Redis集群
數據分區是集群的實現基礎。集群是數據分區的具體實現。
-
由于redis出眾的性能,其在眾多的移動互聯網企業中得到廣泛的應用。
-
redis在3.0版本前只支持單實例模式,雖然現在的服務器內存可以到100GB、200GB的規模,但是單實例模式限制了redis沒法滿足業務的需求(比如新浪微博就曾經用redis存儲了超過1TB的數據)。
-
redis的開發者Antrres早在博客上就提出在redis3.0版本中加入集群的功能,但3.0版本等到2015年才發布正式版。
-
各大企業在3.0版本還沒有發布前為了解決redis的存儲瓶頸,紛紛推出了各自的redis集群方案。這些方案的核心思想就是把數據分片(sharding)存儲在多個redis實例中,每一片就是一個redis實例。
實現案例:
Redis cluster是redis作者自己提供的集群化方案
總結
以上是生活随笔為你收集整理的Redis分区/分片详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2d有限元计算机仿真,平面铣削加工过程计
- 下一篇: mysql导入dat文件_后缀名为dat