天天看點

redis-sentinel 高可用方案實踐

近期公司的一塊核心業務使用redis作為配置轉發中心,存在單點問題,考慮服務的可靠性。針對業務需求,我們确定了我們的需求:

  1. 異地跨機房容災
  2. 故障自動切換
  3. 盡可能高的保證資料不丢失

針對以上需求,我們分别對redis主從複之,redis-cluster,redis-sentinel方案進行了調研,對比結果如下:

方案 資料可靠性 服務可靠性 風險
主從備份 出問題需要手動切換,中間推送的資料會丢失
redis-cluster 異地機房熱備,機房間網絡出問題的情況下會出現腦裂的問題;同時我們對redis-cluster無運維和使用經驗
redis-sentinel

在master當機後,用戶端會通過api查詢目前master歸屬,重連redis

使用内網同步,主從之間的資料丢失同步基本可以忽略,業務可以忍受

基于以上調研,我們放棄了主從備份方案,對redis-cluster及redis-sentinel方案進行了深入分析。redis-cluster采用主從備份、master選舉的方式實作高可用,但在異地機房部署時,如配置不當,很容易引發腦裂問題;同時由于redis-cluster我們并沒有成熟的運維經驗,最終放棄了該方案,轉向redis-sentinel。 redis-sentinel就像他的名字一樣,他是一個哨兵,監控master狀态,如果超過規定時間沒有響應,則自動進行主從切換,期間會有一段時間(決定于具體的配置參數)redis叢集無法提供服務 。原理類似mysql的MHA。redis-sentinel-server同時提供了一套接口,用于查詢目前叢集的狀态,Java的用戶端有完整的封裝,php的擴充并沒有提供相應功能,在github上有幾個package,但由于太過複雜,不适合遷移到現有業務(沒有使用命名空間和composer),是以基于phpredis-2.2.8封裝了一個簡易的​​redis-sentinel​​用戶端,目前已在核心業務生産環境上穩定運作。Java用戶端與php用戶端通過查詢redis-sentinel叢集獲得目前redis-master位址,進行連接配接,當叢集發生主從切換時,用戶端會進行重連。 php-redis-sentinel的demo代碼如下:

1

2

3

4

5

6

7

8

9

10

​$sentinel_pool​

​ ​

​= ​

​​

​new​

​\Jenner\RedisSentinel\SentinelPool();​

​$sentinel_pool​

​->addSentinel(​

​'127.0.0.1'​

​, 26379);​

​$sentinel_pool​

​->addSentinel(​

​'127.0.0.1'​

​, 26380);​

​$address​

​= ​

​$sentinel_pool​

​->master(​

​'mymaster'​

​);​

​print_r(​

​$address​

​);​

​$redis​

​= ​

​$sentinel_pool​

​->getRedis(​

​'mymaster'​

​);​

​$info​

​= ​

​$redis​

​->info();​

​print_r(​

​$info​

​);​