`Sentinel`机制下,客户端应该怎么连接上`master`服务呢?因为`master`是可能改变的。所以在`Sentinel`机制下,客户端需要连接上`Sentinel`服务,然后从`Sentinel`服务获得`master`节点的地址进行连接。如下图所示:

#### Jedis 使用 Sentinel 机制
单独的`master-slave`集群使用方式和单台`Redis`的使用方式没有区别,所以我们在实验十一中并没有去讲解如何使用。但是`Sentinel`的使用和单台`Redis`的使用上有点区别,接下来大家跟着我一起动手写一个简单的`Sentinel`使用`demo`(后续还有两个实验也会有`demo`的讲解,为了方便使用第三方`jar`包,在这里我预先搭建好了一个简单的`Spring Boot`项目的骨架,大家就不需要再单独去创建了):
1. 执行命令进行下载、解压缩。
~~~bash
cd /home/project
# 下载
wget https://labfile.oss.aliyuncs.com/courses/3368/redis-demo.zip
# 解压缩
unzip redis-demo.zip
~~~
2. 打开`redis-demo`文件夹,找到`pom.xml`文件,引入如下`pom`依赖:
~~~java
<dependencies>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
~~~
如下图所示:

3. `pom`文件中还有一个属性就是指定当前项目的`main`函数入口,如果大家和我的包名或者类名(下面步骤`4`中的类名)不一致,那么也需要修改一下:

4. 在`src/main/java`目录下的`com.lonely.wolf.redis`包内新建一个测试类`TestJedisSentinel.java`进行测试:
~~~java
package com.lonely.wolf.redis;
import redis.clients.jedis.JedisSentinelPool;
import java.util.HashSet;
import java.util.Set;
public class TestJedisSentinel {
private static JedisSentinelPool pool;
private static JedisSentinelPool initJedisSentinelPool() {
String masterName = "mymaster"; // mymaster的名字需要和sentinel.conf配置文件里面的名称相同
Set<String> sentinels = new HashSet<String>();
sentinels.add("localhost:26379");
sentinels.add("localhost:26380");
sentinels.add("localhost:26381");
pool = new JedisSentinelPool(masterName, sentinels);
return pool;
}
public static void main(String[] args) {
JedisSentinelPool pool = initJedisSentinelPool();
pool.getResource().set("name", "longly_wolf");
System.out.println(pool.getResource().get("name"));
}
}
~~~
连接时需要把所有`Sentinel`的连接建立并放入池内,然后客户端会遍历其中所有服务,找到第一个可用的`Sentinel`服务,并获取到`master`服务器的地址,然后建立连接。
5. 执行如下命令(注意这里是因为环境中已经默认安装了`maven`,如果是在自己的机器上则需要安装`maven`)。
~~~bash
# 进入项目主目录
cd redis-demo
# 将项目打包成一个 jar 包
mvn clean package -Dmaven.test.skip=true
~~~
当出现`BUILD SUCCESS`则表示打包成功,这时候找到`target`目录发现一个`jar`包:

6. 执行命令,运行项目可以成功输出`lonely_wolf`。
~~~bash
java -jar target/redis-demo-1.0.0-SNAPSHOT.jar
~~~

这就说明我们的`Sentinel`服务正常运行了,因为代码中我们并没有显示指定`master`节点,而是通过`Sentinel`动态获取。
- Redis 为什么这么快
- 什么是 Redis
- Redis 的安装
- Redis 到底有多快
- Redis 是单线程还是多线程
- Redis 为什么选择使用单线程来执行请求
- 什么是 IO 多路复用机制
- Redis 中 I/O 多路复用的应用
- 一个简单的字符串,为什么 Redis 要设计的如此特别
- Redis 的 9 种数据类型
- 二进制安全字符串
- sds 空间分配策略
- sds 和 C 语言字符串区别
- sds 是如何被存储的
- type 属性
- encoding 属性
- 通过牺牲速度来节省内存,Redis 是觉得自己太快了吗
- 什么是压缩列表
- ziplist 的存储结构
- entry 存储结构
- ziplist 数据示例
- ziplist 连锁更新问题
- 为了加快速度,Redis 都做了哪些“变态”设计
- 列表对象
- linkedlist
- linkedlist 和 ziplist 的选择
- quicklist
- 列表对象常用操作命令
- Redis 中哈希分布不均匀该怎么办
- 哈希对象
- hashtable
- ziplist
- ziplist 和 hashtable 的编码转换
- 哈希对象常用命令
- 同一份数据,Redis 为什么要存”两次”
- 五种基本类型之集合对象
- intset 编码
- 集合对象常用命令
- 五种基本类型之有序集合对象
- skiplist 编码
- ziplist 编码
- ziplist 和 skiplist 编码转换
- 有序集合对象常用命令
- 要想用活 Redis,Lua 脚本是绕不过去的坎
- 发布与订阅
- 基于频道的实现
- 基于模式的实现
- Lua 脚本
- Lua 脚本的调用
- Lua 脚本中执行 Redis 命令
- Lua 脚本摘要
- Lua 脚本文件
- 脚本异常
- 作为一款内存数据库,为什么断电后 Redis 数据不会丢失
- Redis 持久化机制
- RDB 持久化机制
- AOF 持久化机制
- 内存耗尽后 Redis 会发生什么
- 内存回收
- 过期策略
- 8 种淘汰策略
- LRU 算法
- LFU 算法
- 不能回滚的 Redis 事务还能用吗
- Redis 有事务吗
- Redis 事务实现原理
- Redis 事务 ACID 特性
- watch 命令
- watch 命令的作用
- watch 原理分析
- Redis 为什么不直接用 master-slave 集群
- Redis 集群方案
- 主从复制
- 配置一主两从 master-slave 集群
- 主从复制原理分析
- 主从服务的不足之处
- Sentinel(哨兵)机制为什么从神坛滑落
- 哨兵 Sentinel 机制
- Sentinel 原理分析
- 配置 Sentinel 集群
- Sentinel 机制实战
- Sentinel 机制的不足之处
- Redis Cluster 集群凭什么成为了最终的胜利者
- Redis 分布式集群方案
- 客户端实现分片
- 中间代理服务实现分片
- Redis Cluster 方案
- 手动配置一个 Redis Cluster 集群
- Redis Cluster 集群常用命令
- 客户端如何使用 Redis Cluster 集群
- Redis Cluster 的不足
- 如何从 10 亿数据中快速判断是否存在某一个元素
- 缓存雪崩
- 缓存击穿
- 缓存穿透
- 布隆过滤器(Bloom Filter)
- 布隆过滤器的 2 大特点
- 布隆过滤器的实现(Guava)
- 布隆过滤器的如何删除
