1. 程式人生 > 實用技巧 >Redis ==> 叢集的三種模式

Redis ==> 叢集的三種模式

一、主從同步/複製

  通過持久化功能,Redis保證了即使在伺服器重啟的情況下也不會丟失(或少量丟失)資料,因為持久化會把記憶體中資料儲存到硬碟上,重啟會從硬碟上載入資料。但是由於資料是儲存在一臺伺服器上的,如果這臺伺服器出現硬碟故障等問題,也會導致資料丟失。

  為了避免單點故障,通常的做法是將資料庫複製多個副本以部署在不同的伺服器上,這樣即使有一臺伺服器出現故障,其他伺服器依然可以繼續提供服務。為此,Redis 提供了複製(replication)功能,可以實現當一臺資料庫中的資料更新後,自動將更新的資料同步到其他資料庫上

  在複製的概念中,資料庫分為兩類,一類是主資料庫(master),另一類是從資料庫(slave)。主資料庫可以進行讀寫操作,當寫操作導致資料變化時會自動將資料同步給從資料庫。而從資料庫一般是隻讀的,並接受主資料庫同步過來的資料

。一個主資料庫可以擁有多個從資料庫,而一個從資料庫只能擁有一個主資料庫。

主從資料庫的配置:

  主資料庫不用配置,從資料庫的配置檔案(redis.conf)中可以載入主資料庫的資訊,也可以在啟動時,使用 redis-server --port 6380 --slaveof 127.0.0.1 6379 命令指明主資料庫的 IP 和埠。從資料庫一般是隻讀,可以改為可寫,但寫入的資料很容易被主同步沒,所以還是隻讀就可以。也可以在執行時使用 slaveof ip port 命令,停止原來的主,切換成剛剛設定的主 slaveof no one會把自己變成主。

主從複製原理:

  • 從資料庫連線主資料庫,傳送SYNC命令;
  • 主資料庫接收到SYNC命令後,開始執行BGSAVE命令生成RDB檔案並使用緩衝區記錄此後執行的所有寫命令;
  • 主資料庫BGSAVE執行完後,向所有從資料庫傳送快照檔案,並在傳送期間繼續記錄被執行的寫命令;
  • 從資料庫收到快照檔案後丟棄所有舊資料,載入收到的快照;
  • 主資料庫快照發送完畢後開始向從資料庫傳送緩衝區中的寫命令;
  • 從資料庫完成對快照的載入,開始接收命令請求,並執行來自主資料庫緩衝區的寫命令;(從資料庫初始化完成
  • 主資料庫每執行一個寫命令就會向從資料庫傳送相同的寫命令,從資料庫接收並執行收到的寫命令(從資料庫初始化完成後的操作
  • 出現斷開重連後,2.8之後的版本會將斷線期間的命令傳給重資料庫,增量複製。
  • 主從剛剛連線的時候,進行全量同步;全同步結束後,進行增量同步。當然,如果有需要,slave 在任何時候都可以發起全量同步。Redis 的策略是,無論如何,首先會嘗試進行增量同步,如不成功,要求從機進行全量同步。

優點:

  • 支援主從複製,主機會自動將資料同步到從機,可以進行讀寫分離;
  • 為了分載Master的讀操作壓力,Slave伺服器可以為客戶端提供只讀操作的服務,寫服務仍然必須由Master來完成;
  • Slave同樣可以接受其它Slaves的連線和同步請求,這樣可以有效的分載Master的同步壓力;
  • Master Server是以非阻塞的方式為Slaves提供服務。所以在Master-Slave同步期間,客戶端仍然可以提交查詢或修改請求;
  • Slave Server同樣是以非阻塞的方式完成資料同步。在同步期間,如果有客戶端提交查詢請求,Redis則返回同步之前的資料;

缺點:

  • Redis不具備自動容錯和恢復功能,主機從機的宕機都會導致前端部分讀寫請求失敗,需要等待機器重啟或者手動切換前端的IP才能恢復;
  • 主機宕機,宕機前有部分資料未能及時同步到從機,切換IP後還會引入資料不一致的問題,降低了系統的可用性;
  • 如果多個Slave斷線了,需要重啟的時候,儘量不要在同一時間段進行重啟。因為只要Slave啟動,就會發送sync請求和主機全量同步,當多個 Slave 重啟的時候,可能會導致 Master IO劇增從而宕機。
  • Redis較難支援線上擴容,在叢集容量達到上限時線上擴容會變得很複雜;

二、哨兵模式

  第一種主從同步/複製的模式,當主伺服器宕機後,需要手動把一臺從伺服器切換為主伺服器,這就需要人工干預,費事費力,還會造成一段時間內服務不可用。這不是一種推薦的方式,更多時候,我們優先考慮哨兵模式。

  哨兵模式是一種特殊的模式,首先Redis提供了哨兵的命令,哨兵是一個獨立的程序,作為程序,它會獨立執行。其原理是哨兵通過傳送命令,等待Redis伺服器響應,從而監控執行的多個Redis例項。

哨兵模式的作用:

  • 通過傳送命令,讓Redis伺服器返回監控其執行狀態,包括主伺服器和從伺服器;
  • 當哨兵監測到master宕機,會自動將slave切換成master,然後通過釋出訂閱模式通知其他的從伺服器,修改配置檔案,讓它們切換主機;

然而一個哨兵程序對Redis伺服器進行監控,也可能會出現問題,為此,我們可以使用多個哨兵進行監控。各個哨兵之間還會進行監控,這樣就形成了多哨兵模式。

故障切換的過程:

  假設主伺服器宕機,哨兵1先檢測到這個結果,系統並不會馬上進行 failover 過程,僅僅是哨兵1主觀的認為主伺服器不可用,這個現象成為主觀下線。當後面的哨兵也檢測到主伺服器不可用,並且數量達到一定值時,那麼哨兵之間就會進行一次投票,投票的結果由一個哨兵發起,進行 failover 操作。切換成功後,就會通過釋出訂閱模式,讓各個哨兵把自己監控的從伺服器實現切換主機,這個過程稱為客觀下線。這樣對於客戶端而言,一切都是透明的。

哨兵模式的配置:

配置一主二從和三個哨兵的 Redis 伺服器來演示這個過程

主從伺服器配置

# 使得Redis伺服器可以跨網路訪問
bind 0.0.0.0

# 設定密碼
requirepass "123456"

# 以下有關slaveof的配置只是配置從伺服器,主伺服器不需要配置
# 指定主伺服器
slaveof 192.168.11.128 6379
# 主伺服器密碼
masterauth 123456

哨兵配置

# 禁止保護模式
protected-mode no
# 配置監聽的主伺服器,這裡sentinel monitor代表監控,mymaster代表伺服器的名稱,可以自定義,192.168.11.128代表監控的主伺服器,6379代表埠,2代表只有兩個或兩個以上的哨兵認為主伺服器不可用的時候,才會進行failover操作。
sentinel monitor mymaster 192.168.11.128 6379 2
# sentinel author-pass定義服務的密碼,mymaster是服務名稱,123456是Redis伺服器密碼
# sentinel auth-pass <master-name> <password>
sentinel auth-pass mymaster 123456

配置3個哨兵,每個哨兵的配置都是一樣的。在Redis安裝目錄下有一個sentinel.conf檔案,copy一份進行修改

啟動

注意啟動的順序。首先是主機(192.168.11.128)的 Redis 服務程序,然後啟動從機的 Redis 服務程序,最後啟動3個哨兵的服務程序。

哨兵模式的工作方式:

  • 每個Sentinel(哨兵)程序以每秒鐘一次的頻率向整個叢集中的Master主伺服器,Slave從伺服器以及其他Sentinel(哨兵)程序傳送一個 PING 命令。
  • 如果一個例項(instance)距離最後一次有效回覆 PING 命令的時間超過 down-after-milliseconds 選項所指定的值, 則這個例項會被 Sentinel(哨兵)程序標記為主觀下線(SDOWN)
  • 如果一個Master主伺服器被標記為主觀下線(SDOWN),則正在監視這個Master主伺服器的所有 Sentinel(哨兵)程序要以每秒一次的頻率確認Master主伺服器的確進入了主觀下線狀態
  • 當有足夠數量的 Sentinel(哨兵)程序(大於等於配置檔案指定的值)在指定的時間範圍內確認Master主伺服器進入了主觀下線狀態(SDOWN), 則Master主伺服器會被標記為客觀下線(ODOWN)
  • 在一般情況下, 每個 Sentinel(哨兵)程序會以每 10 秒一次的頻率向叢集中的所有Master主伺服器、Slave從伺服器傳送 INFO 命令。
  • 當Master主伺服器被 Sentinel(哨兵)程序標記為客觀下線(ODOWN)時,Sentinel(哨兵)程序向下線的 Master主伺服器的所有 Slave從伺服器傳送 INFO 命令的頻率會從 10 秒一次改為每秒一次。
  • 若沒有足夠數量的 Sentinel(哨兵)程序同意 Master主伺服器下線, Master主伺服器的客觀下線狀態就會被移除。若 Master主伺服器重新向 Sentinel(哨兵)程序傳送 PING 命令返回有效回覆,Master主伺服器的主觀下線狀態就會被移除。

優點:

  • 哨兵模式是基於主從模式的,所有主從的優點,哨兵模式都具有。
  • 主從可以自動切換,系統更健壯,可用性更高。

缺點:

  • Redis較難支援線上擴容,在叢集容量達到上限時線上擴容會變得很複雜。

三、Cluster 叢集

  Redis 的哨兵模式基本已經可以實現高可用,讀寫分離 ,但是在這種模式下每臺 Redis 伺服器都儲存相同的資料,很浪費記憶體,所以在redis3.0上加入了 Cluster 叢集模式,實現了 Redis 的分散式儲存,也就是說每臺 Redis 節點上儲存不同的內容。

叢集的配置

根據官方推薦,叢集部署至少要 3 臺以上的master節點,最好使用 3 主 3 從六個節點的模式。在測試環境中,只能在一臺機器上面開啟6個服務例項來模擬。

1、修改配置檔案

將 redis.conf 的配置檔案複製6份(檔名最好加上埠字尾),然後開始修改配置檔案中的引數

#開啟redis的叢集模式
cluster-enabled yes

#配置叢集模式下的配置檔案
cluster-config-file nodes-6379.conf

#叢集內節點之間支援最長響應時間
cluster-node-timeout 15000

2、修改完畢之後啟動 6 個 Redis 服務

3、快速部署叢集

6個 Redis 服務啟動成功之後,藉助 redis-tri.rb 工具可以快速的部署叢集,如果本機沒有該命令列需要自行安裝,只需要執行/redis-trib.rb create --replicas 1 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384 127.0.0.1:6385 就可以成功建立叢集。

建立叢集可能會出現的錯誤

#這是由於建立叢集中的某一個服務中曾經插入過資料,並且已經產生了持久化檔案,此時需要flushall命令清空所有資料
[ERR] Node 127.0.0.1:6380 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0

#這是由於之前建立叢集遺留的配置檔案導致的問題,使用命令cluster reset即可
redis-4.1.0/lib/redis/client.rb:124:in `call': ERR Slot 935 is already busy

叢集的部署會在後續的文章中進行詳細的說明和測試,這裡就不詳細說明了

叢集的特點

  • 所有的redis節點彼此互聯(PING-PONG機制),內部使用二進位制協議優化傳輸速度和頻寬。

  • 節點的fail是通過叢集中超過半數的節點檢測失效時才生效。

  • 客戶端與 Redis 節點直連,不需要中間代理層.客戶端不需要連線叢集所有節點,連線叢集中任何一個可用節點即可。

叢集的工作方式

  在 Redis 的每一個節點上,都有這麼兩個東西,一個是插槽(slot),它的的取值範圍是:0-16383。還有一個就是cluster,可以理解為是一個叢集管理的外掛。當我們的存取的 Key到達的時候,Redis 會根據 crc16的演算法得出一個結果,然後把結果對 16384 求餘數,這樣每個 key 都會對應一個編號在 0-16383 之間的雜湊槽,通過這個值,去找到對應的插槽所對應的節點,然後直接自動跳轉到這個對應的節點上進行存取操作。

  為了保證高可用,redis-cluster叢集引入了主從模式,一個主節點對應一個或者多個從節點,當主節點宕機的時候,就會啟用從節點。當其它主節點ping一個主節點A時,如果半數以上的主節點與A通訊超時,那麼認為主節點A宕機了。如果主節點A和它的從節點A1都宕機了,那麼該叢集就無法再提供服務了。

轉載:https://www.cnblogs.com/L-Test/p/11626124.html