jinfeng_wang

          G-G-S,D-D-U!

          BlogJava 首頁 新隨筆 聯系 聚合 管理
            400 Posts :: 0 Stories :: 296 Comments :: 0 Trackbacks
          http://www.tuicool.com/articles/beYZfi7

          引言

          高可用(High Available)是線上生產環境所必不可少的重要條件,阿里云數據庫Redis版作為一款成熟穩定的數據庫產品,針對Redis的特性也支持高可用,本文將介紹云Redis是如何實現這一方案。

          架構

          目前云Redis有主從版和集群版兩種架構,本次主要針對主從版做HA的解析,集群版HA只在最后切換VIP指向時稍有不同,但均可保證高可用性。

          下圖為主從版架構:

          由圖可知,云Redis實例有主備兩個節點,平時只有Master提供服務,Slave只做熱備不提供訪問,Slave通過slaveof命令不斷從Master接收數據,保證Master宕機時云Redis仍可提供服務。

          每一個云Redis實例都會分配一個VIP并與DNS綁定,VIP經過SLB后直接訪問Master不再有其他中間層,訪問Redis的鏈路為DNS-->VIP-->SLB-->REDIS(MASTER)。

          HA模塊

          HA作為一個獨立的系統模塊,遠程探測云Redis的健康狀況,當發生實例不可用時及時主備切換以保證服務質量。

          健康檢查

          健康檢查的邏輯很簡單,通過客戶端連接Redis并發送PING命令,如果返回PONG則說明Redis健康,其他情況則說明Redis異常,檢測邏輯用偽代碼來說明:

          try:     client = Redis(ip, port, connection_timeout, socket_timeout)     //指定要連接Redis的ip:port(這里的ip:port即可以是VIP:VPORT也可以是Master或Slave的物理ip:port,HA會有多維度的探測),并設置超時時間     client.connect()     //嘗試連接Redis,如果連接失敗或超時則會拋出異常     res = client.ping()     //向Redis發送ping命令,結果為PONG說明Redis健康,返回OK;結果非PONG或超時則會拋出異常     if res == PONG:         return OK except:     //處理異常情況,若異常在預先定義的錯誤內,說明Redis真的異常,返回ERROR,HA會做下一步切換動作     if e.message in ERRORS:         return ERROR     else:         return OK

          需要HA真正做切換的異常情況有以下幾種:

          /* 指定ip地址的機器不能找到(也就是說從當前機器不存在到指定ip路由),或者是該ip存在,但找不到指定的端口進行監聽,這時Redis所在主機可能宕機或是進程掛掉 */ "Connection refused"     /* 服務器的并發連接數超過了其承載量,服務器會將其中一些連接主動Down掉 */ "Connection reset" /* 連接超時,目前設置為18秒 */ "connect timed out" /* 讀取數據超時,目前設置為2分鐘 */ "Read timed out" /* Redis正在加載數據 */ "LOADING Redis is loading the dataset in memory" /* 訪問的Redis是Slave */ "READONLY You can't write against a read only slave"

          關于為何將讀超時設置為2分鐘這么久呢,這是我們在日常運維處理各種問題時,根據總結出來的經驗設置的一個相對合理的大小。

          在一開始時讀超時的時間設置的和連接超時同樣為18秒,結果線上經常會有HA發生主備切換,這是因為Redis處理客戶端命令的線程只有一個,當在處理一些耗時操作比如FLUSHALL、KEYS等命令時,執行時間可達數十秒甚至幾分鐘,此時Redis處于"假死"狀態造成誤切換。經測試,清空64G的數據大約需要2分鐘的時間(目前主從版云Redis最大實例規格即為64G),故將讀超時設置為2分鐘。

          單純調整超時時間并不是我們的最終方案,這里仍在改進,比如增加一個狀態監測端口,新開一個狀態線程來探測Redis活性等,歡迎大家集思廣益提供優質解決方案。

          主備切換前準備工作

          當健康檢查發現Redis出現不可用情況時就要準備進行主備切換,在主備切換真正執行前需要額外做一些工作:

          通過VIP檢查Redis健康狀態 if VIP不健康:     檢查Slave狀態     if Slave健康:         再次檢查VIP狀態         if VIP健康:             無需主備切換         else:             執行主備切換     else:         Slave不健康無法切換 else:     無需主備切換

          在執行切換前要檢查Slave狀態以確保切換后實例是可服務的,否則即使切換也是無效的,比如兩臺主機都宕機這種極端情況。

          同時對VPC類型的實例做了特殊處理,因為我們是沒有辦法訪問用戶自定義網絡的VIP的,這時需要把對VIP的健康檢查換成對Master的健康檢查。

          執行主備切換

          當Redis出現不可用且滿足切換條件時,真正開始執行主備切換動作。同時切換動作也支持主動的任務切換和被動的故障切換,兩者主要區別在是否需要Slave等待Master達到同步狀態,以下對主備切換做詳細說明:

          1. 額外再次檢查一次Master狀態 if Master健康:     if 故障切換:         無需切換,返回成功     else:         a. 設置Master為readONLY只讀狀態         b. 通過info replication命令檢查主備同步狀態,也即master_repl_offset是否等于Slave的offset         if 若超時仍未達到一致狀態:             重置Master為readwrite可讀寫狀態,并返回異常 else:     日志記錄此時Master無法連接 2. 切換VIP指向Slave if 切換失敗:     記錄日志并返回異常 3. 更新主備元信息 4. 向Slave發送slaveof no one命令,使其升級為新的Master 5. 嘗試向原Master發送slaveof命令,使其降級為新的Slave     此時原Master可能已經宕機,故不做失敗處理,僅記錄日志

          通過以上方案,云數據庫Redis版SLA可以達到99.99%,僅在主從都發生宕機的極端情況無法服務。

          結束

          本文介紹了云數據Redis版HA方案,通過主從雙機熱備來保證服務高可用,健康檢查出現異常時及時進行主備切換,有效保障業務運行。

          posted on 2016-12-14 16:27 jinfeng_wang 閱讀(176) 評論(0)  編輯  收藏 所屬分類: 2016-REDIS
          主站蜘蛛池模板: 杂多县| 长岛县| 南京市| 浦北县| 乌兰浩特市| 曲水县| 江油市| 永清县| 佛坪县| 亚东县| 资中县| 绥宁县| 南陵县| 闻喜县| 柳江县| 高密市| 托克逊县| 宁乡县| 房山区| 东莞市| 汉沽区| 梅州市| 西宁市| 广饶县| 临桂县| 澜沧| 营口市| 广丰县| 蕲春县| 拉孜县| 英超| 苗栗市| 泊头市| 乡宁县| 张家港市| 田东县| 新安县| 武邑县| 岗巴县| 兴宁市| 德安县|