哨兵高可用模式
为什么要用哨兵模式:主机崩溃以后哨兵监控到主机崩溃,将自动选取其他从机为主机。
准备工作
1.将redis架构设置为一主二从架构
2.搭建三个哨兵
哨兵搭建
1、进入redis-5.0.3目录复制一份sentinel.conf文件到redis目录下的config目录下
[root@VM-16-10-centos redis-5.0.14]# cp sentinel.conf config/sentinel-26379.conf
2、将相关配置修改为如下值:
port 26379 # 每个哨兵端口不一致
daemonize yes # 后台启动
pidfile "/var/run/redis-sentinel-26379.pid" # pidfile端口需要修改
logfile "26379.log" #每个哨兵日志文件需要修改
dir /usr/local/redis-5.0.3/data # /usr/local/redis-5.0.14/data
# sentinel monitor <master-redis-name> <master-redis-ip> <master-redis-port> <quorum>
# quorum是一个数字,指明当有多少个sentinel认为一个master失效时(值一般为:sentinel总数/2 + 1),master才算真正失效
sentinel monitor mymaster 192.168.0.60 6379 2 # (多个哨兵端口号均为6379)mymaster这个名字随便取,客户端访问时会用到;2 使用上述公式计算得出;此处ip为服务器公网ip
#若要设置密码,所有的哨兵都必须加上下面两个密码设置
masterauth xxx #设置主机密码
sentinel auth-pass mymaster xxpasswordxxx #从机同步主机数据需要知道密码才能同步
2.1、再复制两份哨兵(复制的哨兵注释掉:sentinel myid(若未启动过哨兵配置文件中还未生成myid),其他配置参考上述配置)
[root@VM-16-10-centos config]# cp sentinel-26379.conf config/sentinel-26380.conf
[root@VM-16-10-centos config]# cp sentinel-26379.conf config/sentinel-26381.conf
3、启动sentinel哨兵实例
src/redis-sentinel sentinel-26379.conf
src/redis-sentinel sentinel-26380.conf
src/redis-sentinel sentinel-26381.conf
4、查看sentinel的info信息
src/redis-cli -p 26379
127.0.0.1:26379>info replication
可以看到Sentinel的info里已经识别出了redis的主从
断开主机6379:进入redis-cli客户端,使用shutdown命令,等待一段时间在6380、6381客户端使用info replication查看主机已经被更换
补充:可以通过slave-priority 100 # 设置成为主机的权重,值越小优先级越高
Java代码测试
1.jedis测试
引入依赖
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.2.0</version>
</dependency>
java测试代码
public class JedisSentinelTest {
public static void main(String[] args) throws IOException {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(20);
config.setMaxIdle(10);
config.setMinIdle(5);
String masterName = "mymaster";
Set<String> sentinels = new HashSet<String>();
sentinels.add(new HostAndPort("0.0.0.0",26379).toString());
sentinels.add(new HostAndPort("0.0.0.0",26380).toString());
sentinels.add(new HostAndPort("0.0.0.0",26381).toString());
//JedisSentinelPool其实本质跟JedisPool类似,都是与redis主节点建立的连接池
//JedisSentinelPool并不是说与sentinel建立的连接池,而是通过sentinel发现redis主节点并与其建立连接
JedisSentinelPool jedisSentinelPool = new JedisSentinelPool(masterName, sentinels, config, 3000, "123525lbl.");
Jedis jedis = null;
try {
jedis = jedisSentinelPool.getResource();
System.out.println(jedis.set("sentinel", "zhy_b0"));
System.out.println(jedis.get("sentinel"));
} catch (Exception e) {
e.printStackTrace();
} finally {
//注意这里不是关闭连接,在JedisPool模式下,Jedis会被归还给资源池。
if (jedis != null)
jedis.close();
}
}
}
2.SpringBoot测试
引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
配置文件
spring:
redis:
database: 0
timeout: 3000
sentinel: #哨兵模式
master: mymaster #主服务器所在集群名称
nodes: 0.0.0.0:26379,0.0.0.0:26380,0.0.0.0:26381
lettuce:
pool:
max-idle: 50
min-idle: 10
max-active: 100
max-wait: 1000
#若哨兵中配置了密码在此处填写,若未配置密码注释掉即可
password: 123456
测试代码
@RestController
public class IndexController {
private static final Logger logger = LoggerFactory.getLogger(IndexController.class);
@Autowired
private StringRedisTemplate stringRedisTemplate;
/**
* 测试节点挂了哨兵重新选举新的master节点,客户端是否能动态感知到
* 新的master选举出来后,哨兵会把消息发布出去,客户端实际上是实现了一个消息监听机制,
* 当哨兵把新master的消息发布出去,客户端会立马感知到新master的信息,从而动态切换访问的masterip
*
* @throws InterruptedException
*/
@RequestMapping("/test_sentinel")
public void testSentinel() throws InterruptedException {
int i = 30;
while (true){
try {
stringRedisTemplate.opsForValue().set("kuku_sentinel"+i, i+"");
System.out.println("设置key:"+ "kuku_sentinel" + i);
i++;
Thread.sleep(1000);
}catch (Exception e){
logger.error("错误:", e);
}
}
}
}