一、Sentinel介绍
Sentinel是Redis的高可用性(HA)解决方案,由一个或多个Sentinel实例组成的Sentinel系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进行下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器,然后由新的主服务器代替已下线的主服务器继续处理命令请求。Redis提供的sentinel(哨兵)机制,通过sentinel模式启动redis后,自动监控master/slave的运行状态,基本原理是:心跳机制+投票裁决
监控(
Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
提醒(
Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
自动故障迁移(
Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。
二、Sentinel的主从原理
三、
测试环境
windows10操作系统
四、Redis版本
3.2.100(注:redis官网仅发布了linux版本,windows版本需去github下载。下载地址:
https://github.com/MSOpenTech/redis/releases)
五、Redis安装
下载如下
msi文件,点击安装即可
安装完后,目录如下
:
六、Redis Sentinel配置
测试采用
2个哨兵,1个主redis,2个从redis。
复制
5份redis.windows.conf文件并重命名如下(开发者可根据自己的开发习惯进行重命名):
master.6379.conf配置(直接在原配置文件中修改):
port:6379
requirepass:grs
masterauth:grs
slave.6380.conf配置(直接在原配置文件中修改):
port:6380
requirepass:grs
masterauth:grs
dbfilename dump6380.rdb
slaveof 127.0.0.1 6379
master.6381.conf配置(直接在原配置文件中修改):
port:6381
requirepass:grs
masterauth:grs
dbfilename dump6381.rdb
slaveof 127.0.0.1 6379
sentinel.63791.conf 配置(将原配置文件清空后添加如下内容):
port 63791
sentinel monitor master-1 127.0.0.1 6379 2 //主master,2个sentinel选举成功后才有效
sentinel down-after-milliseconds master-1 5000 //判断主master的挂机时间(毫秒),超时未返回正确信息后标记为sdown状态
sentinel failover-timeout master-1 18000 //若sentinel在该配置值内未能完成failover操作(即故障时master/slave自动切换),则认为本次failover失败。
sentinel auth-pass master-1 grs //身份认证
sentinel parallel-syncs master-1 1 //选项指定了在执行故障转移时, 最多可以有多少个从服务器同时对新的主服务器进行同步,这个数字越小,完成故障转移所需的时间就越长
sentinel.63792.conf 配置(将原配置文件清空后添加如下内容):
port 63792
sentinel monitor master-1 127.0.0.1 6379 2 //主master,2个sentinel选举成功后才有效
sentinel down-after-milliseconds master-1 5000 //判断主master的挂机时间(毫秒),超时未返回正确信息后标记为sdown状态
sentinel failover-timeout master-1 18000 //若sentinel在该配置值内未能完成failover操作(即故障时master/slave自动切换),则认为本次failover失败。
sentinel auth-pass master-1 grs //身份认证
sentinel parallel-syncs master-1 1 //选项指定了在执行故障转移时, 最多可以有多少个从服务器同时对新的主服务器进行同步,这个数字越小,完成故障转移所需的时间就越长
这里有三个问题需要注意
第一,若通过
redis-cli -h 127.0.0.1 -p 6379连接,无需改变配置文件,配置文件默认配置为bind 127.0.0.1(只允许127.0.0.1连接访问)
若通过
redis-cli -h 192.168.180.78 -p 6379连接,需改变配置文件,配置信息为bind 127.0.0.1 192.168.180.78(只允许127.0.0.1和192.168.180.78访问)或者将bind 127.0.0.1注释掉(允许所有远程访问)
第二,
masterauth为所要连接的master服务器的requirepass,如果一个redis集群中有一个master服务器,两个slave服务器,当master服务器挂掉时,sentinel哨兵会随机选择一个slave服务器充当master服务器,鉴于这种机制,解决办法是将所有的主从服务器的requirepass和masterauth都设置为一样。
第三,
sentinel monitor master-1 127.0.0.1 6379 2 行尾最后的一个2代表什么意思呢?我们知道,网络是不可靠的,有时候一个sentinel会因为网络堵塞而误以为一个master redis已经死掉了,当sentinel集群式,解决这个问题的方法就变得很简单,只需要多个sentinel互相沟通来确认某个master是否真的死了,这个2代表,当集群中有2个sentinel认为master死了时,才能真正认为该master已经不可用了。(sentinel集群中各个sentinel也有互相通信,通过gossip协议)。
按如下循序依次启动服务
1、redis-server master.6379.conf
2、redis-server slave.6380.conf
3、redis-server slave.6381.conf
4、redis-server sentinel.63791.conf --sentinel(linux:redis-sentinel sentinel.63791.conf)
5、redis-server sentinel.63792.conf --sentinel(linux:redis-sentinel sentinel.63792.conf)
查看
master状态:
查看
slave状态:
查看
sentinel状态:
验证
redis sentinel的主从切换:
1、
首先关闭主
redis(6379)服务(shutdown)。
2、
查看哨兵,发现端口号为
6380的从服务变成了主服务,sentinel自动完成了故障切换。
3、
启动刚才被
shutdown的6379服务并查看,发现它变成了从服务。
七、Jedis Sentinel教程
Maven依赖:
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.0</version>
</dependency>
<!-- spring-redis -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.6.4.RELEASE</version>
</dependency>
redis的配置文件:
#redis config
redis.pass=grs
redis.pool.maxTotal=105
redis.pool.maxIdle=10
redis.pool.maxWaitMillis=60000
redis.pool.testOnBorrow=true
sentinel1.ip=127.0.0.1
sentinel1.port=63791
sentinel2.ip=127.0.0.1
sentinel2.port=63792
Spring的配置文件:
<!-- Redis 配置 -->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="${redis.pool.maxTotal}" />
<property name="maxIdle" value="${redis.pool.maxIdle}" />
<property name="maxWaitMillis" value="${redis.pool.maxWaitMillis}" />
<property name="testOnBorrow" value="${redis.pool.testOnBorrow}" />
</bean>
<bean id="sentinelConfiguration"
class="org.springframework.data.redis.connection.RedisSentinelConfiguration">
<property name="master">
<bean class="org.springframework.data.redis.connection.RedisNode">
<property name="name" value="master-1"></property>
</bean>
</property>
<property name="sentinels">
<set>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="${sentinel1.ip}"></constructor-arg>
<constructor-arg name="port" value="${sentinel1.port}"></constructor-arg>
</bean>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="${sentinel2.ip}"></constructor-arg>
<constructor-arg name="port" value="${sentinel2.port}"></constructor-arg>
</bean>
</set>
</property>
</bean>
<!-- Jedis ConnectionFactory连接配置 -->
<bean id="jedisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="password" value="${redis.pass}"></property>
<property name="poolConfig" >
<ref bean="jedisPoolConfig"/>
</property>
<constructor-arg name="sentinelConfig" ref="sentinelConfiguration"></constructor-arg>
</bean>
<!-- redisTemplate配置,redisTemplate是对Jedis的对redis操作的扩展,有更多的操作,封装使操作更便捷 -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory" />
</bean>
代码中直接用
redisTemplate调用:
@Override
public boolean add(final KeyToken tkey) {
boolean result = redisTemplate.execute(new RedisCallback<Boolean>() {
@Override
public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
RedisSerializer<String> serializer = getRedisSerializer();
byte[] key = serializer.serialize(tkey.getIndex());
byte[] name = serializer.serialize(tkey.getExpire_time());
return connection.setNX(key, name);
}
});
return result;
}
Sentinel
常用命令
1. ping
//
返回
PONG
。
2. sentinel masters
//
列出所有被监视的主服务器,以及这些主服务器的当前状态。
3. sentinel slaves <master name>
//
列出给定主服务器的所有从服务器,以及这些从服务器的当前状态。
4. sentinel get-master-addr-by-name <master name>
//
返回给定名字的主服务器的
IP
地址和端口号。如果这个主服务器正在执行故障转移操作,或者针对这个主服务器的故障转移操作已经完成,那么这个命令返回新的主服务器的
IP
地址和端口号。
5. sentinel reset <pattern>
//
重置所有名字和给定模式
pattern
相匹配的主服务器。
pattern
参数是一个
Glob
风格的模式。重置操作清除主服务器目前的所有状态,包括正在执行中的故障转移,并移除目前已经发现和关联的,主服务器的所有从服务器和
Sentinel
。
sentinel failover <master name> //
当主服务器失效时,在不询问其他
Sentinel
意见的情况下,强制开始一次自动故障迁移(不过发起故障转移的
Sentinel
会向其他
Sentinel
发送一个新的配置,其他
Sentinel
会根据这个配置进行相应的更新)。
Sentinel
配置详解
1.
port 26379
//sentinel
监听端口,默认是
26379
,可以修改。
2. sentinel monitor <master-name> <ip> <redis-port> <quorum>
//
告诉
sentinel
去监听地址为
ip:port
的一个
master
,这里的
master-name
可以自
定义,
quorum
是一个数字,指明当有多少个
sentinel
认为一个
master
失效
时,
master
才算真正失效。
master-name
只能包含英文字母,数字,和“
.-_
”
这三个字符。
配置示例:
sentinel monitor master-1 127.0.0.1 6379 2
3. sentinel down-after-milliseconds <master-name> <milliseconds>
//sentinel
会向
master
发送心跳
PING
来确认
master
是否存活,如果
master
在“一定时间范围”内不回应
PONG
或者是回复了一个错误消
息,那么这个
sentinel
会主观地
(
单方面地
)
认为这个
master
已经不可用了
(subjectively down,
也简称为
SDOWN)
。而这个
down-after-milliseconds
就是用来指定这个
“一定时间范围”的,单位是毫秒。
配置示例:
sentinel down-after-milliseconds master-1 5000
4. sentinel failover-timeout <master-name> <milliseconds>
//
如果在该
时间(
ms
)内未能完成
failover
操作,则认为该
failover
失败。
配置示例:
sentinel failover-timeout master-1 18000
5. sentinel parallel-syncs <master-name> <numslaves>
//
在发生
failover
主备切换时,这个选项指定了最多可以有多少个
slave
同时对新的
master
进行同步,这个数字越小,完成
failover
所需的时间就越长,但是
如果这个数字越大,就意味着越多的
slave
因为
replication
而不可用。可以
通过将这个值设为
1
来保证每次只有一个
slave
处于不能处理命令请求的
状态。
配置示例:
sentinel parallel-syncs master-1 1
6. sentinel notification-script <master-name> <script-path>
//
通知型脚
本
:
当
sentinel
有任何警告级别的事件发生时(比如说
redis
实例的主观失效
和客观失效等等),将会去调用这个脚本,这时这个脚本应该通过邮件,
SMS
等方式去通知系统管理员关于系统不正常运行的信息。调用该脚本时,将传
给脚本两个参数,一个是事件的类型,一个是事件的描述。如果
sentinel.conf
配置文件中配置了这个脚本路径,那么必须保证这个脚本存在于这个路径,
并且是可执行的,否则
sentinel
无法正常启动成功。
配置示例:
sentinel notification-script master-1 D:\script.bat
7. sentinel client-reconfig-script <master-name> <script-path>
//
当一个
master
由于
failover
而发生改变时,这个脚本将会被调用,通知相关的客户
端关于
master
地址已经发生改变的信息。以下参数将会在调用脚本时传给
脚本
:<master-name> <role> <state> <from-ip> <from-port> <to-ip> <to-port>
目前
<state>
总是“
failover
”
, <role>
是“
leader
”或者“
observer
”
中的一个。
参数
from-ip, from-port, to-ip, to-port
是用来和旧的
master
和
新的
master(
即旧的
slave)
通信的。这个脚本应该是通用的,能被多次调用,
不是针对性的。
配置示例:
sentinel client-reconfig-script mymaster D:\script.bat
8. sentinel auth-pass <master-name> <password>
//
设置连接
master
和
slave
时的密码,注意的是
sentinel
不能分别为
master
和
slave
设置不同的
密码,因此
master
和
slave
的密码应该设置相同。
配置示例:
sentinel auth-pass master-1 grs