天天看點

redis高可用架構

一、背景

   公司的業務在大量的使用redis,通路量大的業務我們有在使用codis叢集,redis 3.0叢集,說到redis 3.0叢集,我們線上已經跑了半年多了,叢集本身沒有出現過任務問題,但是由于我們這個業務是海外的,叢集建在aws的ec2上,由于ec2的網絡抖動或者ec2本身的原因,導緻主從切換,目前aws的技術正在跟進,這個叢集目前的qps 50w+,叢集本身已經做到了高可用和橫向擴充,但是,實際情況一些小的業務沒必要上叢集,單個執行個體就可以滿足業務需求,那麼我們就要想辦法如何保證單個執行個體的高可用,最近也在看相關的文檔,做一些測試,大家有在使用redis主從+lvs 漂vip的方案,也有使用redis主從+哨兵 漂vip的方案,甚至有在代碼邏輯做故障切換等等,各種各樣的方案都有,下面我介紹一下redis主從+哨兵 漂vip的方案,後面我們打算線上大規模的使用這個方案。

二、環境

1

2

3

4

5

6

7

8

<code>#redis</code>

<code>100.10.32.54:6400 主庫</code>

<code>100.10.32.55:6400 從庫</code>

<code>100.10.32.250 vip</code>

<code>#sentinel</code>

<code>100.10.32.54:26400 sentinel 本地節點</code>

<code>100.10.32.55:26400 sentinel 本地節點 </code>

<code>100.10.32.57:26400 sentinel 仲裁節點</code>

三、部署

1、安裝

<code>yum -y </code><code>install</code> <code>redis</code>

2、撰寫redis配置檔案(100.10.32.54 和100.10.32.55)

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

<code>vim </code><code>/etc/redis_6400</code><code>.conf</code>

<code>daemonize </code><code>yes</code>

<code>pidfile </code><code>"/var/run/redis_6400.pid"</code>

<code>port 6400</code>

<code>tcp-backlog 65535</code>

<code>bind 0.0.0.0</code>

<code>timeout 0</code>

<code>tcp-keepalive 0</code>

<code>loglevel notice</code>

<code>logfile </code><code>"/var/log/redis/redis_6400.log"</code>

<code>maxmemory 8gb</code>

<code>maxmemory-policy allkeys-lru</code>

<code>databases 16</code>

<code>save 900 1</code>

<code>save 300 10</code>

<code>save 60 10000</code>

<code>stop-writes-on-bgsave-error </code><code>yes</code>

<code>rdbcompression </code><code>yes</code>

<code>rdbchecksum </code><code>yes</code>

<code>dbfilename </code><code>"dump.rdb"</code>

<code>dir</code> <code>"/data/redis/6400"</code>

<code>slave-serve-stale-data </code><code>yes</code>

<code>slave-</code><code>read</code><code>-only </code><code>yes</code>

<code>repl-disable-tcp-nodelay no</code>

<code>slave-priority 100</code>

<code>appendonly no</code>

<code>appendfilename </code><code>"appendonly.aof"</code>

<code>appendfsync everysec</code>

<code>no-appendfsync-on-rewrite no</code>

<code>auto-aof-rewrite-percentage 100</code>

<code>auto-aof-rewrite-min-size 64mb</code>

<code>lua-</code><code>time</code><code>-limit 5000</code>

<code>slowlog-log-slower-than 10000</code>

<code>slowlog-max-len 128</code>

<code>notify-keyspace-events </code><code>""</code>

<code>hash</code><code>-max-ziplist-entries 512</code>

<code>hash</code><code>-max-ziplist-value 64</code>

<code>list-max-ziplist-entries 512</code>

<code>list-max-ziplist-value 64</code>

<code>set</code><code>-max-intset-entries 512</code>

<code>zset-max-ziplist-entries 128</code>

3、撰寫sentinel配置檔案(100.10.32.54 、100.10.32.55 和100.10.32.57)

<code>vim </code><code>/etc/redis-sentinel6400</code><code>.conf</code>

<code>port 26400</code>

<code>dir</code> <code>"/data/redis/redis_sentinels"</code>

<code>pidfile </code><code>"/var/run/redis/sentinel6400.pid"</code>

<code>logfile </code><code>"/data/redis/redis_sentinels/sentinel6400.log"</code>

<code>sentinel monitor master6400 100.10.32.54 6400 2</code>

<code>sentinel down-after-milliseconds master6400 6000</code>

<code>sentinel failover-timeout master6400 18000</code>

<code>sentinel client-reconfig-script master6400 </code><code>/opt/notify_master6400</code><code>.sh   </code><code>##仲裁節點無需添加這行配置,client-reconfig-script參數是在sentinel做failover的過程中調用腳本漂vip到新的master上</code>

ps:

4、撰寫漂vip的腳本(100.10.32.54 、100.10.32.55)

<code>vim </code><code>/opt/notify_master6400</code><code>.sh</code>

<code>#!/bin/bash</code>

<code>master_ip=$6</code>

<code>local_ip=</code><code>'100.10.32.54'</code> <code>#從庫修改為100.10.32.55</code>

<code>vip=</code><code>'100.10.32.250'</code>

<code>netmask=</code><code>'24'</code>         

<code>interface=</code><code>'eth0'</code> 

<code>if</code> <code>[ ${master_ip} = ${local_ip} ]; </code><code>then</code>

<code>         </code><code>/sbin/ip</code> <code>addr add ${vip}/${netmask} dev ${interface}</code>

<code>         </code><code>/sbin/arping</code> <code>-q -c 3 -a ${vip} -i ${interface}</code>

<code>        </code><code>exit</code> <code>0</code>

<code>else</code>

<code>         </code><code>/sbin/ip</code> <code>addr del ${vip}/${netmask} dev ${interface}</code>

<code>fi</code>

<code>exit</code> <code>1</code>

<code>chmod</code> <code>+x </code><code>/opt/notify_master6400</code><code>.sh   </code><code>#賦予可執行權限</code>

這裡大概說一下這個腳本的工作原理,sentinel在做failover的 過程中會傳出6個參數,分别是&lt;master-name&gt;、 &lt;role&gt;、 &lt;state&gt;、 &lt;from-ip&gt;、 &lt;from-port&gt;、 &lt;to-ip&gt; 、&lt;to-port&gt;,其中第6個參數from-ip也就是新的master的ip,對應腳本中的master_ip,下面的if判斷大家應該都很了然了,如果master_ip=local_ip,那就綁定vip,反之删除vip。

5、啟動redis服務(100.10.32.54、100.10.32.55)

<code>redis-server </code><code>/etc/redis_6400</code><code>.conf</code>

6、初始化主從(100.10.32.55)

<code>redis-cli -p 6400 slaveof 10.10.32.54 6400</code>

7、綁定vip到主庫(100.10.32.54)

<code>/sbin/ip</code> <code>addr add 100.10.32.250</code><code>/24</code> <code>dev eth0</code>

8、啟動sentinel服務(100.10.32.54、100.10.32.55、100.10.32.57)

<code>redis-server </code><code>/etc/redis-sentinel6400</code><code>.conf --sentinel</code>

至此,整個高可用方案已經搭建完成。

<code>[root@localhost tmp]</code><code># redis-cli -h 100.10.32.54  -p 6400 info  replication</code>

<code># replication</code>

<code>role:master</code>

<code>connected_slaves:1</code>

<code>slave0:ip=100.10.32.55,port=6400,state=online,offset=72669,lag=1</code>

<code>master_repl_offset:72669</code>

<code>repl_backlog_active:1</code>

<code>repl_backlog_size:1048576</code>

<code>repl_backlog_first_byte_offset:2</code>

<code>repl_backlog_histlen:72668</code>

<code>[root@localhost tmp]</code><code># redis-cli -h 100.10.32.54  -p 26400 info sentinel</code>

<code># sentinel</code>

<code>sentinel_masters:1</code>

<code>sentinel_tilt:0</code>

<code>sentinel_running_scripts:0</code>

<code>sentinel_scripts_queue_length:0</code>

<code>master0:name=master6400,status=ok,address=100.10.32.54:6400,slaves=1,sentinels=3</code>

<code>[root@localhost tmp]</code><code># ip a |grep eth0</code>

<code>2: eth0: &lt;broadcast,multicast,up,lower_up&gt; mtu 1500 qdisc mq state up qlen 1000</code>

<code>    </code><code>inet 100.10.32.54</code><code>/24</code> <code>brd 100.10.32.255 scope global eth0</code>

<code>    </code><code>inet 100.10.32.250</code><code>/24</code> <code>scope global secondary eth0</code>

四、測試

1、把主庫停掉

<code>redis-cli -h 100.10.32.54  -p 6400 </code><code>shutdown</code>

2、看從庫是否提升為主庫

<code>[root@localhost tmp]</code><code># redis-cli -h 100.10.32.55 -p 6400 info replication</code>

<code>connected_slaves:0</code>

<code>master_repl_offset:0</code>

<code>repl_backlog_active:0</code>

<code>repl_backlog_first_byte_offset:0</code>

<code>repl_backlog_histlen:0</code>

3、看vip是否漂移到100.10.32.55上

<code>    </code><code>inet 100.10.32.55</code><code>/24</code> <code>brd 100.10.32.255 scope global eth0</code>

4、看sentinel的監控狀态

<code>[root@localhost tmp]</code><code># redis-cli -p 26400 info  sentinel</code>

<code>master0:name=master6400,status=ok,address=100.10.32.55:6400,slaves=1,sentinels=3</code>

繼續閱讀