一步步实现redis+sentinel双机热备

前言

前些天一直在忙线上环境部署的事情,初步想的是,nginx(keepalive双机热备)+3(tomcat)+2redis(双机热备),可是后来因为阿里云服务器经典网络不提供虚拟IP,没法使用keepalive,nginx双机热备只能暂时先放弃,退而求其次,采用nginx+3tomcat+2redis(双机热备)。nginx+tomcat因为以前配置过,因此重点就落在redis双机热备上,毕竟是线上系统,适当的抗灾能力仍是须要的,咱可不能像测试系统那么去玩,不然黑锅就有的背了,毕竟码代码赚点生活费也不容易。nginx

在网上也查了一些资料,redis集群实现大概有如下几种方式:redis

1.redis-cluster,官方提供的集群搭建方案(过于重量级,比较适合后期数据量较大的时候的使用)数据库

2.redis+keepalive(因为咱们使用的阿里云服务器不支持虚拟IP,因此这套方案也就夭折了)vim

3.redis+zookeeper(须要引入zookeeper,对现有代码变更较大)tomcat

4.redis+sentinel(redis自带监控中间件)(代码变更小,配置少,并且能知足双机热备的需求)bash

基于咱们目前的状况以及需求,通过初略对比,咱们团队决定选用第四种方案redis+sentinel实现双机热备。服务器

准备工做

1.安装redis-001(主)

$ wget http://download.redis.io/releases/redis-3.2.3.tar.gz
$ tar xzf redis-3.2.3.tar.gz
$ mv redis-3.2.3 redis-001
$ cd redis-001
$ make

2.安装redis-002(从)

$ wget http://download.redis.io/releases/redis-3.2.3.tar.gz
$ tar xzf redis-3.2.3.tar.gz
$ mv redis-3.2.3 redis-002
$ cd redis-002
$ make

3.修改redis-002端口为6380

$ cd /usr/tools/redis-002/
$ vim redis.conf
...找到port 6379改成6380...

4.修改redis默认配置

a.关闭ip绑定,注释redis.conf中bind 127.0.0.1网络

b.关闭保护模式,将protected-mode yes改成protected-mode no架构

5.启动redis-001,redis-002

$ cd tools/redis-001/
$ ./src/redis-server redis.conf

出现如下信息就表示启动成功了:socket

12513:M 09 Oct 11:15:49.061 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
12513:M 09 Oct 11:15:49.061 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
12513:M 09 Oct 11:15:49.061 * DB loaded from disk: 0.000 seconds
12513:M 09 Oct 11:15:49.061 * The server is now ready to accept connections on port 6379

redis主从复制

1.redis 复制的特色

    1). 同一个Master能够同步多个Slaves。
    2). Slave一样能够接受其它Slaves的链接和同步请求,这样能够有效的分载Master的同步压力。所以咱们能够将Redis的Replication架构视为图结构。
    3). Master Server是以非阻塞的方式为Slaves提供服务。因此在Master-Slave同步期间,客户端仍然能够提交查询或修改请求。
    4). Slave Server一样是以非阻塞的方式完成数据同步。在同步期间,若是有客户端提交查询请求,Redis则返回同步以前的数据。
    5). 为了分载Master的读操做压力,Slave服务器能够为客户端提供只读操做的服务,写服务仍然必须由Master来完成。即使如此,系统的伸缩性仍是获得了很大的提升。
    6). Master能够将数据保存操做交给Slaves完成,从而避免了在Master中要有独立的进程来完成此操做。

2.redis复制原理

    在Slave启动并链接到Master以后,它将主动发送一个SYNC命令。此后Master将启动后台存盘进程,同时收集全部接收到的用于修改数据集的命令,在后台进程执行完毕后,Master将传送整个数据库文件到Slave,以完成一次彻底同步。而Slave服务器在接收到数据库文件数据以后将其存盘并加载到内存中。此后,Master继续将全部已经收集到的修改命令,和新的修改命令依次传送给Slaves,Slave将在本次执行这些数据修改命令,从而达到最终的数据同步。
    若是Master和Slave之间的连接出现断连现象,Slave能够自动重连Master,可是在链接成功以后,一次彻底同步将被自动执行。

3.redis主从配置

前面也说了,redis主从配置很简单,只须要一个slaveof就能够搞定。

链接redis-002,执行slaveof 192.168.231.130 6379:

C:\Users\lenovo\Desktop\redis>D:
D:\>cd D:\Program Files\Redis-x64-3.0.5
D:\Program Files\Redis-x64-3.0.5>redis-cli.exe -h 192.168.231.130 -p 6380
192.168.231.130:6380> slaveof 192.168.231.130 6379
OK
192.168.231.130:6380>

执行完成后,能够看到服务器上redis-001控制台输出如下内容:

12513:M 09 Oct 11:15:49.061 * DB loaded from disk: 0.000 seconds
12513:M 09 Oct 11:15:49.061 * The server is now ready to accept connections on port 6379
12513:M 09 Oct 11:41:59.371 * Slave 192.168.231.130:6380 asks for synchronization
12513:M 09 Oct 11:41:59.371 * Full resync requested by slave 192.168.231.130:6380
12513:M 09 Oct 11:41:59.371 * Starting BGSAVE for SYNC with target: disk
12513:M 09 Oct 11:41:59.372 * Background saving started by pid 13673
13673:C 09 Oct 11:41:59.388 * DB saved on disk
13673:C 09 Oct 11:41:59.388 * RDB: 6 MB of memory used by copy-on-write
12513:M 09 Oct 11:41:59.462 * Background saving terminated with success
12513:M 09 Oct 11:41:59.462 * Synchronization with slave 192.168.231.130:6380 succeeded

redis-002控制台输出:

13581:S 09 Oct 11:41:59.361 * Connecting to MASTER 192.168.231.130:6379
13581:S 09 Oct 11:41:59.370 * MASTER <-> SLAVE sync started
13581:S 09 Oct 11:41:59.370 * Non blocking connect for SYNC fired the event.
13581:S 09 Oct 11:41:59.371 * Master replied to PING, replication can continue...
13581:S 09 Oct 11:41:59.371 * Partial resynchronization not possible (no cached master)
13581:S 09 Oct 11:41:59.374 * Full resync from master: e2f4e2608956ea6392482c2e0a9429efdebd2b53:1
13581:S 09 Oct 11:41:59.462 * MASTER <-> SLAVE sync: receiving 76 bytes from master
13581:S 09 Oct 11:41:59.463 * MASTER <-> SLAVE sync: Flushing old data
13581:S 09 Oct 11:41:59.463 * MASTER <-> SLAVE sync: Loading DB in memory
13581:S 09 Oct 11:41:59.463 * MASTER <-> SLAVE sync: Finished with success

可是这样作的话,重启redis-002后又会复原,因此一般咱们会直接修改redis-002配置文件redis.conf,在末尾加上slaveof 192.168.231.130 6379部分,就永久有效了。

如今咱们往redis-001中写入数据,就能够从redis-002中查询出来了,咱们来测试一下,往redis-001中写入key为name,value为osc的数据。

192.168.231.130:6379> set name osc
OK
192.168.231.130:6379> keys *
1) "name"
192.168.231.130:6379>

查询redis-002中的数据,会发现一样存在name的key,而且值为osc 

192.168.231.130:6380> keys *
1) "name"
192.168.231.130:6380> get name
"osc"
192.168.231.130:6380>

到目前为止,redis主从复制已经配置成功了,接下来就要开始重点工做,配置双机热备。

redis+sentinel双机热备

1.理论概念

    双机热备特指基于高可用系统中的两台服务器的热备(或高可用),因两机高可用在国内使用较多,故得名双机热备,双机高可用按工做中的切换方式分为:主-备方式(Active-Standby方式)和双主机方式(Active-Active方式),主-备方式即指的是一台服务器处于某种业务的激活状态(即Active状态),另外一台服务器处于该业务的备用状态(即Standby状态)。而双主机方式即指两种不一样业务分别在两台服务器上互为主备状态(即Active-Standby和Standby-Active状态)。

大白话就是,当主服务器挂了以后,从服务器立马切换为主服务器继续工做,当原先主服务器修复完善启动后,会自动充当从服务器的角色继续工做。这样就很好的避免了,因为一台主机出现故障,系统挂点的现象出现。

Sentinel(哨兵)是用于监控redis集群中Master状态的工具,已经集成在redis官方版本中,能够直接配置使用。

2.Sentinel命令

       PING :返回 PONG 。
       SENTINEL masters :列出全部被监视的主服务器,以及这些主服务器的当前状态;
       SENTINEL slaves <master name> :列出给定主服务器的全部从服务器,以及这些从服务器的当前状态;
       SENTINEL get-master-addr-by-name <master name> : 返回给定名字的主服务器的 IP 地址和端口号。 若是这个主服务器正在执行故障转移操做, 或者针对这个主服务器的故障转移操做已经完成, 那么这个命令返回新的主服务器的 IP 地址和端口号;
       SENTINEL reset <pattern> : 重置全部名字和给定模式 pattern 相匹配的主服务器。 pattern 参数是一个 Glob 风格的模式。 重置操做清楚主服务器目前的全部状态, 包括正在执行中的故障转移, 并移除目前已经发现和关联的, 主服务器的全部从服务器和 Sentinel ;
       SENTINEL failover <master name> : 当主服务器失效时, 在不询问其余 Sentinel 意见的状况下, 强制开始一次自动故障迁移。

客户端能够经过SENTINEL get-master-addr-by-name <master name>获取当前的主服务器IP地址和端口号,以及SENTINEL slaves <master name>获取全部的Slaves信息

3.双机热备配置

a.关闭redis-001与redis-002

b.在redis-001和redis-002配置sentinel.conf中加上如下配置信息:

sentinel monitor mymaster 192.168.231.130 6379 1

c.修改redis-002 sentinel.conf监听端口:

​$ cd /usr/tools/redis-002/
$ vim sentinel.conf
...找到port 26379改成26380...
port 26380

d.分别启动redis-001(主)与redis-002(从),redis 服务和sentinel服务

​$ cd /usr/tools/redis-002/
$ ./src/redis-server redis.conf
$ ./src/redis-sentinel sentinel.conf
​$ cd /usr/tools/redis-001/
$ ./src/redis-server redis.conf
$ ./src/redis-sentinel sentinel.conf

此时在主从redis,sentinel控制台会出现如下信息:

14677:X 09 Oct 14:04:49.633 # Sentinel ID is 7b8fdc1e5e47426b0d62a3ddd22ede0fd712f452
14677:X 09 Oct 14:04:49.633 # +monitor master mymaster 192.168.231.130 6379 quorum 1
14677:X 09 Oct 14:04:49.634 * +slave slave 192.168.231.130:6380 192.168.231.130 6380 @ mymaster 192.168.231.130 6379
14677:X 09 Oct 14:05:53.727 * +sentinel sentinel 31e660153984b606951c564395bdc8e193943f0b 192.168.231.130 26380 @ mymaster 192.168.231.130 6379

e.测试结果:

链接主服务器sentinel,注意端口是sentinel.conf中配置的端口

根据前面描述的sentinel命令查询主服务器信息:

192.168.231.130:26379> SENTINEL masters
1)  1) "name"
    2) "mymaster"
    3) "ip"
    4) "192.168.231.130"
    5) "port"
    6) "6379"
    7) "runid"
    8) "fafb94fe9bff119e8a97f9183e3bcb5561933631"
    9) "flags"
   10) "master"
   11) "link-pending-commands"
   12) "0"
   13) "link-refcount"
   14) "1"
   15) "last-ping-sent"
   16) "0"
   17) "last-ok-ping-reply"
   18) "671"
   19) "last-ping-reply"
   20) "671"
   21) "down-after-milliseconds"
   22) "10000"
   23) "info-refresh"
   24) "4904"
   25) "role-reported"
   26) "master"
   27) "role-reported-time"
   28) "205675"
   29) "config-epoch"
   30) "0"
   31) "num-slaves"
   32) "1"
   33) "num-other-sentinels"
   34) "1"
   35) "quorum"
   36) "1"
   37) "failover-timeout"
   38) "180000"
   39) "parallel-syncs"
   40) "1"
192.168.231.130:26379>

查询从服务器信息:

192.168.231.130:26379> SENTINEL slaves mymaster
1)  1) "name"
    2) "192.168.231.130:6380"
    3) "ip"
    4) "192.168.231.130"
    5) "port"
    6) "6380"
    7) "runid"
    8) "feabcfa65e69778e877ca0bd95adb9d642f6522f"
    9) "flags"
   10) "slave"
   11) "link-pending-commands"
   12) "0"
   13) "link-refcount"
   14) "1"
   15) "last-ping-sent"
   16) "0"
   17) "last-ok-ping-reply"
   18) "928"
   19) "last-ping-reply"
   20) "928"
   21) "down-after-milliseconds"
   22) "10000"
   23) "info-refresh"
   24) "7332"
   25) "role-reported"
   26) "slave"
   27) "role-reported-time"
   28) "388802"
   29) "master-link-down-time"
   30) "0"
   31) "master-link-status"
   32) "ok"
   33) "master-host"
   34) "192.168.231.130"
   35) "master-port"
   36) "6379"
   37) "slave-priority"
   38) "100"
   39) "slave-repl-offset"
   40) "472844"
192.168.231.130:26379>

如今,咱们来关闭端口为6379主redis-001服务器,看看会出现什么状况,此时redis-002控制台会出现如下信息:

14735:S 09 Oct 14:15:47.618 # Error condition on socket for SYNC: Connection refused
14735:S 09 Oct 14:15:48.628 * Connecting to MASTER 192.168.231.130:6379
14735:S 09 Oct 14:15:48.628 * MASTER <-> SLAVE sync started
14735:S 09 Oct 14:15:48.628 # Error condition on socket for SYNC: Connection refused
14735:S 09 Oct 14:15:49.638 * Connecting to MASTER 192.168.231.130:6379
14735:S 09 Oct 14:15:49.638 * MASTER <-> SLAVE sync started
14735:S 09 Oct 14:15:49.638 # Error condition on socket for SYNC: Connection refused
14735:S 09 Oct 14:15:50.648 * Connecting to MASTER 192.168.231.130:6379
14735:S 09 Oct 14:15:50.648 * MASTER <-> SLAVE sync started
14735:S 09 Oct 14:15:50.648 # Error condition on socket for SYNC: Connection refused
14735:S 09 Oct 14:15:51.659 * Connecting to MASTER 192.168.231.130:6379
14735:S 09 Oct 14:15:51.659 * MASTER <-> SLAVE sync started
14735:S 09 Oct 14:15:51.659 # Error condition on socket for SYNC: Connection refused
14735:S 09 Oct 14:15:52.669 * Connecting to MASTER 192.168.231.130:6379
14735:S 09 Oct 14:15:52.669 * MASTER <-> SLAVE sync started
14735:S 09 Oct 14:15:52.669 # Error condition on socket for SYNC: Connection refused
14735:M 09 Oct 14:15:53.459 * Discarding previously cached master state.
14735:M 09 Oct 14:15:53.459 * MASTER MODE enabled (user request from 'id=5 addr=192.168.231.130:53187 fd=7 name=sentinel-7b8fdc1e-cmd age=23 idle=0 flags=x db=0 sub=0 psub=0 multi=3 qbuf=0 qbuf-free=32768 obl=36 oll=0 omem=0 events=r cmd=exec')
14735:M 09 Oct 14:15:53.463 # CONFIG REWRITE executed with success.

从日志能够看出,服务器会通过屡次链接主服务器失败后,断定主服务器故障,会对配置文件进行重写(CONFIG REWRITE executed with success),咱们再去看看从服务器的配置文件redis.conf,会发现以前在末尾加上的slaveof 192.168.231.130 6379不见了,这就说明当sentinel监测到主服务器挂掉以后,自动将从服务器切换为主服务器。

咱们再来看看主从服务器sentinel控制台输出了信息:

主sentinel:

14677:X 09 Oct 14:15:54.384 # +promoted-slave slave 192.168.231.130:6380 192.168.231.130 6380 @ mymaster 192.168.231.130 6379
14677:X 09 Oct 14:15:54.384 # +failover-state-reconf-slaves master mymaster 192.168.231.130 6379
14677:X 09 Oct 14:15:54.456 # +failover-end master mymaster 192.168.231.130 6379
14677:X 09 Oct 14:15:54.456 # +switch-master mymaster 192.168.231.130 6379 192.168.231.130 6380
14677:X 09 Oct 14:15:54.456 * +slave slave 192.168.231.130:6379 192.168.231.130 6379 @ mymaster 192.168.231.130 6380
14677:X 09 Oct 14:16:04.479 # +sdown slave 192.168.231.130:6379 192.168.231.130 6379 @ mymaster 192.168.231.130 6380

从sentinel:

14688:X 09 Oct 14:15:53.223 # +sdown master mymaster 192.168.231.130 6379
14688:X 09 Oct 14:15:53.223 # +odown master mymaster 192.168.231.130 6379 #quorum 1/1
14688:X 09 Oct 14:15:53.223 # Next failover delay: I will not start a failover before Sun Oct  9 14:21:53 2016
14688:X 09 Oct 14:15:54.461 # +config-update-from sentinel 7b8fdc1e5e47426b0d62a3ddd22ede0fd712f452 192.168.231.130 26379 @ mymaster 192.168.231.130 6379
14688:X 09 Oct 14:15:54.461 # +switch-master mymaster 192.168.231.130 6379 192.168.231.130 6380
14688:X 09 Oct 14:15:54.461 * +slave slave 192.168.231.130:6379 192.168.231.130 6379 @ mymaster 192.168.231.130 6380
14688:X 09 Oct 14:16:04.483 # +sdown slave 192.168.231.130:6379 192.168.231.130 6379 @ mymaster 192.168.231.130 6380

从上面日志信息能够看出,主从确实已经切换成功了,最后咱们来看看实际状况是否是那样的,打开命令行执行查询主从信息命令,看看会出现什么结果:

192.168.231.130:26379> SENTINEL get-master-addr-by-name mymaster
1) "192.168.231.130"
2) "6380"
192.168.231.130:26379>
192.168.231.130:26379> SENTINEL masters
1)  1) "name"
    2) "mymaster"
    3) "ip"
    4) "192.168.231.130"
    5) "port"
    6) "6380"
    7) "runid"
    8) "bb4fe3dece04db30c29f6650f1edd4d3689da751"
    9) "flags"
   10) "master"
   11) "link-pending-commands"
   12) "0"
   13) "link-refcount"
   14) "1"
   15) "last-ping-sent"
   16) "0"
   17) "last-ok-ping-reply"
   18) "14"
   19) "last-ping-reply"
   20) "14"
   21) "down-after-milliseconds"
   22) "10000"
   23) "info-refresh"
   24) "4648"
   25) "role-reported"
   26) "master"
   27) "role-reported-time"
   28) "847746"
   29) "config-epoch"
   30) "1"
   31) "num-slaves"
   32) "1"
   33) "num-other-sentinels"
   34) "1"
   35) "quorum"
   36) "1"
   37) "failover-timeout"
   38) "180000"
   39) "parallel-syncs"
   40) "1"
192.168.231.130:26379>

到这里基本已经部署完毕了,再去启动原先主服务器redis-001,会发现此时的redis-001变成了从服务器,接下来的内容因为与前面重复较多,我就不演示了。

注意事项

1.一步一步来,先配置主从复制,再配置主从切换

2.启动顺序不要弄错了,先启动主服务器的redis与sentinel,再启动从服务器redis与sentinel,若是遇到失败状况,因为sentinel启动后会自动修改和生成部分配置信息,为避免冲突浪费时间,建议直接删除配置文件,从新配置。

3.若是redis有密码的话,须要在主从服务器redis.conf中都加上:

masterauth <password>

以及在主从服务器sentinel.conf加上:

sentinel auth-pass mymaster <password>

二者密码一致。

4.daemonize yes,启用保护进程
protected-mode no,关闭保护模式

另附

具体程序代码修改部分,能够参考《JedisSentinelPool的相关配置与操做》

《福利送上,未满十八岁勿点》

相关文章
相关标签/搜索