Redis學習(4)-----集羣

思維導圖:

引言

    本文是對Redis集羣機制的簡單介紹。主要內容有主從節點的原理,Cluster集羣的構建及原理,最後,簡單介紹了Redis的哨兵機制。

 

一.主從節點

    在對Cluster集羣進行介紹之前,需要先了解Redis的主從節點機制,其本質思想是冗餘設計,即當主節點異常時使用從節點代替主節點以使系統可以繼續進行服務。

1.1 CAP原理

    因爲Redis通常會在分佈式系統中使用,所以這裏對CAP原理進行簡單介紹。

  • C :Consistent 一致性
  • A :Availability 可用性 
  • P : Partition tolerance 分區容忍性。

    分佈式節點經常會出現網絡斷開,這種情況被稱之爲網絡分區。每當出現網絡分區的時候,數據的一致性便得不到滿足,因爲節點之間已不能進行通訊。而爲了保持系統的一致性,便只能犧牲系統的可用性,即斷掉出現網絡分區的節點,也就是使用從節點從而保證系統的一致性。當無從節點可用的時候,整個系統便不能正常工作了。

    總之,當出現網絡分區時,一致性和可用性便是魚與熊掌不可兼得。

1.2 同步機制

    使用Cluster集羣時,數據默認的複製方式是異步同步的,也被稱爲最終一致性。主節點會將必要的指令傳輸給從節點使其執行以保證一致性。從節點出現網絡分區後,如果從節點再次成功接入主節點,那麼從節點會採取多種方式同步數據。當然,Cluster也支持數據同步同步,使用wait命令即可做到,代價是速度的犧牲以及可能出現的永久性阻塞。

    Cluster集羣有兩種同步方式,一種是增量同步,一種是快照同步,其原理類似於持久化的AOF和快照。

增量同步

    Redis中內存有有一個緩存buffer,其數據結構是環形數組。Redis會將其執行的存在內容修改的指令存入次環形數組中,然後將環形數組的內容傳輸給從節點以保證數據的一致性。從節點在收到指令並執行後,會返回以執行到哪裏的信息,也就是偏移量。所以,Cluster存在一個問題。當從節點長時間與主節點斷開連接時,主節點環形數組的大小是有限的,可能就會出現還尚未傳輸的指令直接被覆蓋的情況。這種時候就需要使用快照同步了。

快照同步

    快照同步就是Redis在本地做一次快照bgsave,然後將生成的持久化文件直接傳輸到從節點,最後從節點(已清空)執行快照文件的內容。因爲在本地進行快照會消耗相當大的IO資源,所以有了無盤同步,其實就是直接將快照的信息通過套接字傳輸給從節點而不再本地寫入快照文件。

 

二. Cluster集羣

    Cluster集羣只是Redis集羣化方案的其中一種,但是這是由Redis作者支持的,所以Redis的集羣以Cluster爲例。

2.1 Cluster原理

    Redis Cluster會將所有數據劃分爲16384個槽位。集羣的每個節點會負責其中的一部分,即槽位和節點之間是存在映射關係的。節點對應的槽位信息會被持久化到本地的文件中。

    客戶端則會緩存槽位的相關信息,這樣,當客戶端需要定位某個key時,就可以直接定位到目標節點。

2.1.1 槽位定位

    Redis Cluster默認使用crc16算法進行hash然後對16384取模以確定key對應的槽位。也可以使用tag標記強制性的將key定位在tag所在的槽位上

2.1.2 跳轉

    當客戶端向錯誤的節點發送指令後,該節點會發現此槽位不歸自己管理,他會發送一個特殊的跳轉指令並攜帶目標操作的節點地址,客訴客戶端連接這個節點可以獲取數據,如下圖:

get x                                     //獲取key x
-MOVED 1000 127.0.0.0:7000                //1000表示槽位編號,後面則是正確節點的IP地址和端口號

2.1.3 遷移

    Redis Cluster可以利用redis-trib工具將一個槽位遷移至另一個節點。當槽位正在進行遷移時,源節點的此槽位會被設置爲中間狀態migrating,目標節點此槽位被設置爲importing狀態。隨後,redis-trib會獲取源節點此槽位中的key列表,然後一個一個key的存入目標節點並刪除源節點中的數據。如果key很大的話,會導致Redis的阻塞,而key小則不會有太大的影響,所以儘量避免大key出現。

    當槽位的某個key正在遷移而客戶端又恰恰好在此時訪問時,源節點則會返回一個 -ASK targetNodeAddr 的重定向指令。客戶端接收到 ASK指令後會去目標節點執行一個沒有任何參數的ASKING指令。然後會在目標節點重新執行原先的操作指令。執行ASKING指令的原因是當客戶端請求源節點時,源節點發現槽位正在遷移,所以返回一個MOVED指令,這樣就可能會出現重定向循環,ASKING指令就是說,下一個指令必須當成自己的槽位處理。

2.1.4 主從切換

    因爲網絡可能會出現網絡抖動,即突然間部分連接不可訪問,然後又突然可以訪問了。我們可以通過設置cluster-node-timeout來避免出現誤判。他的意思是必須超過此時間纔會認定出現節點故障。

    Redis Cluster是去中心化得,所以當少量的節點認爲某個節點出現出現故障後並不會進行主從切換,而是廣播此節點失聯了   P FAIL。只有當大量節點認爲某個節點出現主從故障時即P FAIL COUNT 以達到集羣的大多數時,會立即對該節點進行主從切換。

 

2.2 Cluster構建

    Redis Cluster 集羣的構建主要分爲三大步驟:

  1. 修改redis.conf配置
  2. 啓動redis
  3. 運行cluster構建命令

    看網上的博客,以前在配置Cluster集羣的時候需要用到Ruby,但是最新版本的Redis已經不需要使用Ruby就可以構建Cluster集羣了。取而代之的時redis-cli。以前用的命令都被移植到了這個命令下,系統會有提示。

    爲了模擬三主三從共六個節點的場景,我們首先創建這六個節點所在的文件夾

mkdir redis-cluster //用於儲存6個節點
mkdir 7000 7001 7002 7003 7004 7005 //以端口號在同一臺機器上區分6個節點
cp ../redis-5.0.4/redis.conf  ./7000 //每個節點的文件夾下都創建一個配置文件

 

2.2.1 redis.conf配置

    我們將redis.conf文件經過以下修改,每個節點的端口號不同,分別copy到6個節點的文件夾下

bind 127.0.0.1  //綁定服務器IP地址

port 7000  //綁定端口號,必須修改,以此來區分Redis實例

daemonize yes  //後臺運行

pidfile /var/run/redis-7000.pid  //修改pid進程文件名,以端口號命名

logfile /home/zhouhao/redis-cluster/7000/redis.log  //修改日誌文件名稱,以端口號爲目錄來區分

dir /home/zhouhao/redis-cluster/7000/  //修改數據文件存放地址,以端口號爲目錄名來區分

cluster-enabled yes  //啓用集羣

cluster-config-file nodes-7000.conf  //配置每個節點的配置文件,同樣以端口號爲名稱

cluster-node-timeout 15000  //配置集羣節點的超時時間,可改可不改

appendonly yes  //啓動AOF增量持久化策略

appendfsync always  //發生改變就記錄日誌

2.2.2 運行Redis

    使用服務端命令啓動六個Redis實例並指定redis.conf文件位置。我這裏使用的相對路徑,所以在不同機器上實驗時路徑可能有變化。

./src/redis-server ../redis-cluster/7000/redis.conf
./src/redis-server ../redis-cluster/7001/redis.conf
./src/redis-server ../redis-cluster/7002/redis.conf
./src/redis-server ../redis-cluster/7003/redis.conf
./src/redis-server ../redis-cluster/7004/redis.conf
./src/redis-server ../redis-cluster/7005/redis.conf

2.2.3 創建Cluster集羣

//replicas 1 指主從節點配置比例爲1:1
//-a zhouhao960824 因爲我的redis文件中定義了密碼,所以需要指定米麪
./redis-cli --cluster create 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 --cluster-replicas 1 -a zhouhao

2.2.4 使用

//進入指定節點 -c 必須,指cluster集羣,-h ip,-p 端口號
./redis-cli -c -h 127.0.0.1 -p 7000
//查看節點狀態
cluster nodes

運行上述命令後便可以查看cluster集羣的狀態了,如下圖:

 

三 哨兵 Sentinel

    這個小節會對哨兵做簡單的概念性介紹。

    哨兵是官方提供的一種用於抵抗節點故障的一種方案。他可以幫組我們在節點故障的時候自動進行主從切換,而不需要運維人員維護。

    假如有如下場景,現有一主兩從的Redis 哨兵集羣。哨兵就會持續監控主節點的健康狀態。客戶端連接集羣時,會首先連接哨兵,通過哨兵來查詢主節點地址,然後在連接主節點進行數據交互。

    如果主節點掛掉了,哨兵會自動選擇一個最優的從節點切換成主節點。此後,如果客戶端再次訪問,哨兵就會將最新的主節點地址返回客戶端。

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