Redis 高可用原理:
Redis使用sentinel机制来实现高可用,sentinel是另外一个集群,主要是用来监控所有的Redis服务器,所以主节点和从节点,监控方式仍然使用的是ping指令,sentinel每隔1秒向master发送【ping】,如果在一段时间内没有收到【pong】或者收到无效回复,则认为master下线。
sentinel对下线有两种定义:
a.主观下线(sdown):sentinel实例本身对服务实例的判断
b.客观下线(odown):多个sentinel实例对同一个服务SDOWN的状态做出协商后的判断,只有master才可能在odown状态 。
简单的说,一个sentinel单独做出的判断只能是sdown,是没有任何官方效力的,只有多个sentinel大家商量好,得到一致,才能将某个master状态置为odown,只有确定master odown状态后,才能做后续fail over的操作。
如果发现主的离线了,你不用告诉它哪个是主的,它会获取服务器信息,了解谁是主谁是从,你只要告诉它谁是主的就行了,它会从主上获取有哪些从,如果主down,它会从从中选一个当成为新的主节点,它能够实现监控整个主从复制架构,一旦发现主down了,会自动从多个从中选择一个从的提升为新的主,那么此前从节点连的主节点是原来的老主,原来的主节点不在了怎么办,sentinel告诉客户端新的主是谁 ,向客户端发送slaveof指定让从节点重新选择主节点。
如果sentinel连不主节点或者sentinel本身故障了怎么办,所以sentinel需要做一个集群。由集群中的每个节点来共同判断redis节点是否down了。
Sentinel作用:管理多个redis服务实现HA
监控: Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
通知:当被监控的某个Redis服务器出现问题时, Sentinel可以通过API向管理员或者其他应用程序发送通知。
自动故障转移:当一个主服务器不能正常工作时, Sentinel会开始一次自动故障迁移操作,它会将失效主服务器的其中一个从服务器升级为新的主服务器,并让失效主服务器的其他从服务器改为复制新的主服务器;当客户端试图连接失效的主服务器时,集群也会向客户端返回新主服务器的地址,使得集群可以使用新主服务器代替失效服务器。
流言协议,投票协议。
sentinel的启动
启动方式有两种:
# 通过redis-server 的sentinel参数启动:
redis-servier /etc/sentinel.conf --sentinel
# 通过redis-sentinel命令启动:
redis-sentinel /etc/sentinel.conf
Sentinel依赖于配置文件,它必须用配置文件不停保存自已的状态信息。
启动一个sentinel有以下几个步骤:
1,服务器自身初始化 。
运行 redis-server 中专用于sentinel功能的代码
2,初始化sentinel状态,根据给定的配置文件,初始化监控的master服务器列表
3,创建连向master的连接。
sentinel专用配置文件:/etc/redis-sentinel.conf
port 26379
sentinel monitor mymaster 127.0.0.1 6379 2
#指定要监控的master,mymaster名字,可以不指,quorum法定票数2,此处指的是sentinel的数,三个sentinel占2个,指定的sentinel同意时才认为sentinel做的决策是有效的,一般大于sentinel数量的半数。
# 可以有多个,一组sentinel集群可以监控N个主从复制架构
sentinel auth-pass mymaster redis #指定要连接的redis master密码
sentinel down-after-milliseconds mymaster 30000 #至少多长时间 连不上才认为主的离线了。单位为ms, 即连接超时时长。
sentinel parallel-syncs 1 # 刚刚设定为新主时,允许同时有多少个从向主发起同步请求。
entinel failover-timeout mymaster 180000 #故障转移的超时时长
#当主故障时,把新的从提升为主,多长时间提不上就认为故障转移失败。
示例:
一主两从:
主:10.3.1.15 6379
从:10.3.1.15 6378
从:10.3.1.15 6376
Sentinel:10.3.1.17
1, 在从的redis.conf 加上这句即可成为主从关系:
slaveof <masterip> <masterport>
2, 连接到主服务器上查看:
127.0.0.1:6379> INFO replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6378,state=online,offset=5204,lag=1
slave1:ip=127.0.0.1,port=6376,state=online,offset=5204,lag=1
master_repl_offset:5218
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:5217
127.0.0.1:6379>
#主从关系已正常
3, 配置sentinel.conf
sentinel.conf的配置参数上面已经描述。
4, 在前台启动sentinel
#启动sentinel
./bin/redis-sentinel /data/service/redis/sentinel.conf
18844:X 23 Mar 18:34:58.053 * Increased maximum number of open files to 10032 (it was originally set to 1024).
_._
_.-``__ ‘‘-._
_.-`` `. `_. ‘‘-._ Redis 3.2.11 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ‘‘-._
( ‘ , .-` | `, ) Running in sentinel mode
|`-._`-...-` __...-.``-._|‘` _.-‘| Port: 26379
| `-._ `._ / _.-‘ | PID: 18844
`-._ `-._ `-./ _.-‘ _.-‘
|`-._`-._ `-.__.-‘ _.-‘_.-‘|
| `-._`-._ _.-‘_.-‘ | http://redis.io
`-._ `-._`-.__.-‘_.-‘ _.-‘
|`-._`-._ `-.__.-‘ _.-‘_.-‘|
| `-._`-._ _.-‘_.-‘ |
`-._ `-._`-.__.-‘_.-‘ _.-‘
`-._ `-.__.-‘ _.-‘
`-._ _.-‘
`-.__.-‘
18844:X 23 Mar 18:34:58.054 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
18844:X 23 Mar 18:34:58.056 # Sentinel ID is 524c94beed78f379e4a0b3b641992449b0cdcf7f
18844:X 23 Mar 18:34:58.056 # +monitor master mymaster 10.3.1.15 6379 quorum 2
18844:X 23 Mar 18:34:58.057 * +slave slave 10.3.1.15:6378 10.3.1.15 6378 @ mymaster 10.3.1.15 6379
18844:X 23 Mar 18:34:58.059 * +slave slave 10.3.1.15:6376 10.3.1.15 6376 @ mymaster 10.3.1.15 6379
#启动完成,从控制台上面已经找到master和slave。
下面是连入sentinel 查看master信息:
root@ubuntu17:$ redis-cli -h 10.3.1.17 -p 26379
10.3.1.17:26379> info
DENIED Redis is running in protected mode because protected mode is enabled, no bind address was specified, no authentication password is requested to clients. In this mode connections are only accepted from the loopback interface. If you want to connect from external computers to Redis you may adopt one of the following solutions: 1) Just disable protected mode sending the command ‘CONFIG SET protected-mode no‘ from the loopback interface by connecting to Redis from the same host the server is running, however MAKE SURE Redis is not publicly accessible from internet if you do so. Use CONFIG REWRITE to make this change permanent. 2) Alternatively you can just disable the protected mode by editing the Redis configuration file, and setting the protected mode option to ‘no‘, and then restarting the server. 3) If you started the server manually just for testing, restart it with the ‘--protected-mode no‘ option. 4) Setup a bind address or an authentication password. NOTE: You only need to do one of the above things in order for the server to start accepting connections from the outside.
如上,输入info后报错说是redis工作在保护模式下,通过‘CONFIG SET protected-mode no 来关闭,因为默认protected-mode 为yes。
通过在所有的redis,即一主两从上都加上这句话,然后在sentinel后,仍然报此错,于是尝试在sentinel本身的sentinel.conf文件中加入了这句,保存并重启sentinel,然后执行info就不报错了。
部署成功性验证:
10.3.1.17:26379> INFO
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=10.3.1.15:6379,slaves=2,sentinels=1
10.3.1.17:26379> #mymaster是在sentinel.conf设置的master名称。
sentinel专用命令:
sentinel masters #获取所有监控的主
sentinel slaves <master name> #列出该master的所有从节点
sentinel get-master-addr-by-name <master name>根据名字来获取地址
sentinel reset #重置所有 从头再来
sentinel failover <mater name> #手动故障转移,并指明向哪组mater name发起手动
#获取sentinel 所监控的redis master服务器信息
10.3.1.17:26379> sentinel masters
1) 1) "name"
2) "mymaster"
3) "ip"
4) "10.3.1.15"
5) "port"
6) "6379"
7) "runid"
8) "3520e56cadc7a3cd591da0094199d46a83771318"
9) "flags"
10) "master"
11) "link-pending-commands"
12) "0"
13) "link-refcount"
14) "1"
15) "last-ping-sent"
16) "0"
17) "last-ok-ping-reply"
18) "697"
19) "last-ping-reply"
20) "697"
21) "down-after-milliseconds"
22) "30000"
高可用验证:
当把主master 停掉,在sentinel控制台中输出故障转移过程:
62360:X 24 Mar 13:05:53.197 # +sdown master mymaster 10.3.1.15 6379 #主观认为master已失效
62360:X 24 Mar 13:05:53.197 # +odown master mymaster 10.3.1.15 6379 #quorum 1/1 #客观认为master已失效
62360:X 24 Mar 13:06:07.965 # +new-epoch 13 #准备进master新一纪元,第13次选举。
62360:X 24 Mar 13:06:07.965 # +try-failover master mymaster 10.3.1.15 6379 #尝试转移master
62360:X 24 Mar 13:06:07.967 # +vote-for-leader 9cf767f451de09136054ccc6afc6dcc5f939b5a0 13 #投票选举leader
62360:X 24 Mar 13:06:07.967 # +elected-leader master mymaster 10.3.1.15 6379 #之前被选举出来的 master
62360:X 24 Mar 13:06:07.967 # +failover-state-select-slave master mymaster 10.3.1.15 6379 #Leader开始select合适的master
62360:X 24 Mar 13:06:08.034 # +selected-slave slave 10.3.1.15:6376 10.3.1.15 6376 @ mymaster 10.3.1.15 6379 #已找到了合适的从10.3.1.15:6376为主
62360:X 24 Mar 13:06:08.034 * +failover-state-send-slaveof-noone slave 10.3.1.15:6376 10.3.1.15 6376 @ mymaster 10.3.1.15 6379 #Leader 向 slave 发送“slaveof no one”指令,此时 slave 已经完成角色转换,此 slave 即为 master
62360:X 24 Mar 13:06:08.093 * +failover-state-wait-promotion slave 10.3.1.15:6376 10.3.1.15 6376 @ mymaster 10.3.1.15 6379 #等待其他 sentinel 确认 slave
62360:X 24 Mar 13:06:09.116 # +promoted-slave slave 10.3.1.15:6376 10.3.1.15 6376 @ mymaster 10.3.1.15 6379 #确认成功
62360:X 24 Mar 13:06:09.116 # +failover-state-reconf-slaves master mymaster 10.3.1.15 6379 #开始对slaves进行reconfig 操作
62360:X 24 Mar 13:06:09.176 * +slave-reconf-sent slave 10.3.1.15:6378 10.3.1.15 6378 @ mymaster 10.3.1.15 6379 #向指定的slave 发送“slaveof”指令,告知此 slave 跟随新的 master
62360:X 24 Mar 13:06:10.132 * +slave-reconf-inprog slave 10.3.1.15:6378 10.3.1.15 6378 @ mymaster 10.3.1.15 6379 开始对slaves进行reconfig 操作
然后进入sentinel中查看新的master:
10.3.1.17:26379> sentinel masters
#可以看到master已经发生了改变
1) 1) "name"
2) "mymaster"
3) "ip"
4) "10.3.1.15"
5) "port"
6) "6376"
7) "runid"
回到某个slave节点查看:
10.3.1.15:6378> config get slaveof
1) "slaveof"
2) "10.3.1.15 6376"
10.3.1.15:6378>
现在把原来的master 6379启动起来,再看下它是主还是从:
10.3.1.15:6379> config get slaveof
1) "slaveof"
2) "10.3.1.15 6376"
#原来的master,此时已是从节点了
现在进入新选举出来的master查看:
10.3.1.15:6376> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=10.3.1.15,port=6379,state=online,offset=707098,lag=1
slave1:ip=10.3.1.15,port=6379,state=wait_bgsave,offset=0,lag=0
master_repl_offset:707098
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:707097
10.3.1.15:6376>
以上就是sentinel就是高可用功能,客户端程序应该向sentinel发请求,去寻求新Master的地址 ,这时要用redis专用程序,根据sentinel反馈来联络新服务器。
原文:http://blog.51cto.com/newfly/2090648