荔枝Redis高可用方案


一、背景

  • 線上redis架構(gòu),總共大概250套主從
  • 架構(gòu)以1主1從為主,少部分1主多從
  • 大部分主庫抗業(yè)務(wù),從庫做持久化及定時備份
  • 少部分主從(大概30多套)通過應(yīng)用配置讀寫域名實(shí)現(xiàn)讀寫分離


二、關(guān)于目前Redis讀寫分離方案的一些看法

  1. 目前線上的讀寫分離是否有必要(單實(shí)例扛不住的原因在哪里)
  2. 從庫做持久化對請求的影響(需要額外掛從庫做持久化)
  3. 如果真的需要做讀寫分離,應(yīng)該怎么做


    image.png
image.png

結(jié)論:大部分業(yè)務(wù)沒必要做讀寫分離。讀寫分離適合讀多寫少場景,并且至少部署2個從做負(fù)載均衡分?jǐn)傋x負(fù)載。而rdb持久化/aof重寫等操作會阻塞業(yè)務(wù)庫,所以有備份需求的架構(gòu)需要額外添加一個從庫用于持久化備份。復(fù)雜的架構(gòu)也不利于高可用的設(shè)計。根據(jù)實(shí)際業(yè)務(wù)場景將數(shù)據(jù)拆分可能會是更好的選擇。

三、業(yè)界成熟Redis高可用架構(gòu)介紹

1. sentinel

sentinel架構(gòu)

sentinel 檢測原理

  • 每隔10s,每個sentinel會向主節(jié)點(diǎn)和從節(jié)點(diǎn)發(fā)送info replication命令獲取最新的主從拓?fù)浣Y(jié)構(gòu)
  • 每隔2s,每個sentinel節(jié)點(diǎn)向redis節(jié)點(diǎn)的__ sentinel __:hello頻道發(fā)送該sentinel節(jié)點(diǎn)對主節(jié)點(diǎn)判斷及當(dāng)前sentinel信息,其他sentinel節(jié)點(diǎn)也會訂閱該頻道,了解各個sentinel節(jié)點(diǎn)以及他們對主節(jié)點(diǎn)的判斷
  • 每隔1s,每個sentinel節(jié)點(diǎn)會向所有redis節(jié)點(diǎn)以及其他sentinel節(jié)點(diǎn)發(fā)送ping命令做一次心跳檢測,確認(rèn)各個節(jié)點(diǎn)是否可達(dá)

sentinel 切換原理

主觀下線:sentinel節(jié)點(diǎn)通過每2秒的ping心跳檢測,超過down-after-milliseconds主觀判斷redis節(jié)點(diǎn)下線

客觀下線:sentinel節(jié)點(diǎn)判斷主觀下線后,通過發(fā)送sentinel ismaster-down-by-addr到其他sentinel節(jié)點(diǎn)詢問對主節(jié)點(diǎn)的判斷,當(dāng)超過quonum個數(shù),則判斷該redis主節(jié)點(diǎn)客觀下線

故障轉(zhuǎn)移過程

  1. sentinel節(jié)點(diǎn)判斷redis節(jié)點(diǎn)主觀下線
  2. sentinel節(jié)點(diǎn)判斷redis節(jié)點(diǎn)客觀下線
  3. sentinel節(jié)點(diǎn)發(fā)起選舉,一旦節(jié)點(diǎn)獲得max(quorum,num(sentinels)/2+1)的票數(shù),即成為leader(選舉過程非???,基本上誰先完成客觀下線,誰就是leader)
  4. 由sentinel leader節(jié)點(diǎn)進(jìn)行redis failover

redis failover 包括提升redis從庫為主庫,將其他從庫掛載到新主庫等操作

特點(diǎn)

  • 一套sentinel集群至少3個節(jié)點(diǎn),sentinel節(jié)點(diǎn)通過raft算法選舉,節(jié)點(diǎn)個數(shù)為奇數(shù)
  • 1套sentinel集群可以監(jiān)控多套redis主從
  • 建議部署方式:相同業(yè)務(wù)使用同一套sentinel集群進(jìn)行監(jiān)控。
  • Client 端需要修改連接方式,配置由原來直連域名,修改為配置sentinel集群信息+redis主節(jié)點(diǎn)標(biāo)識名
  • sentinel只對主節(jié)點(diǎn)進(jìn)行failover,從節(jié)點(diǎn)故障只做主觀下線判斷,沒有后續(xù)的處理操作
  • sentinel不是中間件,應(yīng)用只會在初次連接的時候請求sentinel返回一個redis主節(jié)點(diǎn)的連接池,實(shí)際上是直連redis主節(jié)點(diǎn)的。(持續(xù)訂閱sentinel,當(dāng)redis發(fā)生故障切換,會重新返回一個主節(jié)點(diǎn)連接池)

痛點(diǎn)

  • 客戶端原生JedisSentinelPool只拿到redis主節(jié)點(diǎn)的連接池,無法支持讀寫分離
  • 應(yīng)用端需要修改連接配置(這個其實(shí)不算很痛,可以逐步推進(jìn))


2. Redis-Cluster

redis-cluster

特點(diǎn)

  • 無中心分布式架構(gòu),解決高可用,擴(kuò)展性問題
  • 集群中數(shù)據(jù)節(jié)點(diǎn)個數(shù)為奇數(shù)。每個節(jié)點(diǎn)代表一套redis主從(主庫讀寫,從庫備用)
  • 通過虛擬槽hash到各節(jié)點(diǎn)(總共16384個slots),實(shí)現(xiàn)數(shù)據(jù)分片
  • 無代理層,client端配置集群所有節(jié)點(diǎn)信息。連接集群中任一節(jié)點(diǎn)皆可訪問整個集群數(shù)據(jù)(自動路由)
  • 據(jù)說存在不少坑,需要先部署測試一段時間再上線


四、適合荔枝的Redis高可用架構(gòu)

從荔枝整體redis環(huán)境看,redis多為單主從,實(shí)例數(shù)據(jù)大部分在10G以內(nèi),不同業(yè)務(wù)之間實(shí)例相互獨(dú)立。sentinel是最合適的高可用方式。主要解決讀寫分離和域名切換的問題,這里給出2種方案

1. sentinel+consul

sentinel 負(fù)責(zé)故障主從切換,consul 主要提供DNS,健康檢測,服務(wù)發(fā)現(xiàn),域名切換
consul簡介

consul introduce

整體架構(gòu)
consul+sentinel redis高可用

說明

  • 客戶端需要改成特定后綴的域名格式(比如.consul)
  • 每臺緩存機(jī)器部署一個consul client,用于該機(jī)器所有redis實(shí)例的服務(wù)發(fā)現(xiàn),健康檢測
  • consul可以實(shí)現(xiàn)從節(jié)點(diǎn)的故障轉(zhuǎn)移

2. sentinel(取消讀寫分離) + redis-cluster(個別大數(shù)據(jù)量高并發(fā)實(shí)例)

整體架構(gòu)

redis+sentinel架構(gòu)圖.png

說明

  • 這套架構(gòu)可以滿足目前90%的redis高可用需求,架構(gòu)復(fù)雜度低,建議優(yōu)先考慮
  • python redis庫支持讀寫分離,可以通過master標(biāo)識名拿到從庫連接。jedis待測試
    >>> from redis.sentinel import Sentinel
    >>> sentinel = Sentinel([('localhost', 26379)], socket_timeout=0.1)
    >>> master = sentinel.master_for('mymaster', socket_timeout=0.1)
    >>> master.set('foo', 'bar')
    >>> slave = sentinel.slave_for('mymaster', socket_timeout=0.1)
    >>> slave.get('foo')
  • 對于現(xiàn)有的小部分做了讀寫分離的實(shí)例,先評估是否可以取消掉讀寫分離,接入sentinel
  • 對于大數(shù)據(jù)量,高并發(fā)的實(shí)例,考慮接入Redis-Cluster

3. sentinel + jedis改造(支持從庫failover)

說明

  • 原生sentinel實(shí)現(xiàn)master failover
  • 對于從庫故障sentinel 只做主觀下線判斷( +sdown)不進(jìn)行failover
  • 通過這個特點(diǎn),可以通過改造客戶端,將所有從節(jié)點(diǎn)看做一個資源池。訂閱sentinel和從節(jié)點(diǎn)變動有關(guān)的事件消息,從而動態(tài)返回從節(jié)點(diǎn)連接池
  • 這套方案架構(gòu)簡單,并能支持讀寫分離以及主從庫故障轉(zhuǎn)移,是目前我們選擇的高可用方案
從庫變動相關(guān)的事件
·+switch-master:切換主節(jié)點(diǎn)(原來的從節(jié)點(diǎn)晉升為主節(jié)點(diǎn)),說明減
少了某個從節(jié)點(diǎn)。
·+convert-to-slave:切換從節(jié)點(diǎn)(原來的主節(jié)點(diǎn)降級為從節(jié)點(diǎn)),說明
添加了某個從節(jié)點(diǎn)。
·+sdown:主觀下線,說明可能某個從節(jié)點(diǎn)可能不可用(因?yàn)閷墓?jié)點(diǎn)
不會做客觀下線),所以在實(shí)現(xiàn)客戶端時可以采用自身策略來實(shí)現(xiàn)類似主觀
下線的功能。
·+reboot:重新啟動了某個節(jié)點(diǎn),如果它的角色是slave,那么說明添加
了某個從節(jié)點(diǎn)。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容