Redis常見的叢集方案(轉)

來源:互聯網
上載者:User

前一段時間面試阿里巴巴,面試官問我除了Redis 3.0開發官方提供的Redis Cluster模式(http://www.redis.cn/topics/cluster-tutorial.html)外,你還知道哪些Redis叢集方案。

面試後便查詢了相關資料,記錄了一下Redis常見的各種叢集方案。 1.Redis官方叢集方案 Redis Cluster

Redis Cluster是一種伺服器Sharding技術,3.0版本開始正式提供。
Redis Cluster中,Sharding採用slot(槽)的概念,一共分成16384個槽。對於每個進入Redis的索引值對,根據key進行散列,分配到這16384個slot中的某一個中。使用的hash演算法也比較簡單,就是CRC16後16384模數。Redis叢集中的每個node(節點)負責分攤這16384個slot中的一部分,也就是說,每個slot都對應一個node負責處理。而對於完成多個Redis共用這16384個slot的命令如下:

./redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 \127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

其中,127.0.0.1的主機從7000~7005運行了6個Redis服務。 選項–replicas 1 表示我們希望為叢集中的每個主節點建立一個從節點。則最終結果為3個Redis作為主機平分了16384個slot,而剩下的3個Redis作為備機。
當動態添加或減少node節點時,需要將16384個槽做個再分配,槽中的索引值也要遷移。當然,這一過程,在目前實現中,還處於半自動狀態,需要人工介入。而對於在上述叢集下再次添加一個主節點並且劃分slot槽的命令如下:
啟動一個連接埠為7006的Redis執行個體

./redis-trib.rb add-node 127.0.0.1:7006 127.0.0.1:7000

如果是為叢集添加一個從節點,需要加參數–slave。

./redis-trib.rb add-node --slave 127.0.0.1:7006 127.0.0.1:7000

此處並沒有指定添加的這個從節點的主節點,這種情況下系統會在其他的複製集中的主節點中隨機選取一個作為這個從節點的主節點。

只需要指定叢集中其中一個節點的地址, redis-trib 就會自動找到叢集中的其他節點。

對於新添加進來的Redis實現,是沒有slot的,此時需要運行來重新劃分。

./redis-trib.rb reshard 127.0.0.1:7000

Redis叢集,要保證16384個槽對應的node都正常工作,如果某個node發生故障,那它負責的slots也就失效,整個叢集將不能工作。為了增加叢集的可訪問性,官方推薦的方案是將node配置成主從結構,即一個master主節點,掛n個slave從節點。這時,如果主節點失效,Redis Cluster會根據選舉演算法從slave節點中選擇一個上升為主節點,整個叢集繼續對外提供服務。Redis Cluster的新節點識別能力、故障判斷及容錯移轉能力是通過叢集中的每個node都在和其它nodes進行通訊,這被稱為叢集匯流排(cluster bus)。它們使用特殊的連接埠號碼,即對外服務連接埠號碼加10000。例如如果某個node的連接埠號碼是6379,那麼它與其它nodes通訊的連接埠號碼是16379。nodes之間的通訊採用特殊的二進位協議。對用戶端來說,整個cluster被看做是一個整體,用戶端可以串連任意一個node進行操作,就像操作單一Redis執行個體一樣,當用戶端操作的key沒有分配到該node上時,Redis會返迴轉向指令,指向正確的node,這有點兒像瀏覽器頁面的302 redirect跳轉。目前該模式能證明在大規模生產環境下成功的案例還不是很多。 2.Redis Sharding叢集

Redis 3正式推出了官方叢集技術,解決了多Redis執行個體協同服務問題。Redis Cluster可以說是服務端Sharding分區技術的體現,即將索引值按照一定演算法合理分配到各個執行個體分區上,同時各個執行個體節點協調溝通,共同對外承擔一致服務。
多Redis執行個體服務,比單Redis執行個體要複雜的多,這涉及到定位、協同、容錯、擴容等技術難題。這裡介紹一種輕量級的用戶端Redis Sharding技術。Redis Sharding可以說是Redis Cluster出來之前,業界普遍使用的多Redis執行個體叢集方法。其主要思想是採用雜湊演算法將Redis資料的key進行散列,通過hash函數,特定的key會映射到特定的Redis節點上。這樣,用戶端就知道該向哪個Redis節點操作資料。

慶幸的是,java redis用戶端jedis,已支援Redis Sharding功能,即ShardedJedis以及結合緩衝池的ShardedJedisPool。Jedis的Redis Sharding實現具有如下特點: 採用一致性雜湊演算法(consistent hashing),將key和節點name同時hashing,然後進行映射匹配。採用一致性雜湊的主要原因是當增加或減少節點時,不會產生由於重新匹配造成的rehashing。一致性雜湊隻影響相鄰節點key分配,影響量小。 為了避免一致性雜湊隻影響相鄰節點造成節點分配壓力,ShardedJedis會對每個Redis節點根據名字(沒有,Jedis會賦予預設名字)會虛擬化出160個虛擬節點進行散列。根據權重weight,也可虛擬化出160倍數的虛擬節點。用虛擬節點做映射匹配,可以在增加或減少Redis節點時,key在各Redis節點移動再分配更均勻,而不是只有相鄰節點受影響。 ShardedJedis支援keyTagPattern模式,即抽取key的一部分keyTag做sharding,這樣通過合理命名key,可以將一組相關聯的key放入同一個Redis節點,這在避免跨節點訪問相關資料時很重要。

Redis Sharding採用用戶端Sharding方式,服務端Redis還是一個個相對獨立的Redis執行個體節點,沒有做任何變動。同時,我們也不需要增加額外的中間處理組件,這是一種非常輕量、靈活的Redis多執行個體叢集方法。

當然,Redis Sharding這種輕量靈活方式必然在叢集其它能力方面做出妥協。比如擴容,當想要增加Redis節點時,儘管採用一致性雜湊,畢竟還是會有key匹配不到而丟失,這時需要索引值遷移。作為輕量級用戶端sharding,處理Redis索引值遷移是不現實的,這就要求應用程式層面允許Redis中資料丟失或從後端資料庫重新載入資料。但有些時候,擊穿緩衝層,直接存取資料庫層,會對系統訪問造成很大壓力。有沒有其它手段改善這種情況。Redis作者給出了一個比較討巧的辦法–presharding,即預先根據系統規模盡量部署好多個Redis執行個體,這些執行個體佔用系統資源很小,一台物理機可部署多個,讓他們都參與sharding,當需要擴容時,選中一個執行個體作為主節點,新加入的Redis節點作為從節點進行資料複製。資料同步後,修改sharding配置,讓指向原執行個體的Shard指向新機器上擴容後的Redis節點,同時調整新Redis節點為主節點,原執行個體可不再使用。presharding是預先分配好足夠的分區,擴容時只是將屬於某一分區的原Redis執行個體替換成新的容量更大的Redis執行個體。參與sharding的分區沒有改變,所以也就不存在key值從一個區轉移到另一個分區區的現象,只是將屬於同分區區的索引值從原Redis執行個體同步到新Redis執行個體。

並不是只有增刪Redis節點引起索引值丟失問題,更大的障礙來自Redis節點突然宕機。在《Redis持久化》一文中已提到,為不影響Redis效能,盡量不開啟AOF和RDB檔案儲存功能,可架構Redis主備模式,主Redis宕機,資料不會丟失,備Redis留有備份。這樣,我們的架構模式變成一個Redis節點切片包含一個主Redis和一個備Redis。在主Redis宕機時,備Redis接管過來,上升為主Redis,繼續提供服務。主備共同組成一個Redis節點,通過自動容錯移轉,保證了節點的高可用性。

高訪問量下,即使採用Sharding分區,一個單獨節點還是承擔了很大的訪問壓力,這時我們還需要進一步分解。通常情況下,應用訪問Redis讀操作量和寫操作量差異很大,讀常常是寫的數倍,這時我們可以將讀寫分離,而且讀提供更多的執行個體數。

可以利用主從模式實現讀寫分離,主負責寫,從負責唯讀,同時一主掛多個從。在Sentinel監控下(Redis Sentinel提供了主備模式下Redis監控、容錯移轉功能達到系統的高可用性),還可以保障節點故障的自動監測。 利用代理中介軟體實現大規模Redis叢集

上面分別介紹了多Redis伺服器叢集的兩種方式,它們是基於用戶端sharding的Redis Sharding和基於服務端sharding的Redis Cluster。
用戶端sharding技術其優勢在於服務端的Redis執行個體彼此獨立,相互無關聯,每個Redis執行個體像單伺服器一樣運行,非常容易線性擴充,系統的靈活性很強。其不足之處在於: 由於sharding處理放到用戶端,規模進步擴大時給營運帶來挑戰。 服務端Redis執行個體群拓撲結構有變化時,每個用戶端都需要更新調整。 串連不能共用,當應用規模增大時,資源浪費制約最佳化。

服務端sharding的Redis Cluster其優勢在於服務端Redis叢集拓撲結構變化時,用戶端不需要感知,用戶端像使用單Redis伺服器一樣使用Redis叢集,營運管理也比較方便。

不過Redis Cluster正式版推出時間不長,系統穩定性、效能等都需要時間檢驗,尤其在大規模使用場合。

能不能結合二者優勢。即能使服務端各執行個體彼此獨立,支援線性可伸縮,同時sharding又能集中處理,方便統一管理。本篇介紹的Redis代理中介軟體twemproxy就是這樣一種利用中介軟體做sharding的技術。

twemproxy處於用戶端和伺服器的中間,將用戶端發來的請求,進行一定的處理後(如sharding),再轉寄給後端真正的Redis伺服器。也就是說,用戶端不直接存取Redis伺服器,而是通過twitter 開源的 twemproxy代理中介軟體間接訪問(http://blog.nosqlfan.com/html/4147.html)。

twemproxy中介軟體的內部處理是無狀態的,它本身可以很輕鬆地叢集,這樣可避免單點壓力或故障。

twemproxy又叫nutcracker,起源於twitter系統中redis/memcached叢集開發實踐,運行效果良好,後代碼奉獻給開源社區。其輕量高效,採用C語言開發,工程網址是:GitHub - twitter/twemproxy: A fast, light-weight proxy for memcached and redis

twemproxy後端不僅支援redis,同時也支援memcached,這是twitter系統具體環境造成的。

由於使用了中介軟體,twemproxy可以通過共用與後端系統的串連,降低用戶端直接連接後端伺服器的串連數量。同時,它也提供sharding功能,支援後端伺服器叢集水平擴充。統一營運管理也帶來了方便。

當然,也是由於使用了中介軟體代理,相比用戶端直連伺服器方式,效能上會有所損耗,實測結果大約降低了20%左右。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.