近期公司的一塊核心業務使用redis作為配置轉發中心,存在單點問題,考慮服務的可靠性。針對業務需求,我們确定了我們的需求:
- 異地跨機房容災
- 故障自動切換
- 盡可能高的保證資料不丢失
針對以上需求,我們分别對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 | |