《Redis 高可用架構最佳實踐》要點:
本文介紹了Redis 高可用架構最佳實踐,希望對您有用。如果有疑問,可以聯系我們。
Redis 是一個開源的使用 ANSI C 語言編寫、支持網絡、可基于內存亦可持久化的日記型、Key-Value 數據庫,并提供多種語言的 API.
如今,互聯網業務的數據正以更快的速度在增長,數據類型越來越豐富,這對數據處理的速度和才能提出了更高要求.Redis 是一種開源的內存非關系型數據庫,給開發人員帶來的體驗是顛覆性的.在自始至終的設計過程中,都充分考慮高性能,這使得 Redis 成為當今速度最快的 NoSQL 數據庫.
考慮高性能的同時,高可用也是很緊張的考慮因素.互聯網 7x24 無間斷服務,在故障期間以最快的速度 Failover,能給企業帶來最小的損失.
那么,在實際利用中,都有哪些高可用架構呢?架構之間有何優劣?我們應該怎么取舍?有哪些最佳實踐?
0x02 Sentinel 原理
在講解 Redis 高可用計劃之前,我們先來看看 Redis Sentinel 原理是怎么樣的.
Sentinel 集群通過給定的配置文件發現 master,啟動時會監控 master.通過向 master 發送 info 信息得到該服務器下面的所有從服務器.
Sentinel 集群通過命令連接向被監視的主從服務器發送 hello 信息 (每秒一次),該信息包含 Sentinel 本身的 IP、端口、id 等內容,以此來向其他 Sentinel 宣告自己的存在.
Sentinel 集群通過訂閱連接接收其他 Sentinel 發送的 hello 信息,以此來發現監視同一個主服務器的其他 Sentinel;集群之間會互相創立命令連接用于通信,因為已經有主從服務器作為發送和接收 hello 信息的中介,Sentinel 之間不會創立訂閱連接.
Sentinel 集群使用 ping 命令來檢測實例的狀態,如果在指定的時間內(down-after-milliseconds)沒有回復或則返回差錯的回復,那么該實例被判為下線.
當 failover 主備切換被觸發后,failover 并不會馬上進行,還需要 Sentinel 中的大多數 Sentinel 授權后才可以進行 failover,即進行 failover 的 Sentinel 會去獲得指定 quorum 個的 Sentinel 的授權,成功后進入 ODOWN 狀態.如在 5 個 Sentinel 中配置了 2 個 quorum,比及 2 個 Sentinel 認為 master 死了就執行 failover.
Sentinel 向選為 master 的 slave 發送 SLAVEOF NO ONE 命令,選擇 slave 的條件是 Sentinel 首先會依據 slaves 的優先級來進行排序,優先級越小排名越靠前.如果優先級相同,則查看復制的下標,哪個從 master 接收的復制數據多,哪個就靠前.如果優先級和下標都相同,就選擇進程 ID 較小的.
Sentinel 被授權后,它將會得到宕掉的 master 的一份最新配置版本號 (config-epoch),當 failover 執行結束以后,這個版本號將會被用于最新的配置,通過廣播形式通知其它 Sentinel,其它的 Sentinel 則更新對應 master 的配置.
1 到 3 是主動發現機制:
以 10 秒一次的頻率,向被監視的 master 發送 info 命令,依據回復獲取 master 當前信息.
以 1 秒一次的頻率,向所有 redis 服務器、包括 Sentinel 在內發送 PING 命令,通過回復判斷服務器是否在線.
以 2 秒一次的頻率,通過向所有被監督的 master,slave 服務器發送當前 Sentinel master 信息的消息.
4 是檢測機制,5 和 6 是 failover 機制,7 是更新設置裝備擺設機制.[1]
0x03 Redis 高可用架構
講授完 Redis Sentinel 原理之后,接下來講授常用的 Redis 高可用架構.
Redis Sentinel 集群 + 內網 DNS + 自界說腳本
Redis Sentinel 集群 + VIP + 自界說腳本
封裝客戶端直連 Redis Sentinel 端口
JedisSentinelPool,得當 Java
PHP 基于 phpredis 自行封裝
Redis Sentinel 集群 + Keepalived/Haproxy
Redis M/S + Keepalived
Redis Cluster
Twemproxy
Codis
接下來共同圖文逐個講解.
3.1 Redis Sentinel 集群 + 內網 DNS + 自界說腳本
上圖是已經在線上環境應用的方案.底層是 Redis Sentinel 集群,代理著 Redis 主從,Web 端連接內網 DNS 提供服務.內網 DNS 依照一定的規則分配,比如 xxxx.redis.cache/queue.port.xxx.xxx
,第一個段表示業務簡寫,第二個段表示這是 Redis 內網域名,第三個段表示 Redis 類型,cache 表示緩存,queue 表示隊列,第四個段表示 Redis 端口,第五、第六個段表示內網主域名.
當主節點發生故障,好比機器故障、Redis 節點故障或者網絡不可達,Sentinel 集群會調用client-reconfig-script
配置的腳本,修改對應端口的內網域名.對應端口的內網域名指向新的 Redis 主節點.
長處:
秒級切換,在 10s 內完成整個切換操作
腳本自界說,架構可控
對應用透明,前端不消擔心后端發生什么變化
毛病:
維護本錢略高,Redis Sentinel 集群建議投入 3 臺機器以上
依附 DNS,存在解析延時
Sentinel 模式存在短時間的服務弗成用
服務通過外網拜訪不可采用此方案
3.2 Redis Sentinel 集群 + VIP + 自界說腳本
此方案和上一個方案相比,略有不同.第一個方案使用了內網 DNS,第二個方案把內網 DNS 換成了虛擬 IP.底層是 Redis Sentinel 集群,代理著 Redis 主從,Web 端通過 VIP 提供服務.在部署 Redis 主從的時候,需要將虛擬 IP 綁定到當前的 Redis 主節點.當主節點發生故障,好比機器故障、Redis 節點故障或者網絡不可達,Sentinel 集群會調用 client-reconfig-script
配置的腳本,將 VIP 漂移到新的主節點上.
長處:
秒級切換,在 5s 內完成整個切換操作
腳本自界說,架構可控
對應用透明,前端不消擔心后端發生什么變化
毛病:
維護本錢略高,Redis Sentinel 集群建議投入 3 臺機器以上
使用 VIP 增加維護本錢,存在 IP 混亂風險
Sentinel 模式存在短時間的服務弗成用
3.3 封裝客戶端直連 Redis Sentinel 端口
部分業務只能通過外網拜訪 Redis,上述兩種方案均不可用,于是衍生出了這種方案.Web 使用客戶端連接其中一臺 Redis Sentinel 集群中的一臺機器的某個端口,然后通過這個端口獲取到當前的主節點,然后再連接到真實的 Redis 主節點進行相應的業務員操作.需要注意的是,Redis Sentinel 端口和 Redis 主節點均需要開放拜訪權限.如果前端業務使用 Java,有 JedisSentinelPool 可以復用;如果前端業務使用 PHP,可以在 phpredis 的基礎上做二次封裝.
長處:
服務探測故障實時
DBA 維護本錢低
毛病:
依附客戶端支持 Sentinel
Sentinel 服務器和 Redis 節點需要開放拜訪權限
對利用有侵入性
3.4 Redis Sentinel 集群 + Keepalived/Haproxy
底層是 Redis Sentinel 集群,代理著 Redis 主從,Web 端通過 VIP 提供服務.當主節點發生故障,好比機器故障、Redis 節點故障或者網絡不可達,Redis 之間的切換通過 Redis Sentinel 內部機制保障,VIP 切換通過 Keepalived 保障.
長處:
秒級切換
對利用透明
毛病:
維護本錢高
存在腦裂
Sentinel 模式存在短時間的服務弗成用
3.5 Redis M/S + Keepalived
此方案沒有使用到 Redis Sentinel.此方案使用了原生的主從和 Keepalived,VIP 切換通過 Keepalived 保障,Redis 主從之間的切換必要自定義腳本實現.
長處:
秒級切換
對利用透明
部署簡單,維護本錢低
毛病:
必要腳本實現切換功能
存在腦裂
3.6 Redis Cluster
From: http://intro2libsys.com/focused-redis-topics/day-one/intro-redis-cluster
Redis 3.0.0 在 2015 年 4 月 2 日正式發布,距今已有兩年多的時間.Redis 集群采用 P2P 模式,無中心化.把 key 分成 16384 個 slot,每個實例負責一部分 slot.客戶端哀求對應的數據,若該實例 slot 沒有對應的數據,該實例會轉發給對應的實例.另外,Redis 集群通過 Gossip 協議同步節點信息.
長處:
組件 all-in-box,部署簡單,節約機械資源
機能比 proxy 模式好
自動故障轉移、Slot 遷徙中數據可用
官方原生集群計劃,更新與支持有保障
毛病:
架構比擬新,最佳實踐較少
多鍵操作支撐有限(驅動可以曲線救國)
為了性能提升,客戶端必要緩存路由表信息
節點發現、reshard 操作不夠主動化
3.7 Twemproxy
From: http://engineering.bloomreach.com/the-evolution-of-fault-tolerant-redis-cluster
多個同構 Twemproxy(配置相同)同時工作,接受客戶端的哀求,根據 hash 算法,轉發給對應的 Redis.
Twemproxy 方案比較成熟了,之前我們團隊長期使用此方案,但是效果并不是很抱負.一方面是定位問題比較困難,另一方面是它對自動剔除節點的支持不是很友好.
長處:
開發簡單,對利用幾乎透明
歷史悠久,計劃成熟
毛病:
代理經銷影響性能
LVS 和 Twemproxy 會有節點機能瓶頸
Redis 擴容異常麻煩
Twitter 內部已放棄使用該計劃,新使用的架構未開源
3.8 Codis
From: https://github.com/CodisLabs/codis
Codis 是由豌豆莢開源的產品,涉及組件眾多,其中 ZooKeeper 存放路由表和代理節點元數據、分發 Codis-Config 的命令;Codis-Config 是集成管理工具,有 Web 界面供使用;Codis-Proxy 是一個兼容 Redis 協議的無狀態代理;Codis-Redis 基于 Redis 2.8 版本二次開發,加入 slot 支持,便利遷移數據.
長處:
開發簡單,對利用幾乎透明
機能比 Twemproxy 好
有圖形化界面,擴容容易,運維便利
毛病:
代理經銷依舊影響性能
組件過多,必要很多機器資源
修改了 Redis 代碼,導致和官方無法同步,新特性跟進遲緩
開發團隊準備主推基于 Redis 改革的 reborndb
0x04 最佳實踐
所謂的最佳實踐,都是最得當具體場景的實踐.
主推以下計劃:
Redis Sentinel 集群 + 內網 DNS + 自界說腳本
Redis Sentinel 集群 + VIP + 自界說腳本
以下是實戰進程中總結出的最佳實踐:
Redis Sentinel 集群建議使用 >= 5 臺機械
分歧的大業務可以使用一套 Redis Sentinel 集群,代理該業務下的所有端口
根據分歧的業務劃分好 Redis 端口范圍
自定義腳本建議采用 Python 實現,擴展方便
自定義腳本必要注意判斷當前的 Sentinel 角色
自界說腳本傳入參數:<service_name> <role> <comment> <from_ip> <from_port> <to_ip> <to_port>
自定義腳本必要遠程 ssh 操作機器,建議使用 paramiko
庫,避免重復建立 SSH 連接,消耗時間
加速 SSH 連接,建議封閉以下兩個參數
UseDNS no
GSSAPIAuthentication no
微信或者郵件告警,建議 fork 一個過程,避免主過程阻塞
主動切換和故障切換,所有操作建議在 15s 以內完成
歡迎參與《Redis 高可用架構最佳實踐》討論,分享您的想法,維易PHP學院為您提供專業教程。
轉載請注明本頁網址:
http://www.snjht.com/jiaocheng/9226.html