前言
隨著很多公司使用Redis作為快取和高效能儲存方案,Redis的可用性也變得越來越重要。目前
比較主流的HA方案是Sentinel+Redis主從複製。Sentinel是Redis官方自帶的高可用中介軟體,運維簡單、穩定,建議使用Redis
3.0及以上穩定版本。
本文重點介紹如何使用該架構,以及需要注意的問題和解決方案。
HA架構圖
首先部署Redis主從複製叢集,比如1主3從;然後部署3個Sentinel節點。
為了安全起見,Sentinel節點分別部署在不同的伺服器上,Redis主從節點分別部署在不同伺服器上。 具體部署步驟,這裡不再贅述。
最佳實踐
針對這個HA架構,應用程式該如何使用呢?這裡介紹一個比較簡單可靠的使用方法。
在應用程式(APP)配置裡設定如下資訊:
3個Sentinel的連線方式(不是Redis主庫連線方式)
Redis密碼
masterName
說明: 如果Sentinel上層使用了LVS,那麼配置裡改為VIP。
應用程式通過和Sentinel互動,獲取到Redis主庫資訊,然後再處理讀寫請求。 其中,由於Sentinel帶來的效能開銷很小,可以忽略。
需要注意的地方:
多個Sentinel連線方式,驅動如何選擇
推薦的處理方式:採用輪訓或者隨機選擇,支援負載均衡。
如果某個Sentinel當機,驅動如何處理
推薦的處理方式:採用重試和黑名單機制,及時上線和下線故障節點,支援高可用。
驅動是否具有連線池功能
一般情況下,主流的語言,比如Java,PHP等等,驅動具有連線管理器的,支援連線複用。
可以從Redis的info資訊裡檢視,如下:
10.11.11.13:6379> info clients
# Clients
connected_clients:150
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0
如果連線無法複用,connected_clients會飆升到上千,甚至導致Redis服務異常,停止處理請求。 如果驅動不支援連線池,需要選擇新驅動,或者二次開發驅動。
問題分析
使用以上HA架構,細心的朋友會發現這樣一個問題。 如果Redis主庫當機,Redis配置會發生改變,如下:
某些引數的值會自動被加上"",比如密碼引數。 一般禁止使用類似""作為密碼的一部分。Redis密碼 引數一旦被加上"",在運維和使用過程中,就會存在比較大的風險和麻煩。
分析Redis原始碼,以下情況會觸發配置修改:
1)Master故障切換
2)新加入Sentinel
3)執行 config rewrite
4)執行 sentinel flushconfig
5)執行 sentinel remove
6)Sentinel新加入Redis master節點
解決方案
針對該問題,常用解決方法:
1 人工處理
為Redis密碼加上監控,一旦變更,報警後人工處理。 這是最簡單也是不可靠的方法。
2 指令碼控制
開發一個指令碼,週期性監控Redis密碼,一旦發現變更後,自動改回。 這種方法,增加了運維成本和風險,也無法100%保證解決問題。
3 修改原始碼邏輯
修改原始碼,從根本上解決這個問題,方法如下:
src/config.c
修改函式int rewriteConfig(char *path)
註釋如下兩行:
rewriteConfigStringOption(state,"masterauth",server.masterauth,NULL);
rewriteConfigStringOption(state,"requirepass",server.requirepass,NULL);
修改後重新編譯Redis原始碼。 可以通過執行config rewrite命令驗證,Redis密碼引數不會備自動修改了。
由於程式碼改動很小,沒有風險點,筆者線上上已經使用一年多時間,Redis服務很穩定,沒有問題。
在此我向大家推薦一個架構學習交流群。交流學習群號: 744642380, 裡面會分享一些資深架構師錄製的視訊錄影:有Spring,MyBatis,Netty原始碼分析,高併發、高效能、分散式、微服務架構的原理,JVM效能優化、分散式架構等這些成為架構師必備的知識體系。還能領取免費的學習資源,目前受益良