1. 程式人生 > 資料庫 >Redis叢集的相關詳解

Redis叢集的相關詳解

注意!要求使用的都是redis3.0以上的版本,因為3.0以上增加了redis叢集的功能。

1.redis介紹

1.1什麼是redis

Redis是用C語言開發的一個開源的高效能鍵值對(key-value)的非關係型資料庫。通過多種鍵值資料型別來適應不同場景下的儲存需求,目前支援的鍵值資料型別有:
字串,雜湊,列表,集合,有序集合

2.2應用場景

快取(資料查詢、短連線、新聞內容、商品內容等等)。(最多使用)
分散式叢集架構中的session分離。
聊天室的線上好友列表。
任務佇列。(秒殺、搶購、12306等等)
應用排行榜。
網站訪問統計。
資料過期處理(可以精確到毫秒)

2.Redis叢集的介紹

2.1Redis叢集的架構

Redis 叢集中內建了 16384 個雜湊槽,redis-cluster把所有的物理節點對映到[0-16383]slot上,cluster 負責維護。當需要在 Redis 叢集中放置一個 key-value 時,redis 先對 key 使用 crc16 演算法算出一個結果,然後把結果對 16384 求餘數,這樣每個 key 都會對應一個編號在 0-16383 之間的雜湊槽,redis 會根據節點數量大致均等的將雜湊槽對映到不同的節點

2.2 Redis叢集的特點

當Redis叢集啟動後,就自動在多個節點間做好分片,同時提供了分片之間的可用性:即當一部分redis節點故障或者網路中斷後,叢集還有從節點可以替代主節點繼續工作,但如果大面積的節點故障,那叢集就不可用了。

Redis叢集提供了:
自動將16384個數據槽點切分到多個Redis節點中
當一部分節點故障或不可達,叢集依然能繼續工作

2.3 Redis叢集的TCP埠

叢集的每個節點都需要建立兩個TCP連線,監聽這兩個埠:
客戶端埠(一般是6379):需要對所有客戶端和叢集節點開放,用於接收客戶端指令,且叢集節點需要通過該埠向客戶端轉移資料。
叢集匯流排埠(一般是6379+10000):只需要對叢集中的所有節點開放,用於節點之間通過二進位制協議通訊。各節點通過叢集匯流排檢測故障節點,更新配置等,而客戶端是不能使用該埠的。

2.4 Redis叢集資料的分片

Redis叢集使用的是雜湊槽,有16384個雜湊槽,決定一個key分配到哪個槽的演算法:計算該key的CRC16,結果再模16384.

叢集中的每個節點負責一部分雜湊槽,比如叢集中有3個節點,則:

  1. 節點A儲存的雜湊槽範圍是:0 – 5500
  2. 節點B儲存的雜湊槽範圍是:5501 – 11000
  3. 節點C儲存的雜湊槽範圍是:11001 – 16384

這樣的分佈方式方便節點的新增和刪除。比如,需要新增一個節點D,只需要把A、B、C中的部分雜湊槽資料移到D節點。同樣,如果希望在叢集中刪除A節點,只需要把A節點的雜湊槽的資料移到B和C節點,當A節點的資料全部被移走後,A節點就可以完全從叢集中刪除。

因為把雜湊槽從一個節點移到另一個節點是不需要停機的,所以,增加或刪除節點,或更改節點上的雜湊槽,也是不需要停機的。

如果多個key都屬於一個雜湊槽,叢集支援通過一個命令(或事務,或lua指令碼)同時操作這些key。通過“雜湊標籤”的概念,使用者可以讓多個key分配到同一個雜湊槽。如果key含有大括號”{}”,則只有大括號中的字串會參與雜湊,比如”this{foo}”和”another{foo}”這2個key會分配到同一個雜湊槽,所以可以在一個命令中同時操作他們。

2.5 Redis叢集的主從模式

每個雜湊槽都有一個主節點和多個從節點。
舉例:如果有六個節點,則分A,B,C三個為主節點,A1,B1,C1三個為對應的從節點,當A發生故障後,叢集會提升A1為主節點,A1會繼承A節點的資料,其實A1就相當於A的一個副本,讓叢集繼續工作。

2.5.1 redis-cluster投票:容錯

(1)投票過程是叢集中所有主節點參與,如果半數以上主節點與故障主節點通訊超過(cluster-node-timeout),認為當前該主節點掛掉.
(2):什麼時候整個叢集不可用(cluster_state:fail)?
a:如果叢集任意主節點掛掉,且沒有從節點.叢集進入fail狀態,也可以理解成叢集的slot對映[0-16383]不完成時進入fail狀態.
b:如果叢集超過半數以上主節點掛掉,無論是否有從節點,叢集都進入fail狀態.
ps:當叢集不可用時,所有對叢集的操作做都不可用,收到((error) CLUSTERDOWN The cluster is down)錯誤。

2.6 Redis叢集的一致性保證

Redis叢集不能保證強一致性。一些已經向客戶端確認寫成功的操作,會在某些不確定的情況下丟失。

產生寫操作丟失的第一個原因,是因為主從節點之間使用了非同步的方式來同步資料。

一個寫操作是這樣一個流程:

  1. 1)客戶端向主節點B發起寫的操作
  2. 2)主節點B迴應客戶端寫操作成功
  3. 3)主節點B向它的從節點B1,B2,B3同步該寫操作

從上面的流程可以看出來,主節點B並沒有等從節點B1,B3寫完之後再回復客戶端這次操作的結果。所以,如果主節點B在通知客戶端寫操作成功之後,但同步給從節點之前,主節點B故障了,其中一個沒有收到該寫操作的從節點會晉升成主節點,該寫操作就這樣永遠丟失了。

節點超時(node timeout):對叢集來說非常重要,當達到了這個節點超時的時間之後,主節點被認為已經宕機,可以用它的一個從節點來代替。同樣,在節點超時時,如果主節點依然不能聯絡到其他主節點,它將進入錯誤狀態,不再接受寫操作。

2.7 Redis叢集的引數配置

在redis.conf中的一些引數說明:

cluster-enabled <yes/no>:
如果配置”yes”則開啟叢集功能,此redis例項作為叢集的一個節點,否則,它是一個普通的單一的redis例項。

cluster-config-file :
注意:雖然此配置的名字叫“叢集配置檔案”,但是此配置檔案不能人工編輯,它是叢集節點自動維護的檔案,主要用於記錄叢集中有哪些節點、他們的狀態以及一些持久化引數等,方便在重啟時恢復這些狀態。通常是在收到請求之後這個檔案就會被更新。

cluster-node-timeout :
這是叢集中的節點能夠失聯的最大時間,超過這個時間,該節點就會被認為故障。如果主節點超過這個時間還是不可達,則用它的從節點將啟動故障遷移,升級成主節點。注意,任何一個節點在這個時間之內如果還是沒有連上大部分的主節點,則此節點將停止接收任何請求。

cluster-slave-validity-factor :
如果設定成0,則無論從節點與主節點失聯多久,從節點都會嘗試升級成主節點。如果設定成正數,則cluster-node-timeout乘以cluster-slave-validity-factor得到的時間,是從節點與主節點失聯後,此從節點資料有效的最長時間,超過這個時間,從節點不會啟動故障遷移。假設cluster-node-timeout=5,cluster-slave-validity-factor=10,則如果從節點跟主節點失聯超過50秒,此從節點不能成為主節點。注意,如果此引數配置為非0,將可能出現由於某主節點失聯卻沒有從節點能頂上的情況,從而導致叢集不能正常工作,在這種情況下,只有等到原來的主節點重新迴歸到叢集,叢集才恢復運作。

cluster-migration-barrier
:主節點需要的最小從節點數,只有達到這個數,主節點失敗時,它從節點才會進行遷移。更詳細介紹可以看本教程後面關於副本遷移到部分。

cluster-require-full-coverage
<yes/no>:在部分key所在的節點不可用時,如果此引數設定為”yes”(預設值),
則整個叢集停止接受操作;如果此引數設定為”no”,則叢集依然為可達節點上的key提供讀操作。

以上所述是小編給大家介紹的Redis叢集的相關詳解整合,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回覆大家的。在此也非常感謝大家對我們網站的支援!