您好,登錄后才能下訂單哦!
這篇文章主要講解了“Redis集群與擴展知識點分析”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Redis集群與擴展知識點分析”吧!
防止單點故障,造成整個集群不可用
實現高可用通常的做法是將數據庫復制多個副本以部署在不同的服務器上,其中一臺掛了也可以繼續提供服務
Redis實現高可用有三種部署模式:主從模式,哨兵模式,集群模式
主節點負責讀寫操作
從節點只負責讀操作
從節點的數據來自主節點,實現原理就是主從復制機制
主從復制包括全量復制,增量復制兩種
當slave第一次啟動連接master,或者認為是第一次連接就采用全量復制
slave與master全量同步之后,master上的數據如果再次發生更新,就會觸發增量復制
主從模式中,一旦主節點由于故障不能提供服務,需要人工將從節點晉升為主節點,同時還要通知應用方更新主節點地址,顯然多數業務場景都不能接受這種故障處理方式,Redis從2.8開始正式提供了Redis Sentinel(哨兵)架構來解決這個問題
哨兵模式是由一個或多個Sentinel實例組成的Sentinel系統,可以監視所有的Redis主節點和從節點,并在被監視的主節點進入下線狀態時自動將下線主服務器屬下的某個從節點升級為新的主節點
但是一個哨兵進程對Redis節點進行監控,就可能會出現問題(單點),因此可以使用多個哨兵來進行監控Redis節點,并且各個哨兵之間還會進行監控
簡單來說,哨兵模式就三個作用
1.發送命令,等待Redis服務器(包括主服務器和從服務器)返回監控其運行狀態 2.哨兵監測到主節點宕機會自動將從節點切換成主節點,然后通過發布訂閱模式通知其他的從節點修改配置文件,讓它們切換主機 3.哨兵之間還會相互監控,從而達到高可用
故障切換過程如下
假設主服務器宕機,哨兵1先檢測到這個結果,系統并不會馬上進行 failover 過程,僅僅是哨兵1主觀的認為主服務器不可用,這個現象稱為主觀下線 當后面的哨兵也檢測到主服務器不可用并且數量達到一定值時,那么哨兵之間就會進行一次投票,投票的結果由一個哨兵發起,進行failover操作 切換成功后通過發布訂閱模式,讓各個哨兵把自己監控的從服務器實現切換主機,這個過程稱為客觀下線 這樣對于客戶端而言,一切都是透明的
哨兵的工作模式
每個Sentinel以每秒鐘一次的頻率向它所知的Master,Slave以及其他Sentinel實例發送一個PING命令 如果實例距離最后一次有效回復PING命令的時間超過down-after-milliseconds選項所指定的值,則這個實例會被Sentinel標記為主觀下線 如果一個Master被標記為主觀下線,則正在監視這個Master的所有Sentinel要以每秒一次的頻率確認Master的確進入了主觀下線狀態 當有足夠數量的Sentinel(大于等于配置文件指定的值)在指定的時間范圍內確認Master的確進入了主觀下線狀態,則Master會被標記為客觀下線 一般情況下,每個Sentinel會以每10秒一次的頻率向它已知的所有Master,Slave發送INFO命令 當Master被Sentinel標記為客觀下線時,Sentinel向下線的Master的所有Slave發送INFO命令的頻率會從10秒一次改為每秒一次 若沒有足夠數量的Sentinel同意Master已經下線,Master的客觀下線狀態就會被移除;若Master重新向Sentinel的PING命令返回有效回復,Master 的主觀下線狀態就會被移除
哨兵模式基于主從模式,實現讀寫分離,還可以自動切換,系統可用性更高,但是它每個節點存儲的數據是一樣的,浪費內存,并且不好在線擴容,因此Cluster集群應運而生,它在Redis3.0加入的
Cluster集群實現Redis的分布式存儲,對數據進行分片,也就是說每臺Redis節點上存儲不同的內容,來解決在線擴容的問題,并且它也提供復制和故障轉移的功能
Redis Cluster集群通過Gossip協議進行通信,節點之間不斷交換信息,交換的信息內容包括節點出現故障、新節點加入、主從節點變更信息、slot信息等等,常用的Gossip消息分別是ping、pong、meet、fail
ping消息:集群內交換最頻繁的消息,集群內每個節點每秒向多個其他節點發送ping消息,用于檢測節點是否在線和交換彼此狀態信息 meet消息:通知新節點加入,消息發送者通知接收者加入到當前集群,meet消息通信正常完成后,接收節點會加入到集群中并進行周期性的ping、pong消息交換 pong消息:當接收到ping、meet消息時,作為響應消息回復給發送方確認消息正常通信;pong消息內部封裝了自身狀態數據,節點也可以向集群內廣播自身的pong消息來通知整個集群對自身狀態進行更新 fail消息:當節點判定集群內另一個節點下線時,會向集群內廣播一個fail消息,其他節點接收到fail消息之后把對應節點更新為下線狀態
Hash Slot插槽算法
既然是分布式存儲,Cluster集群使用的分布式算法是一致性Hash嘛?并不是,而是Hash Slot插槽算法 插槽算法把整個數據庫被分為16384個slot(槽),每個進入Redis的鍵值對根據key進行散列,分配到這16384插槽中的一個 使用的哈希映射也比較簡單,用CRC16算法計算出一個16位的值,再對16384取模,數據庫中的每個鍵都屬于這16384個槽的其中一個,集群中的每個節點都可以處理這16384個槽 集群中的每個節點負責一部分的hash槽,比如當前集群有A、B、C個節點,每個節點上的哈希槽數 =16384/3,那么就有: 節點A負責0~5460號哈希槽 節點B負責5461~10922號哈希槽 節點C負責10923~16383號哈希槽Redis Cluster集群中,需要確保16384個槽對應的node都正常工作,如果某個node出現故障,它負責的slot也會失效,整個集群將不能工作 為了保證高可用,Cluster集群引入了主從復制,一個主節點對應一個或者多個從節點,當其它主節點ping一個主節點A時,如果半數以上的主節點與 A通信超時,那么認為主節點A宕機,如果主節點宕機時,就會啟用從節點Redis的每一個節點上都有兩個玩意,一個是插槽slot(0~16383),另外一個是cluster,可以理解為一個集群管理的插件,當我們存取的key到達時,Redis會根據Hash Slot插槽算法取到編號在0~16383之間的哈希槽,通過這個值去找到對應的插槽所對應的節點,然后直接自動跳轉到這個對應的節點上進行存取操作
主觀下線: 某個節點認為另一個節點不可用,即下線狀態,這個狀態并不是最終的故障判定,只能代表一個節點的意見,可能存在誤判情況
客觀下線: 標記一個節點真正的下線,集群內多個節點都認為該節點不可用,從而達成共識的結果,如果是持有槽的主節點故障,需要為該節點進行故障轉移
故障恢復:故障發現后,如果下線節點的是主節點,則需要在它的從節點中選一個替換它,以保證集群的高可用
分布式鎖可能存在鎖過期釋放,業務沒執行完的問題
能不能將鎖的過期時間設置得長點來解決此問題呢?顯然是不太好的,業務的執行時間是不確定的
Redisson解決該問題,給獲得鎖得線程開啟定時守護線程,每隔一段時間檢查鎖是否存在,存在則延長鎖的過期時間,防止鎖過期提前釋放
線程一在Redis的master節點上拿到了鎖,但是加鎖的key還沒同步到slave節點,恰好這時master節點發生故障,一個slave節點就會升級為master節點,線程二就可以獲取同個key的鎖啦,但線程一也已經拿到鎖了,鎖的安全性就沒了
Redlock解決這個問題,即部署多個Redis master以保證它們不會同時宕掉,并且這些master節點是完全相互獨立的,相互之間不存在數據同步,實現步驟如下
更新數據庫后延遲休眠一會再刪除緩存
這種方案還可以,只有休眠那一會可能有臟數據,一般業務也會接受的
但是如果第二次刪除緩存失敗呢?緩存和數據庫的數據還是可能不一致
給Key設置一個自然的expire過期時間,讓它自動過期怎樣?業務在該過期時間內接受的數據的不一致怎么辦?還是有其他更佳方案
延時雙刪可能會存在第二步的刪除緩存失敗,導致的數據不一致問題
刪除失敗就多刪除幾次呀,保證刪除緩存成功就可以了呀,所以可以引入刪除緩存重試機制
重試刪除緩存機制會造成好多業務代碼入侵,所以引入讀取biglog異步刪除緩存
感謝各位的閱讀,以上就是“Redis集群與擴展知識點分析”的內容了,經過本文的學習后,相信大家對Redis集群與擴展知識點分析這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。