推薦學習:
從伺服器連線主伺服器,傳送PSYNC命令;
主伺服器接收到PSYNC命名後,開始執行BGSAVE命令生成RDB檔案並使用緩衝區記錄此後執行的所有寫命令;
主伺服器BGSAVE執行完後,向所有從伺服器傳送快照檔案,並在傳送期間繼續記錄被執行的寫命令;
從伺服器收到快照檔案後丟棄所有舊資料,載入收到的快照;
主伺服器快照傳送完畢後開始向從伺服器傳送緩衝區中的寫命令;
從伺服器完成對快照的載入,開始接收命令請求,並執行來自主伺服器緩衝區的寫命令;(從伺服器初始化完成)
主伺服器每執行一個寫命令就會向從伺服器傳送相同的寫命令,從伺服器接收並執行收到的寫命令(從伺服器初始化完成後的操作)
當master與slave之間的連線由於某些原因而斷開時,slave能夠自動重連Master,如果master收到了多個slave並行連線請求,它只會進行一次持久化,而不是一個連線一次,然後再把這一份持久化的資料傳送給多個並行連線的slave。
優點:
支援主從複製,主機會自動將資料同步到從機,可以進行讀寫分離
為了分載Master的讀操作壓力,Slave伺服器可以為使用者端提供唯讀操作的服務,寫服務仍然必須由Master來完成
Slave同樣可以接受其它Slaves的連線和同步請求,這樣可以有效的分載Master的同步壓力。
Master Server是以非阻塞的方式為Slaves提供服務。所以在Master-Slave同步期間,使用者端仍然可以提交查詢或修改請求。
Slave Server同樣是以非阻塞的方式完成資料同步。在同步期間,如果有使用者端提交查詢請求,Redis則返回同步之前的資料
缺點:
Redis不具備自動容錯和恢復功能,主機從機的宕機都會導致前端部分讀寫請求失敗,需要等待機器重新啟動或者手動切換前端的IP才能恢復。
主機宕機,宕機前有部分資料未能及時同步到從機,切換IP後還會引入資料不一致的問題,降低了系統的可用性。
Redis較難支援線上擴容,在叢集容量達到上限時線上擴容會變得很複雜。
此處使用6380作為master節點 6381和6382作為slave節點
#1、 建立目錄 conf/master-slave-cluster 存放對應叢集的設定資訊mkdir -p conf/master-slave-cluster# 建立目錄 data 存放對應叢集對應的資料資訊(資料目錄)mkdir -p /usr/local/redis/data/6380 mkdir -p /usr/local/redis/data/6381 mkdir -p /usr/local/redis/data/6382 #複製一份redis.conf檔案 重新命名redis-6381.conf# 2、將相關設定修改為如下值:# 修改埠號port 6381# 把pid程序號寫入pidfile設定的檔案pidfile /var/run/redis_6381.pid # 指定紀錄檔存放目錄logfile "6381.log"# 指定資料存放目錄dir /usr/local/redis-5.0.3/data/6381 # 需要註釋掉bind# bind 127.0.0.1(bind繫結的是自己機器網路卡的ip,如果有多塊網路卡可以配多個ip,代表允許使用者端通過機器的哪些網路卡ip去存取,內網一般可以不設定bind,註釋掉即可)# 3、設定主從複製(6380是master不需要設定如下 只需給6381和6382設定如下屬性)# 從本機6379的redis範例複製資料,Redis 5.0之前使用slaveofreplicaof xxx.xxx.xxx.xxx 6380 # 設定從節點唯讀replica-read-only yes #4、啟動從節點redis-server redis-6381.conf5、連線從節點 redis-cli -p 63816、測試在6380範例上寫資料,6381範例是否能及時同步新修改資料7、同樣的方法再設定一個6382的從節點
檢視redis的主從叢集
master操作
# 連線master[root@ip redis]# src/redis-cli -p 6380127.0.0.1:6380> auth xiu123 OK127.0.0.1:6380> set name "zhangsan"OK127.0.0.1:6380> get name "zhangsan"
slave操作
# 連線slavesrc/redis-cli -p 6381127.0.0.1:6381> get name "zhangsan"#從節點只能進行讀操作127.0.0.1:6381> set name lisi(error) READONLY You can't write against a read only replica.127.0.0.1:6381> ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/36d9e96b1cae498fad03e04d695997c2.png#pic_center)
當master和slave斷開重連後,一般都會對整份資料進行復制。但從redis2.8版本開始,redis改用可以支援部分資料複製的命令PSYNC去master同步資料,slave與master能夠在網路連線斷開重連後只進行部分資料複製(斷點續傳)。
master會在其記憶體中建立一個複製資料用的快取佇列,快取最近一段時間的資料,master和它所有的slave都維護了複製的資料下標offset和master的程序id,因此,當網路連線斷開後,slave會請求master繼續進行未完成的複製,從所記錄的資料下標開始。如果master程序id變化了,或者從節點資料下標offset太舊,已經不在master的快取佇列裡了,那麼將會進行一次全量資料的複製。
主從複製(部分複製,斷點續傳)流程圖:
如果有很多從節點,為了緩解主從複製風暴**(多個從節點同時複製主節點導致主節點壓力過大),可以做如下架構,讓部分從節點與從節點(與主節點同步)同步資料
2、Redis哨兵高可用架構
sentinel哨兵是特殊的redis服務,不提供讀寫服務,主要用來監控redis範例節點。哨兵的作用就是監控Redis系統的執行狀況。它的功能包括以下兩個
(1)監控主伺服器和從伺服器是否正常執行。
(2)主伺服器出現故障時自動將從伺服器轉換為主伺服器。
三個定時任務
sentinel在內部有3個定時任務
1)每10秒每個sentinel會對master和slave執行info命令,這個任務達到兩個目的:
a)發現slave節點
b)確認主從關係
2)每2秒每個sentinel通過master節點的channel交換資訊(pub/sub)。master節點上有一個釋出訂閱的頻道(sentinel:hello)。sentinel節點通過__sentinel__:hello頻道進行資訊交換(對節點的"看法"和自身的資訊),達成共識。
3)每1秒每個sentinel對其他sentinel和redis節點執行ping操作(相互監控),這個其實是一個心跳檢測,是失敗判定的依據。
優點:
哨兵模式是基於主從模式的,所有主從的優點,哨兵模式都具有。
主從可以自動切換,系統更健壯,可用性更高。
缺點:
Redis較難支援線上擴容,在叢集容量達到上限時線上擴容會變得很複雜。
# 1、複製一份sentinel.conf檔案mkdir sentinelcp sentinel.conf sentinel-26380.conf # 保護模式protected-mode no # 埠號port 26380# 是否靜默啟動daemonize yes # pid程序號pidfile "/var/run/redis-sentinel-26380.pid" # 紀錄檔檔案logfile "/usr/local/redis/data/6380/sentinel.log" # 哨兵服務資料儲存dir "/usr/local/redis/data" # 哨兵監控 sentinel monitor <masterName> <maste節點redis ip> <num 哨兵認可主觀下線數量> # 故障轉移後 master節點ip會發生變化sentinel monitor mymaster 182.92.189.235 6380 2 # 連線master節點 密碼# 設定連線master和slave時的密碼,注意的是sentinel不能分別為master和slave設定不同的密碼,因此master和slave的密碼應該設定相同。sentinel auth-pass mymaster xiu123#sentinel config-epoch mymaster 9#sentinel leader-epoch mymaster 9# 自動生成 從節點資訊 但是此處沒有自動生成sentinel known-slave mymaster 182.92.189.235 6381sentinel known-slave mymaster 182.92.189.235 6382 # 自動生成設定 啟動回自動生成一些設定
#啟動sentinel哨兵範例src/redis-sentinel sentinel-26380.conf #檢視sentinel的info資訊src/redis-cli -p 26379127.0.0.1:26379>info #可以看到Sentinel的info裡已經識別出了redis的主從 #同理再次新增兩個sentinel,埠26381和26382 並同理啟動,注意上述組態檔裡的對應數位都要修改
sentinel叢集都啟動完畢後,會將哨兵叢集的後設資料資訊寫入所有sentinel的組態檔裡去(追加在檔案的最下面),我們檢視下如下組態檔sentinel-26380.conf,如下所示:
"shell # 1、檢視當前redis 叢集服務 一主兩從三哨兵 [root@iZ2ze505h9bgsa1t9twojyZ redis]# ps -ef | grep redis root 1166 30926 0 22:43 pts/2 00:00:00 grep --color=auto redis root 28998 1 0 21:12 ? 00:00:06 src/redis-server *:6380 root 29010 1 0 21:12 ? 00:00:06 src/redis-server *:6381 root 29020 1 0 21:12 ? 00:00:06 src/redis-server *:6382 root 31686 1 0 22:05 ? 00:00:05 src/redis-sentinel *:26380 [sentinel] root 32553 1 0 22:22 ? 00:00:03 src/redis-sentinel *:26381 [sentinel] root 32562 1 0 22:22 ? 00:00:03 src/redis-sentinel *:26382 [sentinel] [root@iZ2ze505h9bgsa1t9twojyZ redis]# src/redis-cli -p 6380 127.0.0.1:6380> auth xiu123 OK 127.0.0.1:6380> info replication # Replication role:master connected_slaves:2 slave0:ip=182.92.189.235,port=6381,state=online,offset=261525,lag=0 slave1:ip=182.92.189.235,port=6382,state=online,offset=261525,lag=1 ... 省略部分程式碼 127.0.0.1:6380> quit # 殺掉 redis [root@iZ2ze505h9bgsa1t9twojyZ redis]# kill -9 28998 # 檢視紀錄檔 [root@iZ2ze505h9bgsa1t9twojyZ redis]# tail -f data/6380/sentinel.log # 該哨兵認為主觀下線 31686:X 12 Nov 2021 22:45:40.110 # +sdown master mymaster 182.92.189.235 6382 # 到達主觀下線闕值 則客觀下線 31686:X 12 Nov 2021 22:45:40.181 # +odown master mymaster 182.92.189.235 6382 #quorum 2/2 31686:X 12 Nov 2021 22:45:40.181 # +new-epoch 18 # 嘗試故障轉移 31686:X 12 Nov 2021 22:45:40.181 # +try-failover master mymaster 182.92.189.235 6382 # 投票選舉主節點 31686:X 12 Nov 2021 22:45:40.189 # +vote-for-leader ba9eed52de8664c3fd8d76d9728b42a309c3401b 18 # 選擇主節點 6381 31686:X 12 Nov 2021 22:45:41.362 # +switch-master mymaster 182.92.189.235 6382 182.92.189.235 6381 #檢視新的主從節點資訊 主節點6381 從節點6382 [root@iZ2ze505h9bgsa1t9twojyZ redis]# src/redis-cli -p 6381 127.0.0.1:6381> auth xiu123 OK 127.0.0.1:6381> info replication # Replication role:master connected_slaves:1 slave0:ip=182.92.189.235,port=6382,state=online,offset=469749,lag=0 "
redis的哨兵模式基本已經可以實現高可用,讀寫分離 ,但是在這種模式下每臺redis伺服器都儲存相同的資料,很浪費記憶體,所以在redis3.0上加入了cluster模式,實現的redis的分散式儲存,也就是說每臺redis節點上儲存不同的內容。
Redis-Cluster採用無中心結構,它的特點如下:
所有的redis節點彼此互聯(PING-PONG機制),內部使用二進位制協定優化傳輸速度和頻寬。
節點的fail是通過叢集中超過半數的節點檢測失效時才生效。
使用者端與redis節點直連,不需要中間代理層.使用者端不需要連線叢集所有節點,連線叢集中任何一個可用節點即可。
工作方式:
在redis的每一個節點上,都有這麼兩個東西,一個是插槽(slot),它的的取值範圍是:0-16383。還有一個就是cluster,可以理解為是一個叢集管理的外掛。當我們的存取的key到達的時候,redis會根據crc16的演演算法得出一個結果(hash函數),然後把結果對 16384 求餘數,這樣每個 key 都會對應一個編號在 0-16383 之間的雜湊槽,通過這個值,去找到對應的插槽所對應的節點,然後直接自動跳轉到這個對應的節點上進行存取操作。
為了保證高可用,redis-cluster叢集引入了主從模式,一個主節點對應一個或者多個從節點,當主節點宕機的時候,就會啟用從節點。當其它主節點ping一個主節點A時,如果半數以上的主節點與A通訊超時,那麼認為主節點A宕機了。如果主節點A和它的從節點A1都宕機了,那麼該叢集就無法再提供服務了。
redis叢集是一個由多個主從節點群組成的分散式伺服器群,它具有複製、高可用和分片特性。Redis叢集不需要sentinel哨兵·也能完成節點移除和故障轉移的功能。需要將每個節點設定成叢集模式,這種叢集模式沒有中心節點,可水平擴充套件,據官方檔案稱可以線性擴充套件到上萬個節點(官方推薦不超過1000個節點)。redis叢集的效能和高可用性均優於之前版本的哨兵模式,且叢集設定非常簡單
redis叢集需要至少三個master節點,我們這裡搭建三個master節點,並且給每個master再搭建一個slave節點,總共6個redis節點,這裡用三臺機器部署6個redis範例,每臺機器一主一從,搭建叢集的步驟如下:
6383(主) 6384(從)
6385(主) 6386(從)
6387(主) 6388(從)
# 是否靜默啟動 daemonize yes #埠號 port 6383 # pid程序檔案 pidfile /var/run/redis_6383.pid #資料儲存 dir /usr/local/redis/data/redis-cluster/6383/ # 指定紀錄檔存放目錄 logfile "/usr/local/redis/data/cluster-6383.log" #是否啟動叢集模式 cluster-enabled yes #(叢集節點資訊檔案,這裡最好和port對應上) cluster-config-file nodes-6383.conf cluster-node-timeout 10000 # 關閉保護模式 protected-mode no
redis叢集設定好後,在5.X版本之前需要需要使用ruby指令碼去建立叢集,但是5.x之後可以通過redis-cli 執行建立叢集命令即可
# 分別啟動redis範例 src/redis-server conf/cluster/638*/redis.conf # 下面命令裡的1代表為每個建立的主伺服器節點建立一個從伺服器節點 # 執行這條命令需要確認三臺機器之間的redis範例要能相互存取,可以先簡單把所有機器防火牆關掉,如果不關閉防火牆則需要開啟redis伺服器埠和叢集節點gossip通訊埠16379(預設是在redis埠號上加1W) # 關閉防火牆 # systemctl stop firewalld # 臨時關閉防火牆 # systemctl disable firewalld # 禁止開機啟動 # 注意:下面這條建立叢集的命令大家不要直接複製,裡面的空格編碼可能有問題導致建立叢集不成功 # 本次測試不遠端連線 使用127.0.0.1 如果涉及遠端連線需要設定真實公網ip # -a 密碼。 -- cluster create建立叢集 --cluster-replicas 1 每一個master建立一個從節點 6個範例 中選擇3個作為另外3個主節點的從節點,最終變成3主3從 src/redis-cli -a password --cluster create --cluster-replicas 1 127.0.0.1:6383 127.0.0.1:6384 127.0.0.1:6385 127.0.0.1:6386 127.0.0.1:6387 127.0.0.1:6388
問題:
#1、這是由於建立叢集中的某一個服務中曾經插入過資料,並且已經產生了持久化檔案,重新再進行建立叢集 此時需要flushall命令清空所有資料 [ERR] Node 127.0.0.1:6383 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0 #測試使用flush不好使用 只要找到組態檔對應資料儲存目錄 暴力rm刪除 # 2、登陸某個叢集出現 出現CLUSTERDOWN Hash slot not served 原因 啟動叢集範例後沒有執行叢集建立
讀寫key需要 對key進行hash 不使用叢集模式登陸使用者端,則我們只存取單獨會提示讓我們去對應的節點上進行操作
叢集登陸
# 連線任意一個使用者端即可:./redis-cli -c -h -p (-a存取伺服器端密碼,-c表示叢集模式,指定ip地址和埠號) # -a 密碼 -c 叢集模式 -h ip -p port src/redis-cli -a password -c -h 127.0.0.1 -p 6383
#進行驗證: cluster info(檢視叢集資訊)、cluster nodes(檢視節點列表) #進行資料操作驗證 #關閉叢集則需要逐個進行關閉,使用命令: src/redis-cli -a password -c -h 127.0.0.1 -p 638* shutdown
上述叢集三主三從 。6386、6387、6388分別對應主節點6383、6384、6385的從,如果某個主節點宕機,則從節點會自動被選舉為主節點繼續對外提供服務,一定的容錯機制保證高可用。注意存在從節點的情況下,主從節點不具備讀寫分離,讀寫都使用主節點
# 模擬redis的故障轉移 #登陸節點 發現 name這個key在6384上 age這個key在6383上 wdih這個key在6385上 [root@iZ2ze505h9bgsa1t9twojyZ redis]# src/redis-cli -a xiu123 -c -h 127.0.0.1 -p 6383 127.0.0.1:6384> get name -> Redirected to slot [5798] located at 127.0.0.1:6384 (nil) 127.0.0.1:6384> get age -> Redirected to slot [741] located at 127.0.0.1:6383 "12" 127.0.0.1:6383> get width -> Redirected to slot [15983] located at 127.0.0.1:6385 "110" 127.0.0.1:6385> quit ## 殺掉 6385這個主節點 [root@iZ2ze505h9bgsa1t9twojyZ redis]# kill -9 14187 # 重新登陸叢集 獲取 age、name 還是原來的節點 獲取width 由6385轉移到了6388 檢視6380節點資訊發現其變為了主節點 [root@iZ2ze505h9bgsa1t9twojyZ redis]# src/redis-cli -a xiu123 -c -h 127.0.0.1 -p 6383 127.0.0.1:6383> get age "12" # 這裡因該是在選舉master節點 導致叢集短暫不可用(猜測) 127.0.0.1:6383> get name (error) CLUSTERDOWN The cluster is down 127.0.0.1:6383> get name -> Redirected to slot [5798] located at 127.0.0.1:6384 "xieqx" 127.0.0.1:6384> get width -> Redirected to slot [15983] located at 127.0.0.1:6388 "110" 127.0.0.1:6388> info replication # Replication role:master # 殺掉 6388 則整個叢集服務都不可用 127.0.0.1:6383> get name (error) CLUSTERDOWN The cluster is down
#複製之前6383節點設定 建立6389、6390節點 並啟動範例 --- 叢集擴容 ---- #1、 新增master節點 ## add-node: 後面的分別跟著新加入的***master和叢集的某個節點 NODE_ID*** src/redis-cli --cluster add-node 127.0.0.1:6389 127.0.0.1:6383 -a password # 2、為增加的主節點新增從節點 #--cluster-slave 表明新增的是slave節點 ## add-node: 後面的分別跟著新加入的****slave和slave對應的master NODE_ID*** #--cluster-master-id:表示slave對應的master的node ID src/redis-cli --cluster add-node 127.0.0.1:6390 127.0.0.1:6389 --cluster-slave --cluster-master-id 353662f6868b187ad15bad9b7271b8f0848adf10 -a password # 3、 重新分片slot #-cluster-from:表示slot目前所在的節點的node ID,多個ID用逗號分隔 #--cluster-to:表示需要新分配節點的node ID(貌似每次只能分配一個) # --cluster-slots:分配的slot數量 src/redis-cli --cluster reshard 127.0.0.1:6389 --cluster-from 47318cef1195f4281b7815bf66a41e31d68b6d16,0dbea2fff1554a3bbca70d28b81911e60c5bee6d,2fd29d61e867cb85e2e368ee62aebef33e7aaeb3 --cluster-to 353662f6868b187ad15bad9b7271b8f0848adf10 --cluster-slots 1024 -a password #檢視叢集資訊
--- 叢集縮容 ---- #下線節點127.0.0.1:6389(master)/127.0.0.1:6390(slave) #(1)首先刪除master對應的slave #del-node後面跟著slave節點的 ip:port 和node ID src/redis-cli --cluster del-node 127.0.0.1:6390 353662f6868b187ad15bad9b7271b8f0848adf10 -a password #(2)清空master的slot 將一個下線的節點的slot重新分配到其他三個節點中 #reshard子命令前面已經介紹過了,這裡需要注意的一點是,由於我們的叢集一共有四個主節點,而每次reshard只能寫一個目的節點,因此以上命令需要執行三次(--cluster-to對應不同的目的節點)。 #--cluster-yes:不回顯需要遷移的slot,直接遷移。 src/redis-cli --cluster reshard 127.0.0.1:6389 --cluster-from 353662f6868b187ad15bad9b7271b8f0848adf10 --cluster-to 0dbea2fff1554a3bbca70d28b81911e60c5bee6d --cluster-slots 1024 --cluster-yes #(3)下線(刪除)節點 主節點 src/redis-cli --cluster del-node 127.0.0.1:6389 353662f6868b187ad15bad9b7271b8f0848adf10
推薦學習:
以上就是範例詳解redis怎麼部署叢集的詳細內容,更多請關注TW511.COM其它相關文章!