Redis-sentinel哨兵模式集群方案配置

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis-sentinel哨兵模式集群方案配置相关的知识,希望对你有一定的参考价值。

最近研究了redis的集群方案,第一个方案是创建 redis cluster,第二种方案就是用哨兵模式来进行主从替换以及故障恢复。


一、sentinel介绍


Redis Sentinel

Sentinel(哨兵)是用于监控redis集群中Master状态的工具,其已经被集成在redis2.4+的版本中。

Sentinel作用:

1):Master状态检测 
2):如果Master异常,则会进行Master-Slave切换,将其中一个Slave作为Master,将之前的Master作为Slave 
3):Master-Slave切换后,master_redis.conf、slave_redis.conf和sentinel.conf的内容都会发生改变,即master_redis.conf中会多一行slaveof的配置,sentinel.conf的监控目标会随之调换

Sentinel工作方式:

1):每个Sentinel以每秒钟一次的频率向它所知的Master,Slave以及其他 Sentinel 实例发送一个 PING 命令 
2):如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被 Sentinel 标记为主观下线。 
3):如果一个Master被标记为主观下线,则正在监视这个Master的所有 Sentinel 要以每秒一次的频率确认Master的确进入了主观下线状态。 
4):当有足够数量的 Sentinel(大于等于配置文件指定的值)在指定的时间范围内确认Master的确进入了主观下线状态, 则Master会被标记为客观下线 
5):在一般情况下, 每个 Sentinel 会以每 10 秒一次的频率向它已知的所有Master,Slave发送 INFO 命令 
6):当Master被 Sentinel 标记为客观下线时,Sentinel 向下线的 Master 的所有 Slave 发送 INFO 命令的频率会从 10 秒一次改为每秒一次 
7):若没有足够数量的 Sentinel 同意 Master 已经下线, Master 的客观下线状态就会被移除。 
若 Master 重新向 Sentinel 的 PING 命令返回有效回复, Master 的主观下线状态就会被移除

主观下线和客观下线:

主观下线:Subjectively Down,简称 SDOWN,指的是当前 Sentinel 实例对某个redis服务器做出的下线判断。 
客观下线:Objectively Down, 简称 ODOWN,指的是多个 Sentinel 实例在对Master Server做出 SDOWN 判断,并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后,得出的Master Server下线判断,然后开启failover.

通俗来讲就是: 

redis的sentinel系统用来管理多个redis服务器,可以实现一个功能上实现HA的集群。该系统主要执行四个任务:

①监控( Monitoring ): Redis Sentinel实时监控主服务器和从服务器运行状态。 
②提醒(notification): 当被监控的某个 Redis 服务器出现问题时, Redis Sentinel 可以向系统管理员发送通知, 也可以通过 API 向其他程序发送通知。 
③自动故障转移:如果一个master不正常运行了,哨兵可以启动一个故障转移进程,将一个slave升级成为master,其他的slave被重新配置使用新的master,并且应用程序使用Redis服务端通知的新地址。
④配置提供者:哨兵作为Redis客户端发现的权威来源:客户端连接到哨兵请求当前可靠的master的地址。如果发生故障,哨兵将报告新地址。


二、搭建redis-sentinel 集群环境

0、安装redis

操作系统:CentOS6.5 
wget http://download.redis.io/releases/redis-3.2.1.tar.gz
tar -xzf redis-3.2.1.tar.gz 
cd redis-3.2.1 
yum -y install gcc
make [MALLOC=libc]
make install 

或者
make PREFIX=/usr/local/redis install  #默认安装位置为/usr/local/bin
echo "export PATH=/usr/local/redis/bin:$PATH" >> /etc/profile.d/redis.sh
source /etc/profile.d/redis.sh

1、在/usr/local/ 下新建一个目录redis-sentinel,然后在此目录下新建7501/ 7502/ 7503/ 7504/ 7505/ 7506/ 7507/七个目录。

mkdir /usr/local/redis-sentinel 
mkdir /usr/local/redis-sentinel/{7501,7502,7503,7504,7505,7506,7507}

2、将redis安装目录下的reids.conf,拷贝到前4个目录下,分别命名为:redis-7501.conf redis-7502.conf redis-7503.conf redis-7504.conf

cp /root/redis-3.2.1/redis.conf /usr/local/redis-sentinel/7501/redis-7501.conf
cp /root/redis-3.2.1/redis.conf /usr/local/redis-sentinel/7502/redis-7502.conf
cp /root/redis-3.2.1/redis.conf /usr/local/redis-sentinel/7503/redis-7503.conf
cp /root/redis-3.2.1/redis.conf /usr/local/redis-sentinel/7504/redis-7504.conf

修改配置文件内容(以redis-7501.conf为例):

daemonize yes
pidfile /var/run/redis_7501.pid
port 7501
bind 10.10.172.191  #可选,默认就处理所有请求。
logfile "./redis-7501.log"
dir "/usr/local/redis-sentinel/7501"
redis配置密码的话,需要以下配置
masterauth "123456"
requirepass "123456"
appendonly yes

3、 将redis安装目录下的sentinel.conf拷贝到7505/ 7506/和7507/目录下分别命名: sentinel-7505.conf sentinel-7506.conf sentinel-7507.conf

cp /root/redis-3.2.1/sentinel.conf /usr/local/redis-sentinel/7505/sentinel-7505.conf
cp /root/redis-3.2.1/sentinel.conf /usr/local/redis-sentinel/7506/sentinel-7506.conf
cp /root/redis-3.2.1/sentinel.conf /usr/local/redis-sentinel/7507/sentinel-7507.conf

修改配置文件(以sentinel-7505.conf为例):

daemonize yes 
port 7505
#指定工作目录
dir "/usr/local/redis-sentinel/7505"
logfile "./sentinel.log" 
sentinel monitor mymaster 10.10.172.191 7501 2
#如果3s内mymaster无响应,则认为mymaster宕机了,默认30s  
sentinel down-after-milliseconds mymaster 3000   @30000  
sentinel parallel-syncs mymaster 1
#如果18秒后,master仍没活过来,则启动failover,,默认30s  
sentinel failover-timeout mymaster 10000 
#redis主节点密码  
sentinel auth-pass mymaster 123456  
注:我们稍后要启动四个redis实例,其中端口为7501的redis设为master,其他三个设为slave 。所以mymaster 后跟的是master的ip和端口,最后一个'2'代表我要启动只要有2个sentinel认为master下线,就认为该master客观下线,启动failover并选举产生新的master。通常最后一个参数不能多于启动的sentinel实例数。建议至少启动三台sentinel实例。

4、启动redis和sentinel 

分别启动4个redis实例:

redis-server /usr/local/redis-sentinel/7501/redis-7501.conf 
redis-server /usr/local/redis-sentinel/7502/redis-7502.conf  
redis-server /usr/local/redis-sentinel/7503/redis-7503.conf  
redis-server /usr/local/redis-sentinel/7504/redis-7504.conf

然后分别登陆7502 7503 7504三个实例,动态改变主从关系,成为7501的slave:

redis-cli -h 10.10.172.191 -p 7502
10.10.172.191:7502> SLAVEOF 10.10.172.191 7501
#这里也可以事先直接修改从实例redis文件追加slaveof 10.10.172.191 6379

查看主从状态:

10.10.172.191:7501> info replication
# Replication
role:master
connected_slaves:3
slave0:ip=10.10.172.191,port=7502,state=online,offset=127,lag=0
slave1:ip=10.10.172.191,port=7503,state=online,offset=127,lag=0
slave2:ip=10.10.172.191,port=7504,state=online,offset=127,lag=1
master_repl_offset:127
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:126

注:从库末尾会自动添加同步语句slaveof 10.10.172.191 7501。

以后台启动模式启动两个sentinel(哨兵): 

redis-sentinel /usr/local/redis-sentinel/7505/sentinel-7505.conf
redis-sentinel /usr/local/redis-sentinel/7506/sentinel-7506.conf
redis-sentinel /usr/local/redis-sentinel/7507/sentinel-7507.conf

查看redis进程状态

[[email protected] ~]# ps -ef|grep redis
root      2121     1  0 10:11 ?        00:00:00 redis-server 10.10.172.191:7501                            
root      2125     1  0 10:11 ?        00:00:00 redis-server 10.10.172.191:7502                            
root      2129     1  0 10:11 ?        00:00:00 redis-server 10.10.172.191:7503                            
root      2133     1  0 10:11 ?        00:00:00 redis-server 10.10.172.191:7504                            
root      2156     1  0 10:15 ?        00:00:00 redis-sentinel *:7505 [sentinel]                                
root      2160     1  0 10:15 ?        00:00:00 redis-sentinel *:7506 [sentinel]                                
root      2164     1  0 10:15 ?        00:00:00 redis-sentinel *:7507 [sentinel]                                
root      2169  1858  0 10:16 pts/0    00:00:00 grep redis

5、sentinel一些命令介绍 

要使用sentinel的命令,我们需要用redis-cli命令进入到sentinel:
redis-cli -h 10.10.172.191 -p 7505 -a 123456

①INFO 
sentinel的基本状态信息 
②SENTINEL masters | SENTINEL master mymaster
列出所有被监视的主服务器,以及这些主服务器的当前状态 
③ SENTINEL slaves mymaster
列出给定主服务器的所有从服务器,以及这些从服务器的当前状态 
④SENTINEL get-master-addr-by-name mymaster
返回给定名字的主服务器的 IP 地址和端口号 
⑤SENTINEL reset 
重置所有名字和给定模式 pattern 相匹配的主服务器。重置操作清除主服务器目前的所有状态, 包括正在执行中的故障转移, 并移除目前已经发现和关联的, 主服务器的所有从服务器和 Sentinel 。 
⑥SENTINEL failover 
当主服务器失效时, 在不询问其他 Sentinel 意见的情况下, 强制开始一次自动故障迁移,但是它会给其他sentinel发送一个最新的配置,其他sentinel会根据这个配置进行更新.

6、测试:

(1)登陆到 master:

# redis-cli -h 10.10.172.191 -p 7501 -a 123456
10.10.172.191:7501> info Replication  #列出Master的信息
10.10.172.191:7501> set name "zhangsan"
# redis-cli -h 10.10.172.191 -p 7502
10.10.172.191:7502> get name
"zhangsan"
10.10.172.191:7502> set age 24
(error) READONLY You can't write against a read only slave.

可以看到:我们的主从模式中,slave默认是只读。


(2)目前7501是master, 我们强制kill掉 7501 的进程以后,查看sentinel打出的日志信息: 

# tail -fn 10 /usr/local/redis-sentinel/7505/sentinel.log  
2156:X 28 Mar 10:25:54.960 # +new-epoch 2
2156:X 28 Mar 10:25:54.962 # +vote-for-leader a786b1a5a73cc8251ce888704024a14e417e33af 2
2156:X 28 Mar 10:25:54.992 # +odown master mymaster 10.10.172.191 7501 #quorum 3/2
2156:X 28 Mar 10:25:54.992 # Next failover delay: I will not start a failover before Wed Mar 28 10:26:15 2018
2156:X 28 Mar 10:25:56.037 # +config-update-from sentinel 10.10.172.191:7507 10.10.172.191 7507 @ mymaster 10.10.172.191 7501
2156:X 28 Mar 10:25:56.037 # +switch-master mymaster 10.10.172.191 7501 10.10.172.191 7502
2156:X 28 Mar 10:25:56.037 * +slave slave 10.10.172.191:7504 10.10.172.191 7504 @ mymaster 10.10.172.191 7502
2156:X 28 Mar 10:25:56.037 * +slave slave 10.10.172.191:7503 10.10.172.191 7503 @ mymaster 10.10.172.191 7502
2156:X 28 Mar 10:25:56.037 * +slave slave 10.10.172.191:7501 10.10.172.191 7501 @ mymaster 10.10.172.191 7502
2156:X 28 Mar 10:25:59.085 # +sdown slave 10.10.172.191:7501 10.10.172.191 7501 @ mymaster 10.10.172.191 7502

可以看到,sentinel已经将7502这个redis instance提升为新的master,稍后将7501这个实例启动,动态作为7501的slave,这样就手动恢复了redis 集群。同时也在redis-7501.conf文件末尾看到主从同步配置语句“slaveof 10.10.172.191 7502”。

停止并启动实例7501
kill -9 2121
redis-server /usr/local/redis-sentinel/7501/redis-7501.conf

查看当前redis主从状态
[[email protected] ~]# redis-cli -h 10.10.172.191 -p 7505
10.10.172.191:7505> INFO Sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
master0:name=mymaster,status=ok,address=10.10.172.191:7502,slaves=3,sentinels=3

连接redis主实例查看主从状态并创建key
[[email protected] ~]# redis-cli -h 10.10.172.191 -p 7502 -a 123456  
10.10.172.191:7502> info replication
# Replication
role:master
connected_slaves:3
slave0:ip=10.10.172.191,port=7504,state=online,offset=58539,lag=1
slave1:ip=10.10.172.191,port=7503,state=online,offset=58819,lag=0
slave2:ip=10.10.172.191,port=7501,state=online,offset=58679,lag=0
master_repl_offset:58959
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:58958
10.10.172.191:7502> keys *
1) "name"
10.10.172.191:7502> set age 24
OK
10.10.172.191:7502> exit

redis从实例上查看key
[[email protected] ~]# redis-cli -h 10.10.172.191 -p 7501 -a 123456
10.10.172.191:7501> keys *
1) "name"
2) "age"
10.10.172.191:7501> get age
"24"

7、开机自动启动redis和sentinel:

将以下代码追加到/etc/rc.local文件末尾 
/usr/local/bin/redis-server /usr/local/redis-sentinel/7501/redis-7501.conf 
/usr/local/bin/redis-server /usr/local/redis-sentinel/7502/redis-7502.conf  
/usr/local/bin/redis-server /usr/local/redis-sentinel/7503/redis-7503.conf  
/usr/local/bin/redis-server /usr/local/redis-sentinel/7504/redis-7504.conf
/usr/local/bin/redis-sentinel /usr/local/redis-sentinel/7505/sentinel-7505.conf
/usr/local/bin/redis-sentinel /usr/local/redis-sentinel/7506/sentinel-7506.conf
/usr/local/bin/redis-sentinel /usr/local/redis-sentinel/7507/sentinel-7507.conf


以上是关于Redis-sentinel哨兵模式集群方案配置的主要内容,如果未能解决你的问题,请参考以下文章

Redis-sentinel哨兵模式集群方案配置

Redis哨兵集群

redis的哨兵集群,自动切换主从库

#yyds干货盘点#--快速上手redis-sentinel(哨兵)

redis5.0.9哨兵模式redis-sentinel

redis5.0.9哨兵模式redis-sentinel