1. 程式人生 > >Redis 實戰搭建高可用架構

Redis 實戰搭建高可用架構

前言:最近在看關於redis快取方面的知識,今天就來個 Redis sentinel 高可用架構,實戰開始之前,先看看sentinel的概念

 

什麼是redis-sentinel

  Redis-Sentinel是Redis官方推薦的高可用性(HA)解決方案,當用Redis做Master-slave的高可用方案時,假如master宕機了,
Redis本身(包括它的很多客戶端)都沒有實現自動進行主備切換,而Redis-sentinel本身也是一個獨立執行的程序,它能監控多個master-slave叢集,發現master宕機後能進行自動切換。

 

為什麼使用sentinel服務

  redis的普通主從模式中,當主資料庫遇到異常中斷服務後,開發者可以通過手動的方式選擇一個從資料庫來升格為主資料庫,以使得系統能夠繼續提供服務。然而整個過程相對麻煩且需要人工介入,難以實現自動化。 
為此,Redis 2.8開始提供了哨兵工具來實現自動化的系統監控和故障恢復功能。 哨兵的作用就是監控redis主、從資料庫是否正常執行,主出現故障自動將從資料庫轉換為主資料庫。

 

一、首先實現主從複製(一主多從)

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

這裡,我們把redis.conf作為master,slave_1.conf和slave_2.conf為從


  1、找到redis.conf,複製出2份(我只有一個伺服器,所以通過改變埠來實現)

  

  2、修改以下幾項配置

1、埠號:
        slave_1.conf:6380
        slave_2.conf:6381

2、繫結
        slave_1.conf:slaveof 127.0.0.1 6379
        slave_2.conf:slaveof 127.0.0.1 6379

3、密碼(最好跟master一致)
        slave_1.conf:requirepass 123456
    slave_2.conf:requirepass 123456

4、驗證密碼(從機對主機驗證時,所需的密碼)
     slave_1.conf:masterauth 123456
      slave_2.conf:masterauth 123456

   

  

  

  

  3、啟動主機和從機

   

  

  4、驗證結果

  master:

  

  slave_1:

  

  slave_2:

   

  5、流程圖

 

可以看到主機執行寫命令,從機能同步主機的值,主從複製就實現了。

注意:預設情況下從庫是隻讀的,不能進行修改,需要修改需要設定配置檔案中的slave-read-only為no。在命令列裡執行slaveof no one可以讓一個從庫變成主庫。

問題:當主伺服器掛了怎麼辦

 

二、引入sentinel(哨兵)模式

特點:
    1、不時地監控redis是否按照預期良好地執行;
    2、如果發現某個redis節點執行出現狀況,能夠通知另外一個程序(例如它的客戶端);
    3、能夠進行自動切換。當一個master節點不可用時,能夠選舉出master的多個slave(如果有超過一個slave的話)中的一個來作為新的master,
    其它的slave節點會將它所追隨的master的地址改為被提升為master的slave的新地址。

  單點sentinel示意圖

  叢集sentinel示意圖(防止單點故障)

  

   1、找到sentinel.conf檔案

1、找到sentinel.conf檔案,預設在redis原始碼包裡
2、複製sentinel.conf檔案到redis.conf同級目錄

  2、配置sentinel.conf

說明:我這裡是單個sentinel,叢集sentinel下面方法也通用

1、port : 當前Sentinel服務執行的埠(注意:多個sentinel,記得修改埠號) 2、dir : Sentinel服務執行時使用的臨時資料夾 3、sentinel monitor master001 192.168.110.101 6379 2:Sentinel去監視一個名為master001的主redis例項,這個主例項的IP地址為本機地址192.168.110.101,埠號為6379,
                                而將這個主例項判斷為失效至少需要2個 Sentinel程序的同意(注意:如果是單個sentinel,這裡就是1),只要同意Sentinel的數量不達標,
                                自動failover就不會執行
4、sentinel auth-pass mymaster 123456:設定連線master和slave時的密碼,注意的是sentinel不能分別為master和slave設定不同的密碼,因此master和slave的密碼應該設定相同。
4、sentinel down-after-milliseconds master001 30000:指定了Sentinel認為Redis例項已經失效所需的毫秒數。當例項超過該時間沒有返回PING,或者直接返回錯誤,那麼Sentinel將這個例項標記為主觀下線。
                                只有一個 Sentinel程序將例項標記為主觀下線並不一定會引起例項的自動故障遷移:只有在足夠數量的Sentinel都將一個例項標記為主觀下線之後,
                                例項才會被標記為客觀下線,這時自動故障遷移才會執行 5、sentinel parallel-syncs master001 1:指定了在執行故障轉移時,最多可以有多少個從Redis例項在同步新的主例項,在從Redis例項較多的情況下這個數字越小,同步的時間越長,完成故障轉移所需的時間就越長 6、sentinel failover-timeout master001 180000:如果在該時間(ms)內未能完成failover操作,則認為該failover失敗 7、sentinel notification-script <master-name> <script-path>:指定sentinel檢測到該監控的redis例項指向的例項異常時,呼叫的報警指令碼。該配置項可選,但是很常用

  3、啟動sentinel

命令:redis-sentinel  sentinel.conf

說明:redis-sentinel  path (sentinel的配置檔案路徑) + filename (檔名)

多個sentinel也一樣,只需修改filename就行

  

  啟動後會在控制檯看到如下資訊

  

  4、測試sentinel自動切換功能

    1、停止主節點(埠為6379)

     

     2、檢視slave節點(埠為6380,6381)

    

    

    可以看到,已經成功切換了

    3、恢復主節點(master)

    

    之前的主節點變成了slave

   5、啟動中碰到的問題

1、redis啟動警告問題:WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
  原因:對一個高負載的環境來說tcp設定128這個值,太小了。 
  解決:
      1、臨時:執行  echo 511 > /proc/sys/net/core/somaxconn
      2、永久:開啟ietc/sysctl.conf,在這裡面添net.core.somaxconn= 1024 然後執行sysctl -p 就可以永久消除這個warning

2、在控制檯info中沒看到* +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379這類的資訊,
  而是這個sdown master mymaster 127.0.0.1 6379,Next failover delay: I will not start a failover之類的   原因:沒有設定master連線密碼   解決:在sentinel.conf上設定 sentinel auth-pass mymaster password(master密碼)

3、啟動sentinel出現:*** FATAL CONFIG FILE ERROR *** Reading the configuration file, at line 104 'sentinel auth-pass mymaster redis' No such master with specified name.
  原因:這是因為設定sentinel auth-pass的時候沒有在sentinel monitor mymaster ... 的下面
  解決:設定在sentinel monitor mymaster ... 的下面就行了

   說明:我上面的例子中,只用了單個sentinel,這會存在單點故障問題。這點需要注意

 

三、官方提供的叢集高可用架構(redis-cluster)

前言:關於redis-cluster,這裡就不實際操作了,有興趣的小夥伴可以自己去試試。

  1、這裡簡單說說redis-cluster的作用   

  即使使用哨兵,redis每個例項也是全量儲存,每個redis儲存的內容都是完整的資料,浪費記憶體且有木桶效應。
為了最大化利用記憶體,可以採用cluster群集,就是分散式儲存。即每臺redis儲存不同的內容。 採用redis-cluster架構正是滿足這種分散式儲存要求的叢集的一種體現。redis-cluster架構中,被設計成共有16384個hash slot。
每個master分得一部分slot,其演算法為:hash_slot = crc16(key) mod 16384 ,這就找到對應slot。採用hash slot的演算法,
實際上是解決了redis-cluster架構下,有多個master節點的時候,資料如何分佈到這些節點上去。
key是可用key,如果有{}則取{}內的作為可用key,否則整個可以是可用key。群集至少需要3主3從,且每個例項使用不同的配置檔案。

  示意圖

  

  2、redis-cluster架構說明

  在cluster架構下,預設的,一般redis-master用於接收讀寫,而redis-slave則用於備份,當有請求是在向slave發起時,會直接重定向到對應key所在的master來處理。
但如果不介意讀取的是redis-cluster中有可能過期的資料並且對寫請求不感興趣時,則亦可通過readonly命令,將slave設定成可讀,然後通過slave獲取相關的key,達到讀寫分離。

  3、注意事項

(1)redis-cluster最小配置為三主三從,當1個主故障,大家會給對應的從投票,把從立為主,若沒有從資料庫可以恢復則redis群集就down了。

(2)在這個redis cluster中,如果你要在slave讀取資料,那麼需要帶上readonly指令。redis cluster的核心的理念,主要是用slave做高可用的,
   每個master掛一兩個slave,主要是做資料的熱備,當master故障時的作為主備切換,實現高可用的。redis cluster預設是不支援slave節點讀或者寫的,
   跟我們手動基於replication搭建的主從架構不一樣的。slave node要設定readonly,然後再get,這個時候才能在slave node進行讀取。對於redis -cluster主從架構,
   若要進行讀寫分離,官方其實是不建議的,但也能做,只是會複雜一些。 (3)redis-cluster的架構下,實際上本身master就是可以任意擴充套件的,你如果要支撐更大的讀吞吐量,或者寫吞吐量,或者資料量,都可以直接對master進行橫向擴充套件就可以了。
   也擴容master,跟之前擴容slave進行讀寫分離,效果是一樣的或者說更好。 (4)可以使用自帶客戶端連線:使用redis-cli -c -p cluster中任意一個埠,進行資料獲取測試。

 

以上就是全部內容了,sentinel模式為本人