redis学习之集群部署
redis學習之集群部署
- 1、Redis主從架構
- 1.1、主從復制原理
- 1.2、主從復制優缺點
- 1.3、redis主從架構搭建,配置從節點步驟
- 1.4、校驗結果
- 1.5、數據部分復制
- 2、Redis哨兵高可用架構
- 2.1、哨兵的工作方式
- 2.2、哨兵模式的優缺點
- 2.3、redis哨兵架構搭建步驟
- 2.3.1、配置sentinel.conf文件
- 2.3.2、啟動哨兵服務實例
- 2.3.3、redis哨兵模式故障遷移
- 3、Redis 高可用集群
- 3.1、高可用集群模式
- 3.2、Redis-Cluster集群
- 3.3、Redis高可用集群搭建
- 3.3.1、redis集群搭建
- 節點配置
- 創建集群
- 驗證集群
- 3.3.2、集群故障轉移
- 3.3.3、集群動態擴縮容
1、Redis主從架構
1.1、主從復制原理
-
從服務器連接主服務器,發送PSYNC命令;
-
主服務器接收到PSYNC命名后,開始執行BGSAVE命令生成RDB文件并使用緩沖區記錄此后執行的所有寫命令;
-
主服務器BGSAVE執行完后,向所有從服務器發送快照文件,并在發送期間繼續記錄被執行的寫命令;
-
從服務器收到快照文件后丟棄所有舊數據,載入收到的快照;
-
主服務器快照發送完畢后開始向從服務器發送緩沖區中的寫命令;
-
從服務器完成對快照的載入,開始接收命令請求,并執行來自主服務器緩沖區的寫命令;(從服務器初始化完成)
-
主服務器每執行一個寫命令就會向從服務器發送相同的寫命令,從服務器接收并執行收到的寫命令(從服務器初始化完成后的操作)
-
當master與slave之間的連接由于某些原因而斷開時,slave能夠自動重連Master,如果master收到了多個slave并發連接請求,它只會進行一次持久化,而不是一個連接一次,然后再把這一份持久化的數據發送給多個并發連接的slave。
1.2、主從復制優缺點
優點:
-
支持主從復制,主機會自動將數據同步到從機,可以進行讀寫分離
-
為了分載Master的讀操作壓力,Slave服務器可以為客戶端提供只讀操作的服務,寫服務仍然必須由Master來完成
-
Slave同樣可以接受其它Slaves的連接和同步請求,這樣可以有效的分載Master的同步壓力。
-
Master Server是以非阻塞的方式為Slaves提供服務。所以在Master-Slave同步期間,客戶端仍然可以提交查詢或修改請求。
-
Slave Server同樣是以非阻塞的方式完成數據同步。在同步期間,如果有客戶端提交查詢請求,Redis則返回同步之前的數據
缺點:
-
Redis不具備自動容錯和恢復功能,主機從機的宕機都會導致前端部分讀寫請求失敗,需要等待機器重啟或者手動切換前端的IP才能恢復。
-
主機宕機,宕機前有部分數據未能及時同步到從機,切換IP后還會引入數據不一致的問題,降低了系統的可用性。
-
Redis較難支持在線擴容,在集群容量達到上限時在線擴容會變得很復雜。
1.3、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之前使用slaveof replicaof xxx.xxx.xxx.xxx 6380 # 配置從節點只讀 replica-read-only yes #4、啟動從節點 redis-server redis-6381.conf5、連接從節點 redis-cli -p 63816、測試在6380實例上寫數據,6381實例是否能及時同步新修改數據7、同樣的方法再配置一個6382的從節點1.4、校驗結果
查看redis的主從集群
master操作
# 連接master [root@ip redis]# src/redis-cli -p 6380 127.0.0.1:6380> auth xiu123 OK 127.0.0.1:6380> set name "zhangsan" OK 127.0.0.1:6380> get name "zhangsan"slave操作
# 連接slave src/redis-cli -p 6381 127.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> 1.5、數據部分復制
當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)主服務器出現故障時自動將從服務器轉換為主服務器。
2.1、哨兵的工作方式
三個定時任務
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操作(相互監控),這個其實是一個心跳檢測,是失敗判定的依據。
2.2、哨兵模式的優缺點
優點:
哨兵模式是基于主從模式的,所有主從的優點,哨兵模式都具有。
主從可以自動切換,系統更健壯,可用性更高。
缺點:
Redis較難支持在線擴容,在集群容量達到上限時在線擴容會變得很復雜。
2.3、redis哨兵架構搭建步驟
2.3.1、配置sentinel.conf文件
# 1、復制一份sentinel.conf文件 mkdir sentinel cp 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 6381 sentinel known-slave mymaster 182.92.189.235 6382# 自動生成配置 啟動回自動生成一些配置2.3.2、啟動哨兵服務實例
#啟動sentinel哨兵實例 src/redis-sentinel sentinel-26380.conf #查看sentinel的info信息 src/redis-cli -p 26379 127.0.0.1:26379>info #可以看到Sentinel的info里已經識別出了redis的主從 #同理再次添加兩個sentinel,端口26381和26382 并同理啟動,注意上述配置文件里的對應數字都要修改sentinel集群都啟動完畢后,會將哨兵集群的元數據信息寫入所有sentinel的配置文件里去(追加在文件的最下面),我們查看下如下配置文件sentinel-26380.conf,如下所示:
2.3.3、redis哨兵模式故障遷移
```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```3、Redis 高可用集群
3.1、高可用集群模式
3.2、Redis-Cluster集群
? 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集群的性能和高可用性均優于之前版本的哨兵模式,且集群配置非常簡單
3.3、Redis高可用集群搭建
3.3.1、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* shutdown3.3.2、集群故障轉移
上述集群三主三從 。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 down3.3.3、集群動態擴縮容
#復制之前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学习之集群部署的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 通过HTTP响应头让浏览器自动刷新
- 下一篇: 清华大学计算机专业在职博士吧,清华大学计