這篇文章為大家帶來了關於Redis的相關知識,其中主要介紹了主從模式、哨兵模式以及Redis Cluster模式的相關問題,希望對大家有幫助。
推薦學習:Redis教學
#redis 叢集方案的介紹(主從模式、哨兵模式、Redis Cluster模式)
將資料完全儲存在單一redis中主要存在兩個問題:
資料備份和資料體積較大造成的效能降低。
Redis的主從模式為這兩個問題提供了一個較好的解決方案。主從模式指的是使用一個redis實例作為主機,其餘的實例作為備份機。
主機和從機的資料完全一致,主機支援資料的寫入和讀取等各項操作,而從機則只支援與主機資料的同步和讀取,也就是說,客戶端可以將資料寫入到主機,由主機自動將資料的寫入操作同步到從機。
主從模式很好的解決了資料備份問題,並且由於主從服務資料幾乎是一致的,因而可以將寫入資料的命令發送給主機執行,而讀取資料的命令發送給不同的從機執行,從而達到讀寫分離的目的。
實作主從複製(Master-Slave Replication)的工作原理:
Slave從節點服務啟動並連接到Master之後,它將主動發送一個SYNC命令。 Master服務主節點收到同步指令後將啟動後台記憶體進程,同時收集所有接收到的用於修改資料集的指令,在背景處理程序執行完畢後,Master將傳送整個資料庫檔案到Slave,以完成一次完全同步。而Slave從節點服務在接收到資料庫檔案資料之後將其存檔並載入到記憶體中。此後,Master主節點繼續將所有已經收集到的修改命令,和新的修改命令依序傳送給Slaves,Slave將在本次執行這些資料修改命令,從而達到最終的資料同步。
如果Master和Slave之間的連結出現斷連現象,Slave可以自動重連Master,在連線成功之後,一次完全同步將會自動執行。
部署:
redis version:6.0.9
1.分別複製4份Redis設定檔
命名為master .conf slave1.conf slave2.conf slave3.conf
2.對4份設定檔進行簡單設定
Master節點的設定檔一般不需要特殊設定port預設為6379
Slave1 節點port設定6380 再配置一行replicaof 127.0.0.1 6379
Slave2 節點port設定6381 再配置一行replicaof 127.0.0.1 6379
Slave3 節點port設定6382#replicaof 127.009##7.09.分別開啟Master節點與3個Slave節點
redis-server master.conf
redis-server slave1.confredis-server slave2.conf
redis-server slave3.conf
4.驗證叢集主從狀態
#主從模式的優缺點:
1、優點:
同一個Master可以同步多個Slaves。
master能自動將資料同步到slave,可以進行讀寫分離,分擔master的讀壓力master、slave之間的同步是以非阻塞的方式進行的,同步期間,客戶端仍然可以提交查詢或更新請求
2、缺點:
不具備自動容錯與復原功能,master或slave的宕機都可能導致客戶端要求失敗,需要等待機器重新啟動或手動切換客戶端IP才能恢復
難以支援線上擴容,Redis的容量受限於單機設定
其實redis的主從模式很簡單,在實際的生產環境中很少使用,不建議在實際的生產環境中使用主從模式來提供系統的高可用性,之所以不建議使用都是由它的缺點造成的,在數據量非常大的情況,或對系統的高可用性要求很高的情況下,主從模式也是不穩定的。雖然這個模式很簡單,但這個模式是其他模式的基礎,所以了解這個模式,對其他模式的學習會很有幫助。
二、哨兵模式(Sentinel)
當master發生故障時,能自動將一個slave轉換為master(大哥掛了,選一個小弟上位)
多個哨兵可以監控同一個Redis,哨兵之間也會自動監控
當自動發現slave和其他哨兵節點後,哨兵就可以透過定期發送PING命令定時監控這些資料庫和節點有沒有停止服務。
如果被PING的資料庫或節點逾時(透過 sentinel down-after-milliseconds master-name milliseconds 配置)未回复,哨兵認為其主觀下線(sdown,s就是Subjectively —— 主觀地)。如果下線的是master,哨兵會向其它哨兵發送命令詢問它們是否也認為該master主觀下線,如果達到一定數目(即配置文件中的quorum)投票,哨兵會認為該master已經客觀下線(odown ,o就是Objectively —— 客觀地),並選舉領頭的哨兵節點對主從系統發起故障恢復。若沒有足夠的sentinel進程同意master下線,master的客觀下線狀態會被移除,若master重新向sentinel進程發送的PING指令返回有效回复,master的主觀下線狀態就會被移除。
哨兵認為master客觀下線後,故障恢復的操作需要由選舉的領頭哨兵來執行,
選出領頭哨兵後,領頭者開始對系統進行故障恢復,從出現故障的master的從資料庫中挑選一個來當選新的master,
挑選出需要繼任的slave後,領頭哨兵向該資料庫發送命令使其升格為master,然後再向其他slave發送命令接受新的master,最後更新數據。將已經停止的舊的master更新為新的master的從資料庫,使其恢復服務後以slave的身份繼續運行。
哨兵模式是基於前面的主從複製模式。哨兵的設定檔為sentinel.conf,在對應目錄中加入以下配置,注意連接埠不要衝突:
port 26379 protected-mode no daemonize yes pidfile "/var/run/redis-sentinel-26379.pid" logfile "/data/redis/logs/sentinel_26379.log" dir "/data/redis/6379" sentinel monitor mymaster 127.0.0.1 6379 2 ##指定主机IP地址和端口,并且指定当有2台哨兵认为主机挂了,则对主机进行容灾切换 #sentinel auth-pass mymaster pwdtest@2019 ##当在Redis实例中开启了requirepass,这里就需要提供密码 sentinel down-after-milliseconds mymaster 3000 ##这里设置了主机多少秒无响应,则认为挂了 sentinel failover-timeout mymaster 180000 ##故障转移的超时时间,这里设置为三分钟
格式如下:
##查看哨兵狀態:客戶端與redis節點直連,客戶端不需要連接叢集所有節點,連接叢集中任何一個可用節點即可
在Redis的每個節點上,都有一個插槽(slot),取值範圍為0-16383 ,一共16384個槽
當我們訪問key的時候,Redis會根據CRC16的演算法得出一個結果,然後把結果對16384求餘數,這樣每個key都會對應一個編號在0-16383之間的哈希槽,透過這個值,去找到對應的插槽所對應的節點,然後直接自動跳到這個對應的節點上進行存取操作。
為了增加叢集的可訪問性,官方推薦的方案是將node配置成主從結構,也就是一個master主節點,掛n個slave從節點。這時,如果主節點失效,Redis Cluster會根據選舉演算法從slave節點中選擇一個上升為主節點,整個叢集繼續對外提供服務,Redis Cluster本身提供了故障轉移容錯的能力。
根據cluster的選舉機制和主從備份的實現,redis要求至少三主三從共6個節點才能組成redis集群,測試環境可一台物理機器上啟動6個redis節點,但生產環境至少要準備2~3台實體機。 (這裡使用三台虛擬機器)
#
该模式就支持动态扩容,可以在线增加或删除节点,而且客户端可以连接任何一个主节点进行读写,不过此时的从节点仅仅只是备份的作用。至于为何能做到动态扩容,主要是因为Redis集群没有使用一致性hash,而是使用的哈希槽。Redis集群会有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽,而集群的每个节点负责一部分hash槽。
那么这样就很容易添加或者删除节点, 比如如果我想新添加个新节点, 我只需要从已有的节点中的部分槽到过来;如果我想移除某个节点,就只需要将该节点的槽移到其它节点上,然后将没有任何槽的A节点从集群中移除即可。由于从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节点的哈希槽的数量都不会造成集群不可用的状态。
需要注意的是,该模式下不支持同时处理多个key(如MSET/MGET),因为redis需要把key均匀分布在各个节点上,并发量很高的情况下同时创建key-value会降低性能并导致不可预测的行为。
搭建集群
这里就直接搭建较为复杂的Cluster模式集群,也是企业级开发过程中使用最多的。
最终目录结构如下
以 9001 的为例子,其余五个类似。
编辑 /data/redis-cluster/9001/redis.conf
redis.conf修改如下:
port 9001(每个节点的端口号) daemonize yes appendonly yes //开启aof bind 0.0.0.0(绑定当前机器 IP) dir "/data/redis-cluster/9001"(数据文件存放位置,,自己加到最后一行 快捷键 shift+g) pidfile /var/run/redis_9001.pid(pid 9001和port要对应) logfile "/data/redis-cluster/logs/9001.log" cluster-enabled yes(启动集群模式) cluster-config-file nodes9001.conf(9001和port要对应) cluster-node-timeout 15000
/data/redis-cluster/bin/redis-server /data/redis-cluster/9001/redis.conf
/data/redis-cluster/bin/redis-server /data/redis-cluster/9002/redis.conf
/data/redis-cluster/bin/redis-server /data/redis-cluster/9003/redis.conf
/data/redis-cluster/bin/redis-server /data/redis-cluster/9004/redis.conf
/data/redis-cluster/bin/redis-server /data/redis-cluster/9005/redis.conf
/data/redis-cluster/bin/redis-server /data/redis-cluster/9006/redis.conf
现在检查一下是否成功开启,如下图所示,都开启成功。
ps -el | grep redis
此时的节点虽然都启动成功了,但他们还不在一个集群里面,不能互相发现,测试会报错:(error) CLUSTERDOWN Hash slot not served。
如下图所示
redis-cli --cluster create 10.32.176.80:9001 10.32.176.80:9002 10.32.176.80:9003 10.32.176.80:9004 10.32.176.80:9005 10.32.176.80:9006 --cluster-replicas 1
–cluster-replicas 1 这个指的是从机的数量,表示我们希望为集群中的每个主节点创建一个从节点。
红色选框是给三个主节点分配的共16384个槽点。
黄色选框是主从节点的分配情况。
蓝色选框是各个节点的详情。
现在通过客户端命令连接上,通过集群命令看一下状态和节点信息等
/data/redis-cluster/bin/redis-cli -c -h 10.32.176.80 -p 9001 cluster info cluster nodes
效果图如下,集群搭建成功。
现在往9001这个主节点写入一条信息,我们可以在9002这个主节点取到信息,集群间各个节点可以通信。
故障转移机制详解
集群中的节点会向其它节点发送PING消息(该PING消息会带着当前集群和节点的信息),如果在规定时间内,没有收到对应的PONG消息,就把此节点标记为疑似下线。当被分配了slot槽位的主节点中有超过一半的节点都认为此节点疑似下线(就是其它节点以更高的频次,更频繁的与该节点PING-PONG),那么该节点就真的下线。其它节点收到某节点已经下线的广播后,把自己内部的集群维护信息也修改为该节点已事实下线。
节点资格审查:然后对从节点进行资格审查,每个从节点检查最后与主节点的断线时间,如果该值超过配置文件的设置,那么取消该从节点的资格。准备选举时间:这里使用了延迟触发机制,主要是给那些延迟低的更高的优先级,延迟低的让它提前参与被选举,延迟高的让它靠后参与被选举。(延迟的高低是依据之前与主节点的最后断线时间确定的)
選舉投票:當從節點獲取選舉資格後,會向其他帶有slot槽位的主節點發起選舉請求,由它們進行投票,優先級越高的從節點就越有可能成為主節點,當從節點取得的票數到達一定數值時(如叢集內有N個主節點,那麼只要有一個從節點獲得了N/2 1的選票即認為勝出),就會替換成為主節點。
取代主節點:被選舉出來的從節點會執行slaveof no one把自己的狀態從slave變成master,然後執行clusterDelSlot操作撤銷故障主節點負責的槽,並執行clusterAddSlot把這些槽分配給自己,之後向叢集廣播自己的pong訊息,通知叢集內所有的節點,目前從節點已變成主節點。
接管相關操作:新的主節點接管了先前故障的主節點的槽訊息,接收和處理與自己槽位相關的命令請求。
故障轉移測試
這是先前叢集中具體節點的情況,我簡化成如下,可以向上回看圖片中的叢集資訊。
這裡關閉該9001埠的進程,即模擬該主節點掛掉。
登入掛掉的redis節點,會被拒絕服務,透過還在正常運作的某個主節點進入,然後再次查看叢集中的資訊
簡而言之,就是先前的叢集資訊變成瞭如下所示
#現在,我重啟剛才掛掉的主節點,重新查看叢集內部的節點情況,具體情況如下圖所示
簡而言之,現在叢集內的節點情況如下
推薦學習:Redis教學
以上是深入了解redis叢集方案(主從模式、哨兵模式、Redis Cluster模式)的詳細內容。更多資訊請關注PHP中文網其他相關文章!