Redis是一种key-value型数据库,基于内存,也可持久化,速度非常快。常用于做缓存。
redis单例试验完成。
redis的高可用方案通常有sentinel和Twemproxy,sentinel是redis自带的功能,这里我们选着用sentinel。
测试环境redis高可用至少需要三台主机。host1 192.168.30.1 #主节点master,可读写host2 192.168.30.2 #从节点slave,同步数据,只读不写host3 192.168.30.3 #从节点slave,同步数据,只读不写
配置主从关系首先,host2和host3一样安装redis。其次,修改host2和host3的配置文件如下:
…… slaveof 192.168.30.1 6379 slave-priority 100 #host3设置为200 ……最后,重启host2和host3的redis-server后,三台redis-server的主从关系已经建立。在host2或host3上运行测试可以看到:
$ redis-cli -h 192.168.30.2 -p 6379 192.168.30.2:6379> get test "hello" 192.168.30.2:6379> set test hey (error) READONLY You can't write against a read only slave. # 从节点只读模式 设置sentinel上一步中已经配置了3个redis-server的主从关系,master写入的数据会同步到两个slave。此时如果host1宕机,host2和host3无法写入数据,那么我们就需要将host2、host3中优先级高的那台提升为master。这就需要设置sentinel(哨兵)来监听redis-server,当sentinel判断主节点down的时候,sentinel会将其中一个slave提升为master。
在host1、host2、host3中各新建一个配置文件,内容相同,如下/etc/redis/sentinel.conf
daemonize yes bind 0.0.0.0 port 7000 logfile "/usr/local/redis/log/sentinel.log" sentinel monitor mymaster 192.168.30.1 6379 1 # sentinel monitor配置要监控的master是192.168.3.21,端口为6379, "mymaster"是别名,最后的“1”表示1个sentinel判断mymaster的SDOWN(subjectively down, 主观宕机)即可视为SDOWN。如果是2,那么必须有2个sentinel判断mymaster为SDOWN才能认为是SDOWN。 sentinel down-after-milliseconds mymaster 5000 # sentinel会向mymaster发送心跳PING来确认mymaster是否存活,如果mymaster在“一定时间范围”内不回应PONG 或者是回复了一个错误消息,那么这个sentinel会主观地(单方面地)认为mymaster已经不可用了(SDOWN)。而这个down-after-milliseconds就是用来指定这个“一定时间范围”的,单位是毫秒。 sentinel failover-timeout mymaster 900000 sentinel parallel-syncs mymaster 1 # 在发生failover主备切换时,这个选项指定了最多可以有多少个slave同时对新的master进行同步,这个数字越小,完成failover所需的时间就越长,但是如果这个数字越大,就意味着越多的slave因为replication而不可用。可以通过将这个值设为 1 来保证每次只有一个slave处于不能处理命令请求的状态sentinel主观地判断mymaster宕机(SDOWN)的时候不会立即failover主从切换,它需要再次确认,客观地认为mymaster宕机(ODOWN)后,才会自动进行主从切换。ODOWN,即objectively down,当sentinel认为mymaster主观宕机(SDOWN)时,会发起一个投票,之后当多数sentinel判断mymaster已经宕机时,才会得出结果ODOWN。那么这里判断mymaster ODOWN时就必须有两台sentinel投赞成票。这也是redis高可用至少需要3台主机的原因。
开启三个sentinel $ redis-sentinel /etc/redis/sentinel.conf $ ps -aux | grep redis root 11371 0.0 0.3 136920 7536 ? Ssl 04:45 0:04 redis-server 0.0.0.0:6379 root 12763 0.0 0.4 136916 7672 ? Ssl 06:35 0:00 redis-sentinel 0.0.0.0:7000 [sentinel] # 可以看到多了一个redis-sentinel进程这是再看一下sentinel.conf:
$ cat sentinel.conf protected-mode yes daemonize yes bind 0.0.0.0 port 7000 logfile "/usr/local/redis/log/sentinel.log" # 自动生成了一个uuid sentinel myid 05cd49d65cc61ceac3d12c23dd8c2d279ea83913 sentinel monitor mymaster 192.168.30.1 6379 1 sentinel down-after-milliseconds mymaster 5000 # Generated by CONFIG REWRITE dir "/etc/redis" sentinel failover-timeout mymaster 900000 sentinel config-epoch mymaster 0 sentinel leader-epoch mymaster 1 sentinel current-epoch 1 # 发现了两个slave sentinel known-slave mymaster 192.168.30.2 6379 sentinel known-slave mymaster 192.168.30.3 6379 # 发现了另外两个sentinel sentinel known-sentinel mymaster 192.168.30.2 7000 7d69bacd0e21a13c4fba9f84d9a3f17d7f4b5470 sentinel known-sentinel mymaster 192.168.30.3 7000 7d69bacd0e21a13c4fba9f84d9a3f17d7f4b5411 HA测试第一种情况,host2或host3宕机,这时master是active的,所以没有任何问题。
第二种情况,host1宕机,host2-sentinel和host3-sentinel会判断host1为ODOWN,按照优先级host2被提升为master。我们来模拟这个过程。Kill掉host1的redis-server和redis-sentinel进程:
$ ps -aux | grep redis root 11371 0.0 0.3 136920 7536 ? Ssl 04:45 0:04 redis-server 0.0.0.0:6379 root 12763 0.0 0.4 136916 7672 ? Ssl 06:35 0:00 redis-sentinel 0.0.0.0:7000 [sentinel] $ kill 11371 12763等待几秒后,看一下host2的redis-server
$ cat /etc/redis/redis.conf …… # slaveof 192.168.30.1 6379 #发现一行已经被注释掉了 …… host2的redis-server已经被提升master。 那么,host1在开启来会怎么样呢?$ redis-server /etc/redis/redis.conf$ redis-sentinel /etc/redis/sentinel.conf$ ps -aux | grep redisroot 11371 0.0 0.3 136920 7536 ? Ssl 04:45 0:04 redis-server 0.0.0.0:6379root 12763 0.0 0.4 136916 7672 ? Ssl 06:35 0:00 redis-sentinel 0.0.0.0:7000 [sentinel]
$ cat /etc/redis/redis.conf……slaveof 192.168.30.2 6379
