人的一生犹如负重致远,不可急躁。 以不自由为常事,则不觉不足。 心生欲望时,应回顾贫困之日。 心怀宽恕,视怒如敌,则能无视长久。 只知胜而不知敗,必害其身。 责人不如责己,不及胜于过之。
分类: NOSQL
2017-03-22 10:24:49
redis系列sentinel
1 sentinel
Redis Sentinel(哨兵)是用于监控redis集群中Master和Slave状态的工具,其已经被集成在redis2.4+的版本中。 包括Monitor(监控)、Notification(通知)和Automatic failover(自动故障迁移)和等主要功能。
1.1 监控
Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
1.2 通知
当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过API 向管理员或者其他应用程序发送通知。
1.3 自动故障迁移
当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。
1.4 Sentinel分布式系统
Redis Sentinel 是一个分布式系统, 你可以在一个架构中运行多个 Sentinel 进程(progress), 这些进程使用流言协议(gossip protocols)来接收关于主服务器是否下线的信息, 并使用投票协议(agreement protocols)来决定是否执行自动故障迁移,以及选择哪个从服务器作为新的主服务器。
虽然Redis Sentinel释出为一个单独的可执行文件redis-sentinel,但实际上它只是一个运行在特殊模式下的Redis服务器,你可以在启动一个普通 Redis 服务器时通过给定 --sentinel 选项来启动Redis Sentinel。
命令如下:
$ ./src/redis-server --sentinel
2 Redis Sentinel工作方式
1、每个Sentinel以每秒钟一次的频率向它所知的Master,Slave以及其他 Sentinel 实例发送一个 PING 命令。
2、如果一个Sentinel实例距离最后一次有效回复 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的客观下线状态就会被移除。
8、若Master重新向Sentinel的PING命令返回有效回复, Master的主观下线状态就会被移除。
3 主观下线和客观下线
3.1 主观下线
主观下线(Subjectively Down)简称 SDOWN,指的是当前Sentinel实例对某个redis服务器做出的下线判断。
3.2 客观下线
客观下线(Objectively Down)简称ODOWN,指的是多个Sentinel实例在对Master Server做出SDOWN判断,并且通过SENTINEL is-master-down-by-addr命令互相交流之后,得出的Master Server下线判断,然后开启failover(故障迁移)。
3.3 SDOWN和ODOWN比较
1、SDOWN适合于Master和Slave,只要一个 Sentinel 发现Master进入了ODOWN, 这个Sentinel就可能会被其他Sentinel推选出,并对下线的主服务器执行自动故障迁移操作。
2、ODOWN只适用于Master,对于Slave的Redis实例,Sentinel在将它们判断为下线前不需要进行协商,所以Slave的Sentinel永远不会达到ODOWN。
4 sentinel配置和日志
4.1 sentinel配置说明
sentinel配置的配置项如下:
1、port 16379
#指定sentinel端口号
2、daemonize yes
#是不是守护进程方式启动
3、sentinel monitor mastercache 10.1.51.248 6379 2
# mastercache来表示给要监控的redis server
# 10.1.51.248表示IP地址
# 6379表示端口号
# 2表示两个sentinel才能判断为主管下线才能客观下线
4、sentinel down-after-milliseconds mastercache 10000
# 30000表示向master发出ping,最大响应时间,如果超过则认为主观下线。
5、sentinel parallel-syncs mastercache 1
# 在进行故障转移时,运行多少个slave进行数据备份同步(越少越快)
6、sentinel failover-timeout mastercache 30000
# 出现failover时下一个sentinel与上一个sentinel对同一个master监测的时间间隔
7、pidfile "/data/ sentinel/sentinel.pid"
# 当以守护进程启动的时候进程pid保存的文件
8、loglevel notice
# 日志级别 (debug、verbose、notice、warning)
9、logfile "/data/sentinel/sentinel.log"
# 日志的保存文件
4.2 sentinel日志
1、+reset-master
#主服务器已被重置
2、+slave
#一个新的从服务器已经被 Sentinel 识别并关联。
3、+failover-state-reconf-slaves
#故障转移状态切换到了reconf-slaves 状态。
4、+failover-detected
#另一个Sentinel开始了一次故障转移操作,或者一个从服务器转换成了主服务器。
5、+slave-reconf-sent
#领头(leader)的 Sentinel 向实例发送了SLAVEOF命令,为实例设置新的主服务器。
6、+slave-reconf-inprog
#实例正在将自己设置为指定主服务器的从服务器,但相应的同步过程仍未完成。
7、+slave-reconf-done
#从服务器已经成功完成对新主服务器的同步。
8、-dup-sentinel
#对给定主服务器进行监视的一个或多个Sentinel已经因为重复出现而被移除,
#当Sentinel实例重启的时候,就会出现这种情况。
9、+sentinel
#一个监视给定主服务器的新Sentinel已经被识别并添加。
10、+sdown
#给定的实例现在处于主观下线状态。
11、-sdown
#给定的实例已经不再处于主观下线状态。
12、+odown
#给定的实例现在处于客观下线状态。
13、-odown
#给定的实例已经不再处于客观下线状态。
14、+new-epoch
#当前的纪元(epoch)已经被更新。
15、+try-failover
#一个新的故障迁移操作正在执行中,
#等待被大多数Sentinel选中(waiting to be elected by the majority)。
16、+elected-leader
#赢得指定纪元的选举,可以进行故障迁移操作了。
17、+failover-state-select-slave
#故障转移操作现在处于select-slave状态
# Sentinel正在寻找可以升级为主服务器的从服务器。
18、no-good-slave
#Sentinel 操作未能找到适合进行升级的从服务器。
#Sentinel 会在一段时间之后再次尝试寻找合适的从服务器来进行升级,
#又或者直接放弃执行故障转移操作。
19、selected-slave
#Sentinel顺利找到适合进行升级的从服务器。
20、failover-state-send-slaveof-noone
#Sentinel正在将指定的从服务器升级为主服务器,等待升级功能完成。
21、failover-end-for-timeout
#故障转移因为超时而中止,不过最终所有从服务器都会开始复制新的主服务器。
22、failover-end
#故障转移操作顺利完成。所有从服务器都开始复制新的主服务器了。
23、+switch-master
#配置变更,主服务器的 IP 和地址已经改变。 这是绝大多数外部用户都关心的信息。
24、+tilt
#进入 tilt 模式。
25、-tilt
#退出 tilt 模式。
5 设置开机启动
再启动项中增加启动命令
echo "/redis/src/redis-sentinel /redis/sentinel.conf" >> /etc/rc.local
6 redis主从配置
生产环境主从最好部署到不同的服务器上,这里我们测试可以部署到同一个服务器上,用不同的端口测试。
10.1.51.248:8991 作为主服务器
10.1.51.248:8992 作为从服务器
10.1.51.248:8991 ->10.1.51.248:8992 (主->从)
新建两个目录redis-3.2.8_8991和redis-3.2.8_8992
6.1 在10.1.51.248:8991配置redis.conf文件
##监听端口
port 8991
##绑定ip
bind 10.1.51.248
## client 端空闲断开连接的时间
timeout 0
##日志记录级别,默认是notice,我这边使用warning,是为了监控日志方便。
loglevel warning
## 使用warning后,只有发生告警才会产生日志,这对于通过判断日志文件是否为空来监控报警非常方便。
logfile "/data/redis_8991/redis.log"
##默认是0,也就是只用1 个db,我这边设置成16,方便多个应用使用同一个redis server。
databases 0
##使用select n 命令可以确认使用的redis db ,这样不同的应用即使使用相同的key也不会有问题。
##下面是SNAPSHOTTING持久化方式的策略。
##为了保证数据相对安全,在下面的设置中,更改越频繁,SNAPSHOTTING越频繁,
##也就是说,压力越大,反而花在持久化上的资源会越多。
##所以我选择了master-slave模式,并在master关掉了SNAPSHOTTING。
save 900 1 #在900秒之内,redis至少发生1次修改则redis抓快照到磁盘
save 300 10 #在300秒之内,redis至少发生100次修改则redis抓快照到磁盘
save 60 10000 #在60秒之内,redis至少发生10000次修改则redis抓快照到磁盘
stop-writes-on-bgsave-error yes
rdbcompression yes ##使用压缩
rdbchecksum yes
dbfilename "dump.rdb"
dir "/data/redis_8991"
## replication 设置
slave-serve-stale-data yes
slave-read-only yes
slave-priority 100
###LIMIT 设置
##redis最大可使用的内存量,如果使用redis SNAPSHOTTING的copy-on-write的持久会写方式,会额外的使用内存。
##为了使持久会操作不会使用系统VM,使redis服务器性能下降,建议保留redis最大使用内存的一半来留给持久化使用。
maxmemory 256mb
##使用LRU算法删除设置了过期时间的key,但如果程序写的时间没有写key的过期时间
##建议使用allkeys-lru,这样至少保证redis不会不可写入
maxmemory-policy allkeys-lru
##append only mode设置
appendonly no
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
lua-time-limit 5000
###slow log 设置
slowlog-log-slower-than 10000
slowlog-max-len 128
##advanced config设置,下面的设置主要是用来节省内存的
hash-max-ziplist-entries 1024
hash-max-ziplist-value 2048
list-max-ziplist-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
6.2 在10.1.51.248:8992配置redis.conf文件
从服务器只需要在10.1.51.248:8991的redis.conf配置上修改和增加部分设置
修改:
port 8992
logfile "/data/redis_8992/redis.log"
增加:
## slave 实例只需要配置 slaveof 即可
slaveof 10.1.51.248 8991
6.3 启动主从服务
1、先启动主服务器
redis-3.2.8_8991$ ./redis-server ./redis.conf
2、启动从服务器
redis-3.2.8_8992$ ./redis-server ./redis.conf
3、查看服务器是否启动正常
~$ ps -ef | grep redis
root 6177 5420 0 18:02 pts/8 00:00:00 ./redis-server 10.1.51.248:8991
root 6180 5518 1 18:02 pts/10 00:00:01 ./redis-server 10.1.51.248:8992
root 6304 6256 0 18:04 pts/9 00:00:00 grep --color=auto redis
4、查看10.1.51.248:8991的info信息
$ ./redis-cli -h 10.1.51.248 -p 8991 info replication
# Replication
role:master
connected_slaves:1
slave0:ip=10.1.51.248,port=8992,state=online,offset=8431,lag=0
master_repl_offset:8431
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:8430
5、查看10.1.51.248:8992的info信息
$ ./redis-cli -h 10.1.51.248 -p 8992 info replication
# Replication
role:slave
master_host:10.1.51.248
master_port:8991
master_link_status:up
master_last_io_seconds_ago:6
master_sync_in_progress:0
slave_repl_offset:8501
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
7 sentinel监控master服务器
7.1 配置master的监控文件
配置master服务器到sentinel.conf中,sentinel能自动获取到slave服务器的信息。
daemonize yes
dir "/data/sentinel"
pidfile "/data/sentinel/sentinel.pid"
loglevel notice
logfile "/data/sentinel/sentinel.log"
sentinel monitor redis_3_2_8_8991 10.1.51.248 8991 1
sentinel down-after-milliseconds redis_3_2_8_8991 2500
sentinel parallel-syncs redis_3_2_8_8991 2
sentinel failover-timeout redis_3_2_8_8991 10000
7.2 启动sentinel监控
$ ./redis-sentinel ./sentinel_26379.conf
$ ps -ef | grep redis
root 6177 1 0 08:40 ? 00:00:47 ./redis-server 10.1.51.248:8991
root 6180 1 0 08:40 ? 00:00:46 ./redis-server 10.1.51.248:8992
root 7168 1 0 08:49 ? 00:00:00 ./redis-sentinel *:26379 [sentinel]
7.3 sentinel自动故障转移
模拟故障kill掉master,sentinel会将slave提升为master。
$ ps -ef |grep redis
root 6177 1 0 08:40 ? 00:00:47 ./redis-server 10.1.51.248:8991
root 6180 1 0 08:40 ? 00:00:47 ./redis-server 10.1.51.248:8992
root 7168 1 0 08:49 ? 00:00:01 ./redis-sentinel *:26379 [sentinel]
$ kill 6177
$ ps -ef|grep redis
root 6180 1 0 3月21 ? 00:00:47 ./redis-server 10.1.51.248:8992
root 7168 1 0 08:49 ? 00:00:01 ./redis-sentinel *:26379 [sentinel]
查看10.1.51.248:8992的info
$ ./redis-cli -h 10.1.51.248 -p 8992 info replication
# Replication
role:master
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
注意:kill掉master(10.1.51.248:8991)后,slave(10.1.51.248:8992)变成master服务器了,sentinel完成自动故障转移。
查看日志
$ cat sentinel.log
09:46:31.986 # Sentinel ID is bef5250aa0e5f3c6a67486c3f130b52475dcf72b
09:46:31.986 # +monitor master redis_3_2_8_8991 10.1.51.248 8991 quorum 1
09:46:31.987 * +slave slave 10.1.51.248:8992 10.1.51.248 8992 @ redis_3_2_8_8991 10.1.51.248 8991
09:49:04.495 # +sdown master redis_3_2_8_8991 10.1.51.248 8991
09:49:04.495 # +odown master redis_3_2_8_8991 10.1.51.248 8991 #quorum 1/1
09:49:04.495 # +new-epoch 1
09:49:04.495 # +try-failover master redis_3_2_8_8991 10.1.51.248 8991
09:49:04.528 # +vote-for-leader bef5250aa0e5f3c6a67486c3f130b52475dcf72b 1
09:49:04.528 # +elected-leader master redis_3_2_8_8991 10.1.51.248 8991
09:49:04.528 # +failover-state-select-slave master redis_3_2_8_8991 10.1.51.248 8991
09:49:04.612 # +selected-slave slave 10.1.51.248:8992 10.1.51.248 8992 @ redis_3_2_8_8991 10.1.51.248 8991
09:49:04.612 * +failover-state-send-slaveof-noone slave 10.1.51.248:8992 10.1.51.248 8992 @ redis_3_2_8_8991 10.1.51.248 8991
09:49:04.664 * +failover-state-wait-promotion slave 10.1.51.248:8992 10.1.51.248 8992 @ redis_3_2_8_8991 10.1.51.248 8991
参考链接:
https://my.oschina.net/dchuang/blog/666827
http://blog.csdn.net/vtopqx/article/details/49247285