天天看點

利用redis-sentinel+consul實作redis高可用

由于keepalived的應用場景有限,比如它的核心協定vrrp隻能工作在區域網路内,不能工作在區域網路外(網間、廣域網),而且在網絡不受自己控制時基本不能用,除非設定好的vip是供區域網路使用。是以特别是在雲計算環境中,使用雲主機(例如阿裡雲ecs等)就不能用keepalived,是以隻能尋找一個可替代keepalived的解決方案來替代它。consul作為服務注冊、服務發現的最佳選擇,無疑可以很好的替代keepalived。

前文是用的keepalived提供一個vip為上層應用提供通路入口,本文是将keepalived替換成consul,利用consul的dns interface為上層應用提供redis(master)的ip。

利用redis-sentinel+consul實作redis高可用

前提條件:需要一個可用的consul叢集,可以利用consul叢集本身和配置檔案注冊服務,也可以用一台單獨的主機注冊,還可以用http api向consul注冊。

為了擷取redis(master)的ip而不是redis(slave)的ip,可以用腳本檢查實作,與keepalived腳本中相似,隻是傳回值将1設定成2,因為consul中傳回值0是沒問題(passed),1是警告(warning),2是嚴重(critical)。

下面是用一台單獨的主機注冊的例子。

json配置檔案如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

<code>{</code>

<code>  </code><code>"services"</code><code>: [</code>

<code>    </code><code>{</code>

<code>      </code><code>"id"</code><code>: </code><code>"redisnode1"</code><code>,</code>

<code>      </code><code>"name"</code><code>: </code><code>"redis"</code><code>,</code>

<code>      </code><code>"tags"</code><code>: [</code>

<code>        </code><code>"master"</code>

<code>      </code><code>],</code>

<code>      </code><code>"address"</code><code>: </code><code>"192.168.1.241"</code><code>,</code>

<code>      </code><code>"port"</code><code>: 6379,</code>

<code>      </code><code>"checks"</code><code>: [</code>

<code>        </code><code>{</code>

<code>          </code><code>"script"</code><code>: </code><code>"/usr/local/sbin/redis-cli -h 192.168.1.241 -p 6379 info | grep role:master || exit 2"</code><code>,</code>

<code>          </code><code>"interval"</code><code>: </code><code>"5s"</code>

<code>        </code><code>}</code>

<code>      </code><code>]</code>

<code>    </code><code>},</code>

<code>      </code><code>"id"</code><code>: </code><code>"redisnode2"</code><code>,</code>

<code>      </code><code>"address"</code><code>: </code><code>"192.168.1.242"</code><code>,</code>

<code>          </code><code>"script"</code><code>: </code><code>"/usr/local/sbin/redis-cli -h 192.168.1.242 -p 6379 info | grep role:master || exit 2"</code><code>,</code>

<code>      </code><code>"id"</code><code>: </code><code>"redisnode3"</code><code>,</code>

<code>      </code><code>"address"</code><code>: </code><code>"192.168.1.243"</code><code>,</code>

<code>          </code><code>"script"</code><code>: </code><code>"/usr/local/sbin/redis-cli -h 192.168.1.243 -p 6379 info | grep role:master || exit 2"</code><code>,</code>

<code>    </code><code>}</code>

<code>  </code><code>]</code>

<code>}</code>

注冊是利用consul agent作為client運作注冊的,假設consul叢集中某台server的位址是192.168.1.245。

50

51

52

53

<code>mkdir</code> <code>-p </code><code>/usr/local/consul/data</code> <code>/usr/local/consul/config</code>   

<code>cat</code> <code>&gt;</code><code>/usr/local/consul/config/rediscluster</code><code>.json&lt;&lt;eof</code>

<code>eof</code>

<code>/bin/consul</code> <code>agent -advertise=$(</code><code>ifconfig</code> <code>$(route -n | </code><code>awk</code> <code>'/^0.0.0.0/ &amp;&amp; /ug/ {print $nf}'</code><code>) | </code><code>grep</code> <code>inet | </code><code>egrep</code> <code>-</code><code>v</code> <code>"(inet6|127.0.0.1)"</code> <code>| </code><code>cut</code> <code>-d </code><code>":"</code> <code>-f2 | </code><code>cut</code> <code>-d </code><code>" "</code> <code>-f1) -bind=$(</code><code>ifconfig</code> <code>$(route -n | </code><code>awk</code> <code>'/^0.0.0.0/ &amp;&amp; /ug/ {print $nf}'</code><code>) | </code><code>grep</code> <code>inet | </code><code>egrep</code> <code>-</code><code>v</code> <code>"(inet6|127.0.0.1)"</code> <code>| </code><code>cut</code> <code>-d </code><code>":"</code> <code>-f2 | </code><code>cut</code> <code>-d </code><code>" "</code> <code>-f1) -data-</code><code>dir</code><code>=</code><code>/usr/local/consul/data</code> <code>-config-</code><code>dir</code><code>=</code><code>/usr/local/consul/config</code> <code>-</code><code>join</code> <code>192.168.1.245</code>

需要背景運作時可以添加nohup thiscommandline &gt;/path/to/logfile 2&gt;&amp;1 &amp;

注意:在consul json配置檔案中,每個consul agent的service id都不能重複,name是強制要求的,必須要有,如果id省略,則跟name相同,其他的都是可選的,可有可無。但為了能夠使用某條服務資訊,就必須要有ip和port,當然port可以在應用中指定。check最好要有,否則當出現問題時不能從consul中取消注冊。

注意:上述指令行中使用的是與預設網關同網段ip(公網ip位址),要求此位址與consul叢集位址之間能互相通路。在啟動consul agent之前可以下面兩行指令中的一行确定是否滿足此條件:

<code>consul info -rpc-addr=192.168.1.245:8400   </code>

<code>consul members -rpc-addr=192.168.1.245:8400</code>

在consul agent啟動後,此時redis的資訊就會在consul中展示出來,包括ui、dns interface和http api中都能查詢到。使用redis的應用應該将dns指向consul叢集的dns位址,這樣才能查詢到redis服務對應的ip。

利用redis-sentinel+consul實作redis高可用
利用redis-sentinel+consul實作redis高可用

例如用redis-cli測試一下redis叢集。

利用redis-sentinel+consul實作redis高可用

注意:可能存在的問題。如果redis master發生故障,原先的slave會變成新的master,dns緩存可能不會重新整理,這個在發生故障處理時需要注意清空上層應用的dns緩存。

tag:redis叢集,redis高可用,redis-sentinel,consul api,redis主從複制

--end--

繼續閱讀