1. 程式人生 > >Redis高可用架構的應用及改進經驗談

Redis高可用架構的應用及改進經驗談

針對這個HA架構,應用程式該如何使用呢?這裡介紹一個比較簡單可靠的使用方法。在應用程式(APP)配置裡設定如下資訊:
  • 3個Sentinel的連線方式(不是Redis主庫連線方式)
  • Redis密碼
  • masterName

說明:如果Sentinel上層使用了LVS,那麼配置裡改為VIP。

應用程式通過和Sentinel互動,獲取到Redis主庫資訊,然後再處理讀寫請求。其中,由於Sentinel帶來的效能開銷很小,可以忽略。

需要注意的地方:

  1. 多個Sentinel連線方式,驅動如何選擇推薦的處理方式:採用輪訓或者隨機選擇,支援負載均衡。
  2. 如果某個Sentinel宕機,驅動如何處理推薦的處理方式:採用重試和黑名單機制,及時上線和下線故障節點,支援高可用。
  3. 驅動是否具有連線池功能一般情況下,主流的語言,比如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服務很穩定,沒有問題。

這是修改過的Redis原始碼,已上傳到GitHub:

  • https://github.com/giantmangu888/redis3.0.7

或者直接下載:

  • git clone https://github.com/giantmangu888/redis3.0.7.git
  • 文章來自微信公眾號:DBAplus社群