在一台centos7服务器上搭建redis集群以及哨兵sentinel

很早很早以前,具体时间有点忘记了,那个时候redis还没有高可用的方案,但是线上的又希望有redis的高可用,于是参考资料,搭建了一套基于haproxy和keepalived的方案,但是这套方案在测试的时候就发现了很大很大的问题,于是没有最终上线,只能等着redis官方的高可用版本。现在我们来看一下那个时候我写的一段内容:

当redis master宕机后,HaProxy会马上切换到redis slave上。
假如redis master再次启动后,这个时候问题出来了:
1)  HaProxy会自作聪明的再次将redis请求路由到redis master上。
2)  redis slave将会从redis master上再次同步数据,结果导致redis slave上的数据丢失。
为了应付这个问题,假设有redis master为r1,redis slave为r2,这个时候r1宕掉了,需要如下处理:
1)  千万不要马上重新启动r1,切记。
2)  用redis-cli 连接r2,发送命令。如:./redis-cli  SLAVEOF no one
3)  修改r1的配置文件,把r1设置为slave。如:slaveof  ip:port
4)  热配置HaProxy,将r2设置为主要路由,r1设置为failover路由。具体参见HaProxy的architecture.txt中的4.3 Hot Configuration
5)  启动r1。
上述步骤次序关键,不能搞错,搞错后就有可能导致redis上的数据完全丢失。

上述这段文字大家不用仔细看,只需要知道没有redis的哨兵模式时代是多少的痛苦。

重要知识点,很多同学因为下面这个知识点不明白,导致了出现问题

一开始,比如6379是主,6380是从,redis在进行设置的时候,是有主从设置的,那么在6380的配置文件中需要设置masterauth和slaveof这2个配置,而6379是不需要设置这2个配置的。
后来发生了failover,那6380就成了主,而6379就成了从。这个时候,sentinel会修改6379和6380的配置文件,slaveof还好说,sentinel会自动修改,但是6379要去访问6380,因为一开始在6379中是没有masterauth这个配置的,所以就会出现同步失败。
那为什么sentinel一开始不把6380这个从上设置的masterauth配置给记录下来?原因我没有去进一步探索,是不是涉及安全问题?

结论是:只有一开始的时候对某个redis来说是有主从固定配置的,后续一旦发生了failover,这些配置就会被自动改写。所以对于一开始的主并不能永远是主,那么在设置的时候,还需要参考从的一些配置,事先做好(这一点也会在我的后一篇文章《在docker中搭建redis集群以及哨兵sentinel》讲道),对于6379主,也需要设置好masterauth这个本应该是从的配置。

部署环境

  1. redis的哨兵模式和网络环境很有关系,当在docker、nat等环境下,需要进行额外的处理,详细见我的后一篇文章《在docker中搭建redis集群以及哨兵sentinel
  2. 本文只描述在一台服务器上部署,对于多台服务器结合我后面的那篇文章《在docker中搭建redis集群以及哨兵sentinel》(其实就是网络环境),过程也是同样的
  3. 假设该服务器的ip是:192.168.1.100,已经安装了 redis,版本比如是 5 以上的,其实 3.x.x 也是可以的,这个只需要查看一下redis官方文档即可。
  4. redis只搭建1主1从(网上很多都是1主2从,没有这个必要),3个sentinel(3个是必须的,否则在failover的时候就会出现一些不必要的问题)
  5. 该服务器已经开放了防火墙的端口给客户端来调用:6379,6380,26379,26380,26381
  6. 6379:redis server
    6380: redis server
    26379:redis sentinel
    26380:redis sentinel
    26381:redis sentinel

部署过程

部署redis-6379

1,mkdir -p /usr/local/redis-6379/data && cd /usr/local/redis-6379
2, vi redis.conf,内容如下:
requirepass “123456”
port 6379
daemonize yes
pidfile “/var/run/redis-6379.pid”
logfile “/usr/local/redis-6379/redis.log”
dir “/usr/local/redis-6379/data”
masterauth “123456” #这里是主,为什么还要设置从的配置,原因见上
3,redis-server redis.conf
4, redis-cli -p 6379
> auth 123456
> info
可以看到:
# Replication
role:master
connected_slaves:0
> exit

部署redis-6380

1,mkdir -p /usr/local/redis-6380/data && cd /usr/local/redis-6380
2, vi redis.conf,内容如下:
requirepass “123456”
port 6380
daemonize yes
pidfile “/var/run/redis-6380.pid”
logfile “/usr/local/redis-6380/redis.log”
dir “/usr/local/redis-6380/data”
masterauth “123456”
replicaof 192.168.1.100 6379 #replicaof == slaveof,在3.x.x中用 slaveof
3,redis-server redis.conf
4, redis-cli -p 6379
> auth 123456
> info
可以看到:
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.1.100,port=6380,state=online,offset=15680,lag=0
假如上面的slave0的ip不是192.168.1.100,而是另外一个ip,而这个ip又不是redis的客户端所能访问到的,那么就需要额外进行设置,详细见我的后一篇文章《》
> exit
5, redis-cli -p 6380
> auth 123456
> info
可以看到:
# Replication
role:slave
master_host:192.168.1.100
master_port:6379
可以看到6379是master,6380是slave,各自的配置都是正确的

部署redis-26379

1,mkdir -p /usr/local/redis-26379 && cd /usr/local/redis-26379
2, vi sentinel.conf,内容如下:
protected-mode no #允许外网访问
port 26379
daemonize yes
pidfile “/var/run/sentinel-26379.pid”
logfile “/usr/local/redis-26379/sentinel.log”
sentinel monitor mymaster 192.168.1.100 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 10000
sentinel auth-pass mymaster 123456
3,redis-sentinel sentinel.conf
4, redis-cli -p 26379
> info
可以看到:
# Sentinel
sentinel_masters:1
master0:name=mymaster,status=ok,address=192.168.1.100:6379,slaves=1,sentinels=3
> exit

部署redis-26380

1,mkdir -p /usr/local/redis-26380 && cd /usr/local/redis-26380
2, vi sentinel.conf,内容如下:
protected-mode no #允许外网访问
port 26380
daemonize yes
pidfile “/var/run/sentinel-26380.pid”
logfile “/usr/local/redis-26380/sentinel.log”
sentinel monitor mymaster 192.168.1.100 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 10000
sentinel auth-pass mymaster 123456
3,redis-sentinel sentinel.conf
4, redis-cli -p 26380
> info
可以看到:
# Sentinel
sentinel_masters:1
master0:name=mymaster,status=ok,address=192.168.1.100:6379,slaves=1,sentinels=3
# SENTINEL sentinels mymaster
可以看到到目前为止的2个sentinel,可以看到 sentinel 的ip,假如ip不是192.168.1.100,而是另外一个ip,而这个ip又不是redis的客户端所能访问到的,那么就需要额外进行设置,详细见我的后一篇文章《在docker中搭建redis集群以及哨兵sentinel
> exit

部署redis-26381

和redis-26380的一样,只需要把 26380 改成 26381

测试

咱们用 https://github.com/champbay/redis-sentinel 这个工程来进行测试
启动这个工程后,可以看到不断的往 redis 中插入 test-i 这样的值
然后,kill 掉 6379 这个 redis 进程,可以看到这个工程开始报错,大概过了5秒钟(因为我上面设置的是5秒钟),又恢复正常了,说明 redis sentinel已经起效了。
我们查看一下 6380 的配置文件,cat /usr/local/redis-6380/redis.conf,看到 slaveof 已经不见了,间接说明成为了主。通过redis-cli -p 6380看一下info,可以看到确实成为了master。
我们再次启动 6379,稍等一会,查看6379的配置文件,发现最后多了一行 slaveof 192.168.1.100 6380,(slaveof == replicaof),说明已经成为了从,从 redis-cli也能看出。

发表评论

邮箱地址不会被公开。 必填项已用*标注