分佈式架構 Redis優化及高可用
優化說明:
Redis底層通訊協議對管道提供了支持,通過管道可以一次性發送多條命令,執行完後一次性將結果取回
Redis管道API命令中未體現、但支持管道
優化方案
- 1.精簡鍵名和檢鍵值
- 2.合理設計存儲數據結構和數據關係,減少數據冗餘
- 3.使用mset來賦值、高於set效率,類似 lpush、zadd等批量
- 4.如果條件允許,儘量使用LUA腳本來輔助獲取和操作數據(LUA腳本所有指令一次性完成,效率高),如條件刪除
- 5.hash結構來存儲對象,佔用少內存(zipmap存儲數據值)
- 6.設置maxmemory 最大物理內存,使用了配置物理內存後開始拒接後續請求
- 7.數據採用RDB方式進行數據持久化備份,建議只在Slave上進行RDB持久化,而且較長的時間備份一次就好,(如20分鐘保存一次 避免AOF帶來繼續IO操作,也避免了AOF
Rewrite最後將rewrite過程中產生的新數據寫到新文件造成的阻塞,當然極端情況如果M/S同時掛了,可能會損失20分鐘的數據) - 8.考慮在一臺服務器啓動多個Redis實例、充分利用CPU調度資源(但會帶來嚴重的IO競爭,設置錯開重寫AOF)
高可用說明:
Redis單節點存在宕機的風險,爲了解決這種風險,需要針對其進行高可用方案,
爲了達到高效狀態使其單臺宕機情況下,業務正常運轉
高可用方案如下
- 1.Redis複製
- 2.Redis集羣 (version >=3.0)
複製描述
Redis支持複製功能,實現當一臺服務器數據更新後,自動將新數據同步到另一臺服務器,可以做Master主節點用於讀寫、Slave從節點用於讀
複製的優勢
- 1.實現讀寫分離
- 2.利於主服務器崩潰後數據恢復
複製開啓過程:
從數據庫redis.conf需開啓“saveof 主服務器ip 主服務器端口” (saveof 127.0.0.1 6379)
通過info replication : 查看複製節點信息
slave-read-only 設置redis只讀
slave-serve-stale-data 設置yes,用於響應主從同步期間,新的請求結果
repl-ping-slave-period 設置從節點向主節點報告心跳,默認10s
repl-timeout 設置主動超時時間
複製特性
- 如1主1叢部署結構 期間master出現問題,slave節點可以動態指向新的主節點服務器
從服務器運行 slaveof 可支持運行期間修改slave節點同步信息,(如 saveof 127.0.0.1 6390 ,從節點斷掉和6379主從關係轉向指定新的服務器) - 如1主1叢部署結構 期間master宕機,從服務器可以升級爲主服務器
從服務器運行 slaveof no one,自動升級爲主服務器
監控工具(哨兵)
實現原理:當主服務器宕機後,多個從服務中投票選舉1個用於充當主服務器,選舉輪次可能存在失敗,多次選舉最終達到成功狀態
用途:監控主從服務器運行是否正常,當主服務器出現異常,自動將從服務器升級爲主數據庫
開啓:
建立setinal.conf文件,設置要監控的服務器清單
setinal monitor redis主名稱 地址 端口 1(選舉參數)
/usr/local/bin/redis-setinal setinal.conf
Redis拆分數據過程
當一臺Redis服務器存儲的數據量過大,首先會採用垂直數據拆分,舉例如下:
RedisA 存在(用戶、產品、訂單)數據,拆分成,RedisA、RedisB、RedisC分別存放 用戶、產品、訂單數據
針對RedisA、RedisB、RedisC還可以進行父子Master-Slave方式進行擴展
假如其配置是32G,按照5K條數據1M,保守估計可存儲2-3億數據
複製會存在問題及處理
複製中Redis每個數據庫節點都擁有完整的數據,複製的總數據量受限於內存最小的數據庫節點
由於複製數據量過大, 已經超過了複製的數據庫內存最小的數據庫節點的物理內存,複製過程就失敗了
Redis集羣
官網提供集羣架構如下
如圖所示,體現以下方面
- 所有的Redis節點互聯,內部使用二進制協議優化傳輸速度和寬帶
- 節點的Fail是通過集羣中超過半數的節點監測失效時才生效
- 客戶端與Redis節點直連,不需要中間Proxy代理,客戶端不需要連接集羣所有節點,連接集羣中任何一個可用節點即可
- 集羣把所有物理節點映射到(0-16383)插槽上,集羣負責維護 (節點-插槽-值)關係
集羣描述
針對以上單個複製集存在問題,此時可多個複製集進行集羣,形成水平擴展,每個複製集只存儲整個複製集一分部數據
Redis分片:將數據拆分到多個Redis實例過程,這樣每個Redis只包含實例的一部分完整數據
針對Redis3.0之前的版本,依靠客戶端分片來完成集羣,之後Redis支持集羣模式,還提供網絡分區後的訪問性和支撐對主數據庫的故障恢復
使用集羣后,只能使用默認的0號數據庫
分片方式如下
- 跟業務有關係:按照範圍分片:如 時間、數據條數、編碼等
- 跟業務無關係:一致性hash
分片的缺點
- 數據備份麻煩、聚集需要多個實例和主機持久化文件
- 不好擴容
- 不支持涉及多建操作,如果操作指令分在不同節點存在問題
- 故障恢復處理比較棘手
Redis3.0 集羣優勢
- 將數據自動切分到多個節點的能力
- 當集羣中的一部分節點失效或者無法進行通訊時, 仍然可以繼續處理命令請求的能力
總結:
Redis建議使用hash結構存儲數據、數據傳輸、同步更高效、高可用方案優先級別如下:
1.單節點 父子級複製
2.多節點,垂直數據拆分並父子級複製,加上哨兵監控
3.分佈式集羣
作者簡介:張程 技術研究
更多文章請關注微信公衆號:zachary分解獅 (frankly0423)