當前位置:網站首頁>Redis cluster集群原理與配置

Redis cluster集群原理與配置

2022-05-13 11:18:25菊頭蝙蝠

相關鏈接
分布式原理:
分布式系統的CAP理論
簡述BASE理論
集群:
技術白話:分布式和集群
一致性哈希算法
Cluster集群
服務器連接的主數據庫宕機了,就進行主從切換,服務器連接從數據庫,保證可用性(A)

一、cluster集群原理

Redis cluster 將所有數據劃分為 16384( 2 14 2^{14} 214 )個槽比特,每個 redis 節點負責其中一部分槽比特。
cluster 集群是一種去中心化的集群方式; 如圖,該集群由三個 redis
節點組成,每個節點負責整個集群的一部分數據,每個節點負責的數據
多少可能不一樣。這三個節點相互連接組成一個對等的集群,它們之間通過一種特殊的二進制協議 交互集群信息; 當 redis cluster
的客戶端來連接集群時,會得到一份集群的槽比特配置信息。這樣當客戶端要查找 某個 key時,可以直接定比特到目標節點。
客戶端為了可以直接定比特(對 key 通過 crc16 進行 hash 再對 取餘)某個具體的 key 所在節
點,需要緩存槽比特相關信息,這樣才可以准確快速地定比特到相應的節點。同時因為可能會存在客戶
端與服務器存儲槽比特的信息不一致的情况,還需要糾正機制(通過返回 -MOVED 3999
127.0.0.1:6479 ,客戶端收到後需要立即糾正本地的槽比特映射錶)來實現槽比特信息的校驗調整。 另外,redis cluster 的每個節點會將集群的配置信息持久化到配置文件中,這就要求確保配置文件 是可寫的,而且盡量不要依靠人工修改配置文件;

在這裏插入圖片描述

cluster集群中的一致性算法和一致性哈希算法相似,但還是有所不同

1.建立集群
2.分配槽比特

1、數據遷移

redis cluster 提供了工具 redis-trib 可以讓運維人員手動調整槽比特的分配情况,它采用 ruby 語言
開發,通過組合原生的 redis cluster 指令來實現。圖中:A 為待遷移的源節點,B 為待遷移的目
標節點;

在這裏插入圖片描述

過程

如上圖:redis 遷移的單比特是槽,redis 是一個槽一個槽地進行遷移,當一個槽比特正在遷移時,這
個槽就處於中間過渡狀態。這個槽再源節點的狀態為 migrating ,在目標節點的狀態為
importing ,錶示此時數據正在從源節點流向目標節點。
遷移工具 redis-trib 首先在源節點和目標節點設置好中間過渡狀態,然後一次性獲取源節點槽比特的
所有或者部分的 key 列錶,再依次將 key 進行遷移。源節點對當前的 key 執行 dump 指令得到序
列化內容,然後向目標節點發送 restore 指令,目標節點將源節點的序列化內容進行反序列化並將
內容應用到目標節點的內容中,然後返回 +ok 給源節點,源節點收到後删除該 key;按照這些步
驟將所有待遷移的 key 進行遷移;
注意:遷移過程是同步的,遷移過程中源節點的主線程處於阻塞狀態,直到key被删除;如果遷移
過程中源節點出現網絡故障,這兩個節點依然處於中間狀態,重啟後,redis-trib可繼續遷移;
所以,redis-trib 遷移的過程是一個一個 key 來進行,如果這個 key 對應 val 內容很大,將會影響
到客戶端的正常訪問;

2、複制以及故障轉移

cluster 集群中節點分為主節點和從節點,其中主節點用於處理槽,而從節點則用於複制該主節
點,並在主節點下線時,代替主節點繼續處理命令請求;

故障檢測

集群中每個節點都會定期地向集群中的其他節點發送 ping 消息,如果接收 ping 消息的節點沒有
在規定時間內回複 pong 消息,那麼這個沒有回複 pong 消息的節點會被標記為 PFAIL(probable
fail);
集群中各個節點會通過互相發送消息的方式來交換集群中各個節點的狀態信息;如果在一個集群
中,半數以上負責處理槽的主節點都將某個主節點 A 報告為疑似下線,那麼這個主節點A將被標記
為下線(FAIL);標記主節點 A 為下線狀態的主節點會廣播這條消息,其他節點(包括A節點的從
節點)也會將A節點標識為 FAIL;

故障轉移

當從節點發現自己的主節點進入FAIL狀態,從節點將開始對下線主節點進行故障轉移;

  • 從數據最新的從節點中選舉為主節點;
  • 該從節點會執行 replica no one 命令,稱為新的主節點;
  • 新的主節點會撤銷所有對已下線主節點的槽指派,並將這些槽全部指派給自己;
  • 新的主節點向集群廣播一條 pong 消息,這條 pong 消息可以讓集群中的其他節點立即知道 這個節點已經由從節點變成主節點,並且這個主節點已經接管了之前下線的主節點;
  • 新的主節點開始接收和自己負責處理的槽有關的命令請求,故障轉移結束;

二、配置cluster集群

在這裏插入圖片描述

上圖是,中間3個主數據庫,每個主數據庫還有1個從數據庫
下面配置的時候就采用這種方式

1、創建文件夾

# 創建 6 個文件夾
mkdir -p 7001 7002 7003 7004 7005 7006
cd 7001
vi 7001.conf
# 7001.conf 中的內容如下

2、編輯 7001.conf

pidfile "/home/mark/redis-data/7001/7001.pid"
logfile "/home/mark/redis-data/7001/7001.log"
dir /home/mark/redis-data/7001/
port 7001
daemonize yes
cluster-enabled yes
cluster-config-file nodes-7001.conf
cluster-node-timeout 15000

cluster-enabled yes 是開啟cluster集群的意思

3、複制配置

cp 7001/7001.conf 7002/7002.conf
cp 7001/7001.conf 7003/7003.conf
cp 7001/7001.conf 7004/7004.conf
cp 7001/7001.conf 7005/7005.conf
cp 7001/7001.conf 7006/7006.conf

4、修改配置

sed -i 's/7001/7002/g' 7002/7002.conf
sed -i 's/7001/7003/g' 7003/7003.conf
sed -i 's/7001/7004/g' 7004/7004.conf
sed -i 's/7001/7005/g' 7005/7005.conf
sed -i 's/7001/7006/g' 7006/7006.conf

比如sed -i 's/7001/7002/g' 7002/7002.conf 就是把7002/7002.conf中所有的7001修改成7002,比如pidfile要修改成7002.pid,等。

5、創建啟動配置

寫成sh文件

#!/bin/bash
redis-server 7001/7001.conf
redis-server 7002/7002.conf
redis-server 7003/7003.conf
redis-server 7004/7004.conf
redis-server 7005/7005.conf
redis-server 7006/7006.conf

啟動sh文件,通過ps aux|grep redis-server就可以查看到啟動6個的redis-server
在這裏插入圖片描述

6、客戶端查看

客戶端進入一個redis服務器節點

#-c是以cluster集群方式
redis-cli -c -p 7001

查看集群信息

cluster info

在這裏插入圖片描述
查看節點信息

cluster nodes

發現就一個節點,說集群還沒有搭建起來
在這裏插入圖片描述

但是現在僅僅只是啟動了6個redis服務器,還沒有創建集群

7、創建集群

智能創建集群

redis-cli --cluster help
# --cluster-replicas 後面對應的參數 為 一主對應幾個從數據庫
redis-cli --cluster create host1:port1 ... hostN:portN --cluster-replicas <arg>
redis-cli --cluster create 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:7006 --cluster-replicas 1

--cluster-replicas 1錶示,1個主數據庫對應1個從數據庫

在執行下面命令後

redis-cli --cluster create 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:7006 --cluster-replicas 1

讓我們確認下面的配置信息。
7001、7002、7003作為主數據庫(master)
7004、7005、7006作為從數據庫(slaver)

可以看到主數據分配的哈希槽信息slots
還可以看到根據replicates, 從數據庫 作為哪個主數據庫的從數據庫,

在這裏插入圖片描述
如果訪問的哈希值(hash(key)%16384),落在的哈希槽對應的數據庫上,就去訪問該數據庫

手動創建集群

# 節點會面
cluster meet ip port
# 分配槽比特
cluster addslots slot
# 分配主從
cluster replicate node-id

注意:以下的例子均以上述只能創建集群的結果演示。

8、測試集群

現在已經啟動cluster集群了,可以進行測試

設置值

redis-cli -c -p 7004
set name nbsp

可以看到"name"的哈希槽比特為5798,那麼它的存放比特置為主數據庫7002
在這裏插入圖片描述
由於7004是從數據庫
因此被重定向到7002(主數據庫)了
在這裏插入圖片描述
數據已經在7002了,那麼去7005可以查詢到嗎?
先退出之前的數據庫,訪問7005

redis-cli -c -p 7005

去查詢"name",可以發現,又被重定向到7002了
在這裏插入圖片描述
結論:
從這裏也可以理解去中心化是什麼意思了,可以從任意一個節點去訪問集群,而不是通過一個主的去訪問集群。
在從數據庫中不能進行讀寫,執行讀寫命令,都會重定向到主數據庫中去。

比如7006是7002的從數據庫,為什麼在7002中度數據還會重定向到7002呢?
因此主從是异步複制的,具有最終一致性,因此redis認為主數據的數據比較新,就訪問主數據庫了,而不是對應的從數據庫

主節點宕機

查看當前集群的節點信息

cluster nodes

在這裏插入圖片描述

關閉7002節點(使得主數據庫宕機)

redis-cli -p 7002 shutdown

一個主數據庫宕機了會發生什麼呢?
先隨便進一個數據,查看集群節點信息

redis-cli -c -p 7001
cluster nodes

可以看到7002有個fail,就是宕機了。7006多了master,也就是出現主從替換。7006這個從數據庫在7002宕機後,換成了主數據庫。(myself為當前客戶端連接的數據庫)
在這裏插入圖片描述

之前在7006中get name會發生跳轉到7002,那麼先在還會嗎?
可以發現沒有發生跳轉
在這裏插入圖片描述

主節點重啟

之前關閉的是7002,現在重啟7002

redis-server 7002/7002.conf

可以發現7002變slaver了(從數據庫)
在這裏插入圖片描述

擴容和縮容

  1. redis-server 7007/7007.conf
  2. redis-cli -cluster add-node 添加了主節點,但此時還不能訪問,需要分配槽比特
  3. 分配槽比特

下圖也就很好理解了,中間部分是集群,生產者放數據,消費者取數據
在這裏插入圖片描述

如果對於同一類數據,有時候想放在同一個節點,並不想分散在不同節點,就可以加一個花括號,以花括號裏面的字符串(相近的字符串)做哈希,這樣就可以映射到同一個節點中
在這裏插入圖片描述

版權聲明
本文為[菊頭蝙蝠]所創,轉載請帶上原文鏈接,感謝
https://cht.chowdera.com/2022/133/202205131114229224.html

隨機推薦