sentinel的主要配置
port ${port}
dir "/opt/soft/redis/data/"
logfile "${port}.log"
# 表示有两个sentinel认为master有问题的时候就进行故障转移
sentinel monitor mymaster 192.168.5.129 7000 2
#当ping master不通30秒之后则认为master挂掉了
sentinel down-after-milliseconds mymaster 30000
#故障转移之后salve 对 master的复制是并行还是串行,1表示串行
sentinel parallel-syncs mymaster 1
# 故障转移时间
sentinel failover-timeout mymaster 180000
主从节点的准备
在redis config目录下创建 redis-7000.conf
vim redis-7000.conf
填写如下配置:
port 7000
daemonize yes
pidfile /var/run/redis-7000.pid
logfile "7000.log"
dir "/opt/soft/redis/data/" #没有该目录记得要创建
上面是主节点的配置 下面将快速生成从节点的配置
sed "s/7000/7001/g" redis-7000.conf >> redis-7001.conf
sed "s/7000/7002/g" redis-7000.conf >> redis-7002.conf
添加配置
echo "slaveof 192.168.5.129 7000">>redis-7002.conf
echo "slaveof 192.168.5.129 7000">>redis-7001.conf
配置检验
cat redis-7000.conf
cat redis-7001.conf
cat redis-7002.conf
启动
[root@localhost config]# redis-server redis-7000.conf
[root@localhost config]# redis-cli -p 7000 ping
PONG
redis-server redis-7001.conf
[root@localhost config]# redis-server redis-7002.conf
[root@localhost config]# ps -ef | grep redis-server | grep 700
root 5091 1 0 20:27 ? 00:00:00 redis-server *:7000
root 5097 1 0 20:28 ? 00:00:00 redis-server *:7001
root 5101 1 0 20:28 ? 00:00:00 redis-server *:7002
查看从节点是否配置成功
[root@localhost config]# redis-cli -p 7000 info replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.5.129,port=7001,state=online,offset=57,lag=1
slave1:ip=192.168.5.129,port=7002,state=online,offset=57,lag=1
master_repl_offset:57
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:56
Redis Sentinel的配置安装
将redis 目录下的配置 复制到 config下
cp sentinel.conf config
查看该配置(去掉所有注释和空行)
cat sentinel.conf | grep -v "#" | grep -v "^$"
创建新的文件
cat sentinel.conf | grep -v "#" | grep -v "^$" > redis-sentinel-26379.conf
进行编辑
vim redis-sentinel-26379.conf
需要更改的地方
dir /opt/soft/redis/redis/data/
daemonize yes
logfile "26379.log"
sentinel monitor mymaster 192.168.5.129 7000 2
进行启动并查看状态:
[root@localhost config]# redis-sentinel redis-sentinel-26379.conf
[root@localhost config]# ps -ef | grep redis-sentinel
root 1336 1 0 20:58 ? 00:00:00 redis-sentinel *:26379 [sentinel]
root 1340 1250 0 20:58 pts/0 00:00:00 grep --color=auto redis-sentinel
使用redis进行连接
[root@localhost config]# redis-cli -p 26379
192.168.5.129:26379> ping
PONG
192.168.5.129:26379> info
其中使用 info是查看该sentinel的信息
其中 sentinel 能够能够自动通过主节点去发现他的从节点 可以通过配置文件进行查看:
[root@localhost config]# cat redis-sentinel-26379.conf
port 26379
daemonize yes
dir "/opt/soft/redis/redis/data"
logfile "26379.log"
sentinel monitor mymaster 192.168.5.129 7000 2
sentinel config-epoch mymaster 0
sentinel leader-epoch mymaster 0
sentinel known-slave mymaster 192.168.5.129 7002 #这里
# Generated by CONFIG REWRITE
sentinel known-slave mymaster 192.168.5.129 7001 #和这里
sentinel current-epoch 0
再添加两个sentinel的配置:
sed "s/26379/26381/g" redis-sentinel-26379.conf > redis-sentinel-26381.conf
sed "s/26379/26380/g" redis-sentinel-26379.conf > redis-sentinel-26380.conf
启动和查看状态
redis-sentinel redis-sentinel-26381.conf
redis-sentinel redis-sentinel-26380.conf
[root@localhost config]# ps -ef | grep redis-sentinel
root 1336 1 0 20:58 ? 00:00:01 redis-sentinel *:26379 [sentinel]
root 1386 1 0 21:09 ? 00:00:00 redis-sentinel *:26380 [sentinel]
root 1396 1 0 21:11 ? 00:00:00 redis-sentinel *:26381 [sentinel]
root 1400 1250 0 21:11 pts/0 00:00:00 grep --color=auto redis-sentinel
连接一个 sentinel 并执行info
[root@localhost config]# redis-cli -p 26380
192.168.5.129:26380> info
最后一行表示 它也发下了master 和slaves 并且 sentine之间彼此连接上了
master0:name=mymaster,status=ok,address=192.168.5.129:7000,slaves=2,sentinels=3
Java 客户端连接Redis Sentinel
第一个问题 客户端是否能使用直连。
答案是否定的,搞可用仅存在与服务端 ,客户端需要及时获取故障转移之后的服务端地址才行。
客户端实现的基本原理:首先 要遍历Sentinel节点集合
获取一个可用的Sentinel节点,同时 如果要获取master 就要获取masterName
第二步:同过上面获取的两个参数,去请求能够ping 通的 sentinel-k 然后返回 sentinel 自动获取到的 master节点信息
第三步:验证 获取到的节点是否是真正的master节点:
第四步:客户端订阅服务端 ,当master发生变化之后 由sentinel将新的master信息发送给客户端
客户端接入流程:
- 获取Sentinel地址集合
- 获取masterName
- 需要注意这里不是代理模式,客户端并不是每次从sentinel那里获取数据。
public static void main(String[] args) {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(10);
config.setMaxWaitMillis(10000);
String masterName = "mymaster";
Set<String> sentinelSet = new HashSet<>();
sentinelSet.add("192.168.5.129:26379");
sentinelSet.add("192.168.5.129:26380");
sentinelSet.add("192.168.5.129:26381");
JedisSentinelPool pool = new JedisSentinelPool(masterName, sentinelSet, config);
Jedis jedis = null;
try {
jedis = pool.getResource();
String value = jedis.get("hello");
System.out.println(value);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (jedis != null) {
jedis.close();
}
}
}
故障转移演练
创建项目添加倚赖:
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.6</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.1</version>
</dependency>
编写代码 启动
public class RedisSentinelFailoverTest {
private static Logger logger = LoggerFactory.getLogger(RedisSentinelFailoverTest.class);
public static void main(String[] args) {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(10);
config.setMaxWaitMillis(10000);
String masterName = "mymaster";
Set<String> sentinelSet = new HashSet<>();
sentinelSet.add("192.168.5.129:26379");
sentinelSet.add("192.168.5.129:26380");
sentinelSet.add("192.168.5.129:26381");
JedisSentinelPool pool = new JedisSentinelPool(masterName, sentinelSet);
int counter = 0;
while (true){
counter++;
Jedis jedis = null;
try {
jedis = pool.getResource();
int i = new Random().nextInt(100000);
String key = "key-"+i;
String value = "value-"+i;
jedis.set(key,value);
if (counter %100 == 0)
logger.info("{} value is {}",key,jedis.get(key));
TimeUnit.MILLISECONDS.sleep(10);
} catch (Exception e) {
logger.error( e.getMessage(),e);
} finally {
if (jedis != null) {
jedis.close();
}
}
}
}
}
查询 7000节点的 process_id:2140
192.168.5.129:7000> info server
然后执行
[root@localhost config]# kill -9 2140
[root@localhost config]# ps -ef | grep redis-server | grep 7000
执行后会抛出大量的异常
但根据之前的配置 30秒后 会重新连接成功