sentinel哨兵是特殊的redis服务,不提供读写服务,主要用来监控redis实例节点。
哨兵架构下client端第一次从哨兵找出redis的主节点,后续就直接访问redis的主节点,不会每次都通过
sentinel代理访问redis的主节点,当redis的主节点发生变化,哨兵会第一时间感知到,并且将新的redis
主节点通知给client端(这里面redis的client端一般都实现了订阅功能,订阅sentinel发布的节点变动消息)
redis哨兵架构搭建步骤:
1
1
、复制一份
sentinel
.
conf
文件
2
cp sentinel
.
conf sentinel
‐
26379.
conf
3
4
2
、将相关配置修改为如下值:
5
port
26379
6
daemonize yes
7
pidfile
"/var/run/redis‐sentinel‐26379.pid"
8
logfile
"26379.log"
9
dir
"/usr/local/redis‐5.0.3/data"
10
# sentinel monitor
<
master
‐
redis
‐
name
> <
master
‐
redis
‐
ip
> <
master
‐
redis
‐
port
> <
quorum
>
11
#
quorum
是一个数字,指明当有多少个
sentinel
认为一个
master
失效时
(
值一般为:
sentinel
总数
/
2
+
1
)
,
master
才算真正失效
12
sentinel monitor mymaster
192.168.0.60 6379 2
# mymaster
这个名字随便取,客户端访问时会用
到
13
14
3
、启动
sentinel
哨兵实例
15
src
/
redis
‐
sentinel sentinel
‐
26379.
conf
16
17
4
、查看
sentinel
的
info
信息
18
src
/
redis
‐
cli
‐
p
26379
19
127.0.0.1
:
26379
>
info
20
可以看到
Sentinel
的
info
里已经识别出了
redis
的主从
21
22
5
、可以自己再配置两个
sentinel
,端口
26380
和
26381
,注意上述配置文件里的对应数字都要修改
23
sentinel集群都启动完毕后,会将哨兵集群的元数据信息写入所有sentinel的配置文件里去(追加在文件的
最下面),我们查看下如下配置文件sentinel-26379.conf,如下所示:
1
sentinel known
‐
replica mymaster
192.168.0.60 6380
#
代表
redis
主节点的从节点信息
2
sentinel known
‐
replica mymaster
192.168.0.60 6381
#
代表
redis
主节点的从节点信息
3
sentinel known
‐
sentinel mymaster
192.168.0.60 26380 52
d0a5d70c1f90475b4fc03b6ce7c3c569
35760f #
代表感知到的其它哨兵节点
4
sentinel known
‐
sentinel mymaster
192.168.0.60 26381
e9f530d3882f8043f76ebb8e1686438ba8
bd5ca6 #
代表感知到的其它哨兵节点
当redis主节点如果挂了,哨兵集群会重新选举出新的redis主节点,同时会修改所有sentinel节点配置文件
的集群元数据信息,比如6379的redis如果挂了,假设选举出的新主节点是6380,则sentinel文件里的集
群元数据信息会变成如下所示:
1
sentinel known
‐
replica mymaster
192.168.0.60 6379
#
代表主节点的从节点信息
2
sentinel known
‐
replica mymaster
192.168.0.60 6381
#
代表主节点的从节点信息
3
sentinel known
‐
sentinel mymaster
192.168.0.60 26380 52
d0a5d70c1f90475b4fc03b6ce7c3c569
35760f #
代表感知到的其它哨兵节点
4
sentinel known
‐
sentinel mymaster
192.168.0.60 26381
e9f530d3882f8043f76ebb8e1686438ba8
bd5ca6 #
代表感知到的其它哨兵节点
同时还会修改sentinel文件里之前配置的mymaster对应的6379端口,改为6380
1
sentinel monitor mymaster
192.168.0.60 6380 2
当6379的redis实例再次启动时,哨兵集群根据集群元数据信息就可以将6379端口的redis节点作为从节点
加入集群
哨兵的Jedis连接代码:
1
public class
JedisSentinelTest
{
2
public static void
main
(
String
[]
args
)
throws IOException
{
3
4
JedisPoolConfig config
=
new
JedisPoolConfig
();
5
config
.
setMaxTotal
(
20
);
6
config
.
setMaxIdle
(
10
);
7
config
.
setMinIdle
(
5
);
8
9
String masterName
=
"mymaster"
;
10
Set
<
String
>
sentinels
=
new
HashSet
<
String
>
();
11
sentinels
.
add
(
new
HostAndPort
(
"192.168.0.60"
,
26379
).
toString
());
12
sentinels
.
add
(
new
HostAndPort
(
"192.168.0.60"
,
26380
).
toString
());
13
sentinels
.
add
(
new
HostAndPort
(
"192.168.0.60"
,
26381
).
toString
());
14
//JedisSentinelPool
其实本质跟
JedisPool
类似,都是与
redis
主节点建立的连接池
15
//JedisSentinelPool
并不是说与
sentinel
建立的连接池,而是通过
sentinel
发现
redis
主节点并与其
建立连接
16
JedisSentinelPool jedisSentinelPool
=
new
JedisSentinelPool
(
masterName
,
sentinels
,
co
nfig
,
3000
,
null
);
17
Jedis jedis
=
null
;
18
try
{
19
jedis
=
jedisSentinelPool
.
getResource
();
20
System
.
out
.
println
(
jedis
.
set
(
"sentinel"
,
"zhuge"
));
21
System
.
out
.
println
(
jedis
.
get
(
"sentinel"
));
22
}
catch
(
Exception e
) {
23
e
.
printStackTrace
();
24
}
finally
{
25
//
注意这里不是关闭连接,在
JedisPool
模式下,
Jedis
会被归还给资源池。
26
if
(
jedis
!=
null
)
27
jedis
.
close
();
28
}
29
}
30
}
哨兵的Spring Boot整合Redis连接代码见示例项目:redis-sentinel-cluster
1、引入相关依赖:
1
<
dependency
>
2
<
groupId
>
org
.
springframework
.
boot
</
groupId
>
3
<
artifactId
>
spring
‐
boot
‐
starter
‐
data
‐
redis
</
artifactId
>
4
</
dependency
>
5
6
<
dependency
>
7
<
groupId
>
org
.
apache
.
commons
</
groupId
>
8
<
artifactId
>
commons
‐
pool2
</
artifactId
>
9
</
dependency
>
springboot项目核心配置:
1
server
:
2
port
:
8080
3
4
spring
:
5
redis
:
6
database
:
0
7
timeout
:
3000
8
sentinel
:
#
哨兵模式
9
master
:
mymaster #
主服务器所在集群名称
10
nodes
:
192.168.0.60
:
26379
,
192.168.0.60
:
26380
,
192.168.0.60
:
26381
11
lettuce
:
12
pool
:
13
max
‐
idle
:
50
14
min
‐
idle
:
10
15
max
‐
active
:
100
16
max
‐
wait
:
1000
17
访问代码:
1
@RestController
2
public class
IndexController
{
3
4
private static
final Logger logger
=
LoggerFactory
.
getLogger
(
IndexController
.
class
);
5
6
@Autowired
7
private
StringRedisTemplate stringRedisTemplate
;
8
9
/**
10
*
测试节点挂了哨兵重新选举新的
master
节点,客户端是否能动态感知到
11
*
新的
master
选举出来后,哨兵会把消息发布出去,客户端实际上是实现了一个消息监听机制,
12
*
当哨兵把新
master
的消息发布出去,客户端会立马感知到新
master
的信息,从而动态切换访问的
maste
rip
13
*
14
*
@throws InterruptedException
15
*/
16
@
RequestMapping
(
"/test_sentinel"
)
17
public void
testSentinel
()
throws InterruptedException
{
18
int i
=
1
;
19
while
(
true
){
20
try
{
21
stringRedisTemplate
.
opsForValue
().
set
(
"zhuge"
+
i
,
i
+
""
);
22
System
.
out
.
println
(
"
设置
key
:
"
+
"zhuge"
+
i
);
23
i
++
;
24
Thread
.
sleep
(
1000
);
25
}
catch
(
Exception e
){
26
logger
.
error
(
"
错误:
"
,
e
);
27
}
28
}
29
}
30
}
StringRedisTemplate与RedisTemplate详解
spring 封装了 RedisTemplate 对象来进行对redis的各种操作,它支持所有的 redis 原生的 api。在
RedisTemplate中提供了几个常用的接口方法的使用,分别是:
1
private
ValueOperations
<
K
,
V
>
valueOps
;
2
private
HashOperations
<
K
,
V
>
hashOps
;
3
private
ListOperations
<
K
,
V
>
listOps
;
4
private
SetOperations
<
K
,
V
>
setOps
;
5
private
ZSetOperations
<
K
,
V
>
zSetOps
;
RedisTemplate中定义了对5种数据结构操作
1
redisTemplate
.
opsForValue
();
//
操作字符串
2
redisTemplate
.
opsForHash
();
//
操作
hash
3
redisTemplate
.
opsForList
();
//
操作
list
4
redisTemplate
.
opsForSet
();
//
操作
set
5
redisTemplate
.
opsForZSet
();
//
操作有序
set
StringRedisTemplate继承自RedisTemplate,也一样拥有上面这些操作。
StringRedisTemplate默认采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存
的。
RedisTemplate默认采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。
![](https://i-blog.csdnimg.cn/blog_migrate/111e2e1209231e81fd15fd424398d57b.png)