如上图所示:
两台服务器分别存在一主一丛,且分别为交叉主从关系,且在服务器上分别有sentinel(哨兵)来监控当前服务器主从情况,
通过sentinel进行主从切换,完成failover。
说明:
master_16319、slave_26319。
master_16320、slave_26320。
分别对应两组不同的组从,配置文件分别对应为:
redis_master_16319.conf ... 名称中体现了role 和端口。
常用命令:
脚本文件在redis/src目录,将src目录下redis-server、redis-cli、redis-sentinel到/usr/local/bin目录下,这样在任何目录可以直接使用这些命令。否则必须到src目录下:./redis-xxx
redis启动:redis-server /path/xxx.conf
redis连接:redis-cli -p 16319
redis停止:redis-cli 进入后执行shutdown命令.
redis主从配置,请参考文章
port 16320
pidfile /var/run/redis_16320.pid
daemonize yes 后台运行
logfile "/data/logs/redis_16320.log"指定一个日志路径。
loglevel notice (默认即可)
bind 属性暂时全部注释.bind只允许指定的IP能够请求,可以多个,我这里先不限制。
同master区别在与需要多配置:
slaveof
这里改成对应master的IP和端口
这里有个错误:
redis-cli -p 26319 命令连接redis终端.
执行info命令查看slave信息。
# Replication
role:slave
master_host:10.27.xxx.xxx
master_port:16319
master_link_status:down
在其中可以看到master_link_status 状态为down,正常应该为up,这里上面配置的logfile,用上了,看日志发现有一段error:
Error reply to PING from master: '-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'。
意思大概是没有设置auth redis验证,也没有设置bind ip,
所以解决方案有3中:
1、redis 加入auth
2、配置文件中配置bind属性。(bind IP1 IP2 IP...)
3、关闭redis保护模式,protected-mode yes 改成no (3.2版本之后新增的).
这里我采用第三种,解决。
说明
前一篇文章中我有提到,将sentinel.conf文件和redis.conf文件单独放到conf目录,便于后期维护。这里我们两台服务器各配置一个sentinel.conf ,分别改名为:sentinel_36001.conf,sentinel_36002.conf
port:36001 #sentinel端口
dir:/tmp #工作文件临时目录
protected-mode no #保护模式关闭
daemonize yes #后台运行,这行是新增的,文件中默认没有.
sentinel monitor 这里改成对应的
sentinel monitor master1 10.27.171.167 16319 1
这里的表示,sentinel去监控名称为master1,ip为10.27.171.167 端口为16319的master,当1个sentinel判断master失效时,sentinel就执行failover,这里因为只有2台服务quorum设置为1。
sentinel down-after-milliseconds mymaster 30000
Sentinel认为Redis实例已经失效所需的毫秒数
sentinel parallel-syncs master1 1
指定了在执行故障转移时,最多可以有多少个从Redis实例在同步新的主实例
sentinel failover-timeout master1 180000
如果在该时间(ms)内未能完成failover操作,则认为该failover失败
我这里如下,配置监控多个master
sentinel monitor master1 10.27.171.167 16319 1
sentinel down-after-milliseconds master1 30000
sentinel parallel-syncs master1 1
sentinel failover-timeout master1 180000
sentinel monitor master2 10.24.206.145 16320 1
sentinel down-after-milliseconds master2 30000
sentinel parallel-syncs master2 1
sentinel failover-timeout master2 180000
这里单个sentinel监控两个master信息。
两天服务器sentinel配置文件相同,修改为不同的端口即可。
sentinel配置完成。
sentinel 启动:
进入redis src 目录:
./redis-sentinel ../conf/sentinel_36001.conf
也可以
redis-cli -p 36002
进入客户端后,执行info命令可以看到相关的信息.
如:# Sentinel
sentinel_masters:2
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=master1,status=ok,address=10.27.171.167:16319,slaves=1,sentinels=1
master1:name=master2,status=ok,address=10.24.206.145:16320,slaves=1,sentinels=1
说明:可以直接通过进入redis客户端,通过info命令,查看sentinel状态,当shutdown其中一台master之后,看原来的slave是否已经切换为master。
这里我使用jedis客户端,在java程序中进行测试。
jedis
我这里直接下载源码,下载地址http://redis.io/clients#java
然后去网上下载,commons-pool2-2.4.2.jar
新建一个web工程,
如上图:左边是源码,运行应用程序,下面会有错误,原因还是protected mode 需要改成no,关闭保护模式。
修改sentinel 的conf文件之后:
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisSentinelPool;
public class RedisTest {
public static void main(String[] args) {
Set s = new LinkedHashSet();
s.add("1.2.3.4:36001");
s.add("5.6.7.8:36002");
JedisSentinelPool pool = new JedisSentinelPool("master_2",s );
int i=0;
while(true){
i++;
System.out.println(pool.getCurrentHostMaster() +" -- "+i);
try {
new Thread().sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
看到运行结果master的端口为16319
... ...
十一月 18, 2016 6:04:53 下午 redis.clients.jedis.JedisSentinelPool initPool
信息: Created JedisPool to master at 10.24.206.145:16320
10.24.206.145:16320 – 1
10.24.206.145:16320 – 2
10.24.206.145:16320 – 3
这时候我们将16320 停掉,程序 while(true) 看效果
命令:redis -cli -p 16320 进入后执行,shutdown
10.24.206.145:16320 -- 12
10.24.206.145:16320 -- 13
十一月 18, 2016 6:05:30 下午 redis.clients.jedis.JedisSentinelPool initPool
信息: Created JedisPool to master at 10.27.171.167:26320
10.27.171.167:26320 -- 14
ok,从控制台输出的日志中看出,顺利达到failover的目的.
配置过程中或多或少都会有些许问题,日志以及相关问题可以从以下几个方面分析.
一、
不管是master还是sentinel,我们都可以进入控制台后输入info命令查看相关信息。
[root@iZwz9istfz0zvx3yuaf6tqZ ~]# redis-cli -p 26320
127.0.0.1:26320> info
… …
role:slave (当前为slave)
master_host:10.27.171.167 (master的ip)
master_port:16319 (master 端口)
master_link_status:up (连接状态,down为非成功状态)
… …
redis.conf 和sentinel.conf 都可以配置这两个属性,sentinel.conf中默认无,但其实是支持的(包括后台运行等),直接参考redis.conf中的配置即可。
主目录:http://redis.io/documentation
主从相关:http://redis.io/topics/replication
sentinel相关:http://redis.io/topics/sentinel
官方文档中都有很清晰的描述。