天天看點

redis哨兵+主從+redis叢集

一、redis哨兵+主從的問題

假設我們在一台主從機器上配置了200G記憶體,但是業務需求是需要500G的時候,主從結構+哨兵可以實作高可用故障切換+備援備份,但是并不能解決資料容量的問題,用哨兵,redis每個執行個體也是全量存儲,每個redis存儲的内容都是完整的資料,浪費記憶體且有木桶效應。

為了最大化利用記憶體,可以采用cluster群集,就是分布式存儲。即每台redis存儲不同的内容。

Redis 分布式方案一般有兩種:

1、用戶端分區方案,優點是分區邏輯可控,缺點是需要自己處理資料路由、高可用、故障轉移等問題,比如在redis2.8之前通常的做法是擷取某個key的hashcode,然後取餘分布到不同節點,不過這種做法無法很好的支援動态伸縮性需求,一旦節點的增或者删操作,都會導緻key無法在redis中命中。

2、代理方案,優點是簡化用戶端分布式邏輯和更新維護便利,缺點是加重架構部署複雜度和性能損耗,比如twemproxy、Codis

3、官方為我們提供了專有的叢集方案:Redis Cluster,它非常優雅地解決了 Redis 叢集方面的問題,部署友善簡單,是以了解應用好 Redis Cluster 将極大地解放我們使用分布式 Redis 的工作量。

二、Redis Cluster

1、簡介

Redis Cluster 是 Redis 的分布式解決方案,在3.0版本正式推出,有效地解決了 Redis 分布式方面的需求。當遇到單機記憶體、并發、流量等瓶頸時,可以采用 Cluster 架構方案達到負載均衡的目的。

架構圖:

在這個圖中,每一個藍色的圈都代表着一個redis的伺服器節點。它們任何兩個節點之間都是互相連通的。用戶端可以與任何一個節點相連接配接,然後就可以通路叢集中的任何一個節點,對其進行存取和其他操作。

Redis 叢集提供了以下兩個好處:

1、将資料自動切分到多個節點的能力。

2、當叢集中的一部分節點失效或者無法進行通訊時, 仍然可以繼續處理指令請求的能力,擁有自動故障轉移的能力。

2、redis cluster vs. replication + sentinal如何選擇

如果你的資料量很少,主要是承載高并發高性能的場景,比如你的緩存一般就幾個G,單機足夠了。

Replication:一個mater,多個slave,要幾個slave跟你的要求的讀吞吐量有關系,結合sentinal叢集,去保證redis主從架構的高可用性,就可以了。

redis cluster:主要是針對海量資料+高并發+高可用的場景,海量資料,如果你的資料量很大,那麼建議就用redis cluster。

資料分布是如何進行的

什麼是資料分布?資料分布有兩種方式,順序分區和哈希分區。

分布式資料庫首先要解決把整個資料集按照分區規則映射到多個節點的問題,即把資料集劃分到多個節點上,每個節點負責整體資料的一個子集。

順序分布就是把一整塊資料分散到很多機器中,如下圖所示。

順序分布一般都是平均配置設定的。

哈希分區

如下圖所示,1~100這整塊數字,通過 hash 的函數,取餘産生的數。這樣可以保證這串數字充分的打散,也保證了均勻的配置設定到各台機器上。

哈希分布和順序分布隻是場景上的适用。哈希分布不能順序通路,比如你想通路1~100,哈希分布隻能周遊全部資料,同時哈希分布因為做了 hash 後導緻與業務資料無關了。

資料傾斜與資料遷移跟節點伸縮

順序分布是會導緻資料傾斜的,主要是通路的傾斜。每次點選會重點通路某台機器,這就導緻最後資料都到這台機器上了,這就是順序分布最大的缺點。

但哈希分布其實是有個問題的,當我們要擴容機器的時候,專業上稱之為“節點伸縮”,這個時候,因為是雜湊演算法,會導緻資料遷移。

哈希分區方式

因為redis-cluster使用的就是哈希分區規則是以分析下幾種分區形式

1、節點取餘分區

使用特定的資料(包括redis的鍵或使用者ID),再根據節點數量N,使用公式:hash(key)%N計算出一個0~(N-1)值,用來決定資料映射到哪一個節點上。即哈希值對節點總數取餘。

缺點:當節點數量N變化時(擴容或者收縮),資料和節點之間的映射關系需要重新計算,這樣的話,按照新的規則映射,要麼之前存儲的資料找不到,要麼之前資料被重新映射到新的節點(導緻以前存儲的資料發生資料遷移)

實踐:常用于資料庫的分庫分表規則,一般采用預分區的方式,提前根據資料量規劃好分區數,比如劃分為512或1024張表,保證可支撐未來一段時間的資料量,再根據負載情況将表遷移到其他資料庫中。

2、一緻性哈希

一緻性哈希分區(Distributed Hash Table)實作思路是為系統中每個節點配置設定一個 token,範圍一般在0~232,這些 token 構成一個哈希環。資料讀寫執行節點查找操作時,先根據 key 計算 hash 值,然後順時針找到第一個大于等于該哈希值的 token 節點

上圖就是一個一緻性哈希的原了解析。

假設我們有 n1~n4 這四台機器,我們對每一台機器配置設定一個唯一 token,每次有資料(圖中黃色代表資料),一緻性雜湊演算法規定每次都順時針漂移資料,也就是圖中黃色的數 據都指向 n3。

這個時候我們需要增加一個節點 n5,在 n2 和 n3 之間,資料還是會發生漂移(會偏移到大于等于的節點),但是這個時候你是否注意到,其實隻有 n2~n3 這部分的資料被漂移,其他的資料都是不會變的,這種方式相比節點取餘最大的好處在于加入和删除節點隻影響哈希環中相鄰的節點,對其他節點無影響

缺點:每個節點的負載不相同,因為每個節點的hash是根據key計算出來的,換句話說就是假設key足夠多,被hash算法打散得非常均勻,但是節點過少,導緻每個節點處理的key個數不太一樣,甚至相差很大,這就會導緻某些節點壓力很大

實踐:加減節點會造成哈希環中部分資料無法命中,需要手動處理或者忽略這部分資料,是以一緻性哈希常用于緩存場景。

3.虛拟槽分區

虛拟槽分區巧妙地使用了哈希空間,使用分散度良好的哈希函數把所有資料映射到一個固定範圍的整數集合中,整數定義為槽(slot)。這個範圍一般遠遠大于節點數,比如 Redis Cluster 槽範圍是0~16383。槽是叢集内資料管理和遷移的基本機關。采用大範圍槽的主要目的是為了友善資料拆分和叢集擴充。每個節點會負責一定數量的槽,下圖所示。

目前叢集有5個節點,每個節點平均大約負責3276個槽。由于采用高品質的雜湊演算法,每個槽所映射的資料通常比較均勻,将資料平均劃分到5個節點進行資料分區。Redis Cluster 就是采用虛拟槽分區,下面就介紹 Redis 資料分區方法。

每當 key 通路過來,Redis Cluster 會計算哈希值是否在這個區間裡。它們彼此都知道對應的槽在哪台機器上,這樣就能做到平均配置設定了。