1. 程式人生 > >Redis 備份、容災及高可用實戰

Redis 備份、容災及高可用實戰

作者介紹

郝朝陽,宜搜科技,運維工程師,負責前端運維工作。專注於運維自動化的實現。致力於DevOps思想的推廣,幫助企業形成形成自有文化的運維體系建設。

一、Redis簡單介紹

Redis是一個高效能的key-value非關係型資料庫,由於其具有高效能的特性,支援高可用、持久化、多種資料結構、叢集等,使其脫穎而出,成為常用的非關係型資料庫。

此外,Redis的使用場景也比較多。

  1. 會話快取(Session Cache)
    Redis快取會話有非常好的優勢,因為Redis提供持久化,在需要長時間保持會話的應用場景中,如購物車場景這樣的場景中能提供很好的長會話支援,能給使用者提供很好的購物體驗。
  2. 全頁快取

    在WordPress中,Pantheon提供了一個不錯的外掛wp-redis,這個外掛能以最快的速度載入你曾經瀏覽過的頁面。
  3. 佇列
    Reids提供list和set操作,這使得Redis能作為一個很好的訊息佇列平臺來使用。我們常通過Reids的佇列功能做購買限制。比如到節假日或者推廣期間,進行一些活動,對使用者購買行為進行限制,限制今天只能購買幾次商品或者一段時間內只能購買一次。也比較適合適用。
  4. 排名
    Redis在記憶體中對數字進行遞增或遞減的操作實現得非常好。所以我們在很多排名的場景中會應用Redis來進行,比如小說網站對小說進行排名,根據排名,將排名靠前的小說推薦給使用者。
  5. 釋出/訂閱
    Redis提供釋出和訂閱功能,釋出和訂閱的場景很多,比如我們可以基於釋出和訂閱的指令碼觸發器,實現用Redis的釋出和訂閱功能建立起來的聊天系統。

此外還有很多其它場景,Redis都表現的不錯。

二、Redis使用中單點故障問題

正是由於Redis具備多種優良特新,且應用場景非常豐富,以至於Redis在各個公司都有它存在的身影。那麼隨之而來的問題和風險也就來了。Redis雖然應用場景豐富,但部分公司在實踐Redis應用的時候還是相對保守使用單節點部署,那為日後的維護帶來了安全風險。

在2015年的時候,曾處理過一個因為單點故障原因導致的業務中斷問題。當時的Redis都未採用分散式部署,採用單例項部署,並未考慮容災方面的問題。

當時我們通過Redis伺服器做使用者購買優惠商品的行為控制,但後來由於未知原因Redis節點的伺服器宕機了,導致我們無法對使用者購買行為進行控制,造成了使用者能夠在一段時間內多次購買優惠商品的行為。

這種宕機事故可以說已經對公司造成了不可挽回的損失了,安全風險問題非常嚴重,作為當時運維這個系統的我來說有必要對這個問題進行修復和在架構上的改進。於是我開始瞭解決非分散式應用下Redis單點故障方面的研究學習。

三、非分散式場景下Redis應用的備份與容災

Redis主從複製現在應該是很普遍了。常用的主從複製架構有如下兩種架構方案。

常用Redis主從複製

  • 方案一

Redis這是最常見的一種架構,一個Master節點,兩個Slave節點。客戶端寫資料的時候是寫Master節點,讀的時候,是讀取兩個Slave,這樣實現讀的擴充套件,減輕了Master節點讀負載。

  • 方案二

Maste

  • 這種架構同樣是一個Master和兩個Slave。不同的是Master和Slave1使用keepalived進行VIP轉移。Client連線Master的時候是通過VIP進行連線的。避免了方案一IP更改的情況。

Redis主從複製優點與不足

  • 優點
  1. 實現了對master資料的備份,一旦master出現故障,slave節點可以提升為新的master,頂替舊的master繼續提供服務
  2. 實現讀擴充套件。使用主從複製架構, 一般都是為了實現讀擴充套件。Master主要實現寫功能,  Slave實現讀的功能
  • 不足
    架構方案一
    當Master出現故障時,Client就與Master端斷開連線,無法實現寫功能,同時Slave也無法從Master進行復制。

架構

此時需要經過如下操作(假設提升Slave1為Master):

  1. 在Slave1上執slaveof no one命令提升Slave1為新的Master節點。
  2. 在Slave1上配置為可寫,這是因為大多數情況下,都將slave配置只讀。
  3. 告訴Client端(也就是連線Redis的程式)新的Master節點的連線地址。
  4. 配置Slave2從新的Master進行資料複製。

架構方案二
當master出現故障後,Client可以連線到Slave1上進行資料操作,但是Slave1就成了一個單點,就出現了經常要避免的單點故障(single point of failure)。

之後需要經過如下操作:

  1. 在Slave1上執行slaveof no one命令提升Slave1為新的Master節點
  2. 在Slave1上配置為可寫,這是因為大多數情況下,都將Slave配置只讀
  3. 配置Slave2從新的Master進行資料複製

可以發現,無論是哪種架構方案都需要人工干預來進行故障轉移(failover)。需要人工干預就增加了運維工作量,同時也對業務造成了巨大影響。這時候可以使用Redis的高可用方案-Sentinel

四、Redis Sentinel介紹

Redis Sentinel為Redis提供了高可用方案。從實踐方面來說,使用Redis Sentinel可以建立一個無需人為干預就可以預防某些故障的Redis環境。
Redis Sentinel設計為分散式的架構,執行多個Sentinel程序來共同合作的。執行多個Sentinel程序合作,當多個Sentinel同一給定的master無法再繼續提供服務,就會執行故障檢測,這會降低誤報的可能性。

五、Redis Sentinel功能

Redis Sentinel在Redis高可用方案中主要作用有如下功能:

  • 監控
    Sentinel會不斷的檢查master和slave是否像預期那樣正常執行
  • 通知
    通過API,Sentinel能夠通知系統管理員、程式監控的Redis例項出現了故障
  • 自動故障轉移
    如果master不像預想中那樣正常執行,Sentinel可以啟動故障轉移過程,其中的一個slave會提成為master,其它slave會重新配置來使用新的master,使用Redis服務的應用程式,當連線時,也會被通知使用新的地址。
  • 配置提供者
    Sentinel可以做為客戶端服務發現的認證源:客戶端連線Sentinel來獲取目前負責給定服務的Redis master地址。如果發生故障轉移,Sentinel會報告新的地址。

六、Redis Sentinel架構

Redis

七、Redis Sentinel實現原理

Sentinel叢集對自身和Redis主從複製進行監控。當發現Master節點出現故障時,會經過如下步驟:

  • 1)Sentinel之間進行選舉,選舉出一個leader,由選舉出的leader進行failover
  • 2)Sentinel leader選取slave節點中的一個slave作為新的Master節點。對slave選舉需要對slave進行選舉的方法如下:a) 與master斷開時間
    如果與master斷開的時間超過down-after-milliseconds(sentinel配置) * 10秒加上從sentinel判定master不可用到sentinel開始執行故障轉移之間的時間,就認為該slave不適合提升為master。

    b) slave優先順序
    每個slave都有優先順序,儲存在redis.conf配置檔案裡。如果優先順序相同,則繼續進行。

    c) 複製偏移位置
    複製偏移紀錄著從master複製資料複製到哪裡,複製偏移越大表明從master接受的資料越多,如果複製偏移量也一樣,繼續進行選舉

    d) Run ID
    選舉具有最小Run ID的Slave作為新的Master
    流程圖如下:

  • 3)  Sentinel leader會在上一步選舉的新master上執行slaveof no one操作,將其提升為master節點
  • 4)Sentinel leader向其它slave傳送命令,讓剩餘的slave成為新的master節點的slave
  • 5)Sentinel leader會讓原來的master降級為slave,當恢復正常工作,Sentinel leader會發送命令讓其從新的master進行復制
    以上failover操作均有sentinel自己獨自完成,完全無需人工干預。

總結

使用sentinel實現了Redis的高可用,當master出現故障時,完全無需人工干預即可實現故障轉移。避免了對業務的影響,提高了運維工作效率。
在部署sentinel的時候,建議使用奇數個sentinel節點,最少三個sentinel節點。

寫在最後

由於sentinel知識點比較多,這裡僅給大家進行介紹,讓大家有個瞭解,想了解更多可與我聯絡。謝謝。