一、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.
SDOWN适合于Master和Slave,只要一个 Sentinel 发现Master进入了ODOWN, 这个 Sentinel 就可能会被其他 Sentinel 推选出, 并对下线的主服务器执行自动故障迁移操作。
ODOWN只适用于Master,对于Slave的 Redis 实例,Sentinel 在将它们判断为下线前不需要进行协商, 所以Slave的 Sentinel 永远不会达到ODOWN.
192.168.137.58 node01 #主,哨兵
192.168.137.59 node02 #从,哨兵
192.168.137.60 node03 #从,哨兵
链接:https://pan.baidu.com/s/15Ct8MXyH1ZsGYlGVPly76Q 提取码:qbwg
1、创建目录
mkdir /home/tools
mkdir /home/deploy
mkdir /home/deploy/redis
2、上软件包redis-3.2.1.tar.gz至/home/tools
3、安装redis
cd /home/tools
tar xf redis-3.2.11.tar.gz
cd redis-3.2.11/
make PREFIX=/home/deploy/redis install
cp /home/tools/redis-3.2.11/redis.conf /home/deploy/redis/bin/
cp /home/tools/redis-3.2.11/utils/redis_init_script /etc/init.d/redis
chmod 700 /etc/init.d/redis
echo 'PATH=$PATH:$HOME/bin:/home/deploy/redis/bin/' >> /etc/profile
source /etc/profile
redis-server --version
4、修改redis启动脚本
Vim /etc/init.d/redis
#!/bin/sh
# chkconfig: 2345 90 10
##修改运行级别--上面添加
#redis服务器监听的端口
REDISPORT=6379
#服务端所处位置
EXEC=/home/deploy/redis/bin/redis-server
#客户端位置
CLIEXEC=/home/deploy/redis/bin/redis-cli
#redis的PID文件位置,需要修改
PIDFILE=/var/run/redis_6379.pid
#redis的配置文件位置,需将${REDISPORT}修改为文件名
CONF="/home/deploy/redis/bin/redis.conf"
后面 就可以用/etc/init.d/redis stop停止redis服务了
如果是给redis设置了 密码,则需要给脚本指定密码;如下
$CLIEXEC -p $REDISPORT shutdown 这一行改为 –a "密码";
$CLIEXEC -a "123456" -p $REDISPORT shutdown
vim /home/deploy/redis/bin/redis.conf
1、允许所有访问
bind 127.0.0.1 à bind 0.0.0.0
2、设置密码
requirepass 123456
3、允许后台启动
daemonize no à daemonize yes
4、设置日志路径
Logfile " " à logfile "/home/deploy/redis/redis_6379.log"
5、设置dump.rdb路径
dir ./ à dir /home/deploy/redis/
在从服务器上操作:
vim /home/deploy/redis/bin/redis.conf
#如果为 yes,代表为只读状态,但并不表示客户端用集群方式以从节点为入口连入集群时,不可以进行 set 操作,且 set 操作的数据不会被放在从节点的槽上,会被放到某主节点的槽上。
slave-read-only yes
# slaveof <masterip> <masterport>
slaveof 192.168.137.58 6379
# masterauth <master-password>
masterauth 123456
临时解决
echo never > /sys/kernel/mm/transparent_hugepage/enabled
sysctl vm.overcommit_memory=1
永久解决方法:
将其写入/etc/rc.local文件中。
在主库上设置一个键值对
redis-cli
set test 12222
OK
在从库上去读该键
redis-cli
127.0.0.1:6379> get test
"12222"
如果在从库上,能取出设置的键值对,那么就表示以上操作都是成功的。
##注意:从库上是 set不了的
注意:三个节点都加上
vim /home/deploy/redis/bin/sentinel-26379.conf
port 26379
sentinel monitor mymaster 192.168.137.58 6379 2
sentinel down-after-milliseconds mymaster 3000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 10000
daemonize yes
dir "/tmp"
protected-mode no
logfile "/home/deploy/redis/sentinel-26379.log"
配置文件仅需要这些内容,如果redis 主从 有密码需要添加授权选项
#redis主节点密码
sentinel auth-pass mymaster 123456
port :当前Sentinel服务运行的端口
2. dir : Sentinel服务运行时使用的临时文件夹
3.sentinel monitor mymaster 192.168.137.58 6379 2:Sentinel去监视一个名为mymaster的主redis实例,这个主实例的IP地址为本机地址192.168.137.58,端口号为6379,而将这个主实例判断为失效至少需要2个 Sentinel进程的同意,只要同意Sentinel的数量不达标,自动failover就不会执行
4.sentinel down-after-milliseconds mymaster 30000:指定了Sentinel认为Redis实例已经失效所需的毫秒数。当实例超过该时间没有返回PING,或者直接返回错误,那么Sentinel将这个实例标记为主观下线。只有一个 Sentinel进程将实例标记为主观下线并不一定会引起实例的自动故障迁移:只有在足够数量的Sentinel都将一个实例标记为主观下线之后,实例才会被标记为客观下线,这时自动故障迁移才会执行
5.sentinel parallel-syncs mymaster 1:指定了在执行故障转移时,最多可以有多少个从Redis实例在同步新的主实例,在从Redis实例较多的情况下这个数字越小,同步的时间越长,完成故障转移所需的时间就越长
6.sentinel failover-timeout mymaster 180000:如果在该时间(ms)内未能完成failover操作,则认为该failover失败
7.sentinel notification-script <master-name> <script-path>:指定sentinel检测到该监控的redis实例指向的实例异常时,调用的报警脚本。该配置项可选,但是很常用
#注意三台机器,先node01、再node02和node03
redis-sentinel /home/deploy/redis/bin/sentinel-26379.conf
[root@node01 redis]# tailf -199 sentinel-26379.log
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 3.2.11 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in sentinel mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 26379
| `-._ `._ / _.-' | PID: 11237
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
11237:X 10 Dec 20:27:42.853 # Sentinel ID is d6c378e820404eec650f5e234e3df18704c83554
11237:X 10 Dec 20:27:42.853 # +monitor master mymaster 192.168.137.58 6379 quorum 2
11237:X 10 Dec 20:27:42.854 * +slave slave 192.168.137.60:6379 192.168.137.60 6379 @ mymaster 192.168.137.58 6379
11237:X 10 Dec 20:27:42.855 * +slave slave 192.168.137.59:6379 192.168.137.59 6379 @ mymaster 192.168.137.58 6379
11237:X 10 Dec 20:28:14.250 * +sentinel sentinel fe2e7fc9a4574db8bb30fb52b7c795e660b741b1 192.168.137.59 26379 @ mymaster 192.168.137.58 6379
11237:X 10 Dec 20:29:53.691 * +sentinel sentinel 9d2cafd155cc7fd03c17b089d7402176585533e0 192.168.137.60 26379 @ mymaster 192.168.137.58 6379
###注意:如果看到11237:X 10 Dec 20:28:14.250 * +sentinel sentinel fe2e7fc9a4574db8bb30fb52b7c795e660b741b1 192.168.137.59 26379 @ mymaster 192.168.137.58 6379
11237:X 10 Dec 20:29:53.691 * +sentinel sentinel 9d2cafd155cc7fd03c17b089d7402176585533e0 192.168.137.60 26379 @ mymaster 192.168.137.58 6379
则说明成功+ sentinel sentinel
如果是-号 ,则不成功
l 在主node01服务器上关闭redis
/etc/init.d/redis stop
在node查看日志
tailf -199 sentinel-26379.log
63552:X 10 Dec 20:34:54.435 # +sdown master mymaster 192.168.137.58 6379
63552:X 10 Dec 20:34:54.506 # +odown master mymaster 192.168.137.58 6379 #quorum 3/2
63552:X 10 Dec 20:34:54.506 # +new-epoch 1
63552:X 10 Dec 20:34:54.506 # +try-failover master mymaster 192.168.137.58 6379
63552:X 10 Dec 20:34:54.507 # +vote-for-leader fe2e7fc9a4574db8bb30fb52b7c795e660b741b1 1
63552:X 10 Dec 20:34:54.508 # d6c378e820404eec650f5e234e3df18704c83554 voted for fe2e7fc9a4574db8bb30fb52b7c795e660b741b1 1
63552:X 10 Dec 20:34:54.509 # 9d2cafd155cc7fd03c17b089d7402176585533e0 voted for fe2e7fc9a4574db8bb30fb52b7c795e660b741b1 1
63552:X 10 Dec 20:34:54.597 # +elected-leader master mymaster 192.168.137.58 6379
63552:X 10 Dec 20:34:54.597 # +failover-state-select-slave master mymaster 192.168.137.58 6379
63552:X 10 Dec 20:34:54.655 # +selected-slave slave 192.168.137.59:6379 192.168.137.59 6379 @ mymaster 192.168.137.58 6379
63552:X 10 Dec 20:34:54.655 * +failover-state-send-slaveof-noone slave 192.168.137.59:6379 192.168.137.59 6379 @ mymaster 192.168.137.58 6379
63552:X 10 Dec 20:34:54.713 * +failover-state-wait-promotion slave 192.168.137.59:6379 192.168.137.59 6379 @ mymaster 192.168.137.58 6379
63552:X 10 Dec 20:34:54.814 # +promoted-slave slave 192.168.137.59:6379 192.168.137.59 6379 @ mymaster 192.168.137.58 6379
63552:X 10 Dec 20:34:54.814 # +failover-state-reconf-slaves master mymaster 192.168.137.58 6379
63552:X 10 Dec 20:34:54.889 * +slave-reconf-sent slave 192.168.137.60:6379 192.168.137.60 6379 @ mymaster 192.168.137.58 6379
63552:X 10 Dec 20:34:55.588 # -odown master mymaster 192.168.137.58 6379
63552:X 10 Dec 20:34:55.862 * +slave-reconf-inprog slave 192.168.137.60:6379 192.168.137.60 6379 @ mymaster 192.168.137.58 6379
63552:X 10 Dec 20:34:55.862 * +slave-reconf-done slave 192.168.137.60:6379 192.168.137.60 6379 @ mymaster 192.168.137.58 6379
63552:X 10 Dec 20:34:55.945 # +failover-end master mymaster 192.168.137.58 6379
63552:X 10 Dec 20:34:55.945 # +switch-master mymaster 192.168.137.58 6379 192.168.137.59 6379
63552:X 10 Dec 20:34:55.946 * +slave slave 192.168.137.60:6379 192.168.137.60 6379 @ mymaster 192.168.137.59 6379
63552:X 10 Dec 20:34:55.946 * +slave slave 192.168.137.58:6379 192.168.137.58 6379 @ mymaster 192.168.137.59 6379
63552:X 10 Dec 20:34:58.981 # +sdown slave 192.168.137.58:6379 192.168.137.58 6379 @ mymaster 192.168.137.59 6379
###从日志可以看出,master node01宕机,master已经从node01切换为node02
l 在从库上查看状态:
[root@node03 bin]# redis-cli -p 6379 -a 123456
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.137.59
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:204885
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6379>
可以看出node02已经从从库升级为master
l 启动node01 old mater
[root@node01 redis]# /etc/init.d/redis start
查看日志
tailf -199 sentinel-26379.log
11237:X 10 Dec 20:54:54.960 * +convert-to-slave slave 192.168.137.58:6379 192.168.137.58 6379 @ mymaster 192.168.137.59 6379
###由日志可以看出
Node01 已经加入node02(现在的master节点)变为slove节点。
[root@node01 redis]# redis-cli -p 6379 -a gichain123456
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.137.59
master_port:6379
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:1
master_link_down_since_seconds:1544446844
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6379>
l 停掉node02 ;master升级为node03
l 开启node02;node02加入node03(现在的master节点)
l 关闭node03;master切换为node02,没有切换到node01;这是为什么呢?
此时在node01 redis.conf 加入
# masterauth <master-password>
masterauth 123456
不然主是切换不到node01的
1):首次启动时,必须先启动Master
2):Sentinel 只在 server 端做主从切换,app端要自己开发(例如Jedis库的SentinelJedis,能够监控Sentinel的状态)
3):若Master已经被判定为下线,Sentinel已经选择了新的Master,也已经将old Master改成Slave,但是还没有将其改成new Master。若此时重启old Master,则Redis集群将处于无Master状态,此时只能手动修改配置文件,然后重新启动集群
到此redis集群配置完毕
Java连接redis sentinel,哨兵模式下不要直连master,要连sentinel,master挂了才会自动故障转移
String masterName = "mymaster";
Set<String> sentinelSet =new HashSet<String>();
sentinelSet.add("node01:26379");
sentinelSet.add("node02:26379");
sentinelSet.add("node03:26379");
JedisSentinelPool sentinelPool = new JedisSentinelPool(masterName,sentinelSet,poolConfig,timeout);
Jedis jedis = null;
try{
jedis = sentinelPool.getResource();
}catch(Exception e){
logger.error(e.getMessage(),e);
}finally{
if(jedis != null){
jedis.close();
}
}