热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

一文搞懂RedisSentinel

RedisSent

 点击关注Coding小暮,获取更多优质内容哦

一文搞懂Redis Sentinel

其实redis真正的高可用只有两种:Redis Sentinel(哨兵模式)
Redis Cluster(集群默认)
如果有人说还有主从复制模式,那你就可以用这篇文章甩出来怕怕打他的脸了。主从复制就两台机器,如果master挂了还得手动切换,这样算高可用?顶多算是备份。下面我们来详细说一下这两种高可用的配置方式以及使用方法。

Redis哨兵模式(Sentinel)

Sentinel的特点是自动故障转移,单节点运行。为什么我这里说单节点运行呢?是因为在Sentinel模式下,真正给应用提供服务的只有master一台机器,它使用的内存容量是有限的,不能像集群那也成倍增长,但是他最大的优点就是他的自动故障转移。应用服务器只需要连接Sentinel节点就好了,不需要关心到底有几台在运行的redis节点,因为Sentinel会给应用程序返回可用的master节点。我们采用先6个redis节点来搭建Redis Sentinel

服务器类型角色ip端口
redismaster127.0.0.16379

slave127.0.0.16380

slave127.0.0.16381
sentinel-127.0.0.126379

-127.0.0.126380

-127.0.0.126381

配置文件

我们在redis的安装目录下新建redis-sentinel目录:

  1. 复制redis.conf到redis-sentinel目录中,并修改文件名,格式:redis-{role}-{port}.conf
  2. 复制sentinel.conf到redis-sentinel目录中,并修改文件名,格式:sentinel-{port}.conf

最终如下图

部署架构

最终的部署效果是,sentinel节点相互监控,每个sentinel都监控redis的master节点,并通过master节点知晓它的所有slave节点

redis节点的配置

redis-master-6379.conf 修改内容

# 任意网络可访问(注意此参数在生产环境不可以配置的这么随意)
bind 0.0.0.0
# 设置master节点的访问密码
requirepass 123456

redis-slave-6380.conf、redis-slave-6381.conf 配置修改

# 任意网络可访问(注意此参数在生产环境不可以配置的这么随意)
bind 0.0.0.0
# 设置slave节点的访问密码
requirepass 123456
# master节点的ip端口
slaveof 127.0.0.1 6379
# master节点的密码
masterauth 123456
# 修改为自己的端口号
port 6381

sentinel节点的配置

sentinel-26379.conf

# 配置sentinel的监听,参数解析
# sentinel monitor    
# :master的名称
#      :master节点的ip
#  :master节点的端口
#     :代表大于 个sentinel个节点认为master不可用时,才会进行故障转移
sentinel monitor mymaster 127.0.0.1 6379 2
# master节点的密码
sentinel auth-pass mymaster 123456
# 修改为自己的端口
port 26379

启动命令

完成以上操作后,就可以到命令行启动了。redis Sentinel的启动顺序是 master->slave->slave->sentinel,所以我们的启动命令就是

# 进入redis bin目录
cd redis4.0.11/bin/
# 启动redis
./redis-server ../redis-sentinel/redis-master-6379.conf &
./redis-server ../redis-sentinel/redis-slave-6380.conf &
./redis-server ../redis-sentinel/redis-slave-6381.conf &
# 启动sentinel
./redis-server ../redis-sentinel/sentinel-26379.conf  --sentinel &
./redis-server ../redis-sentinel/sentinel-26380.conf  --sentinel &
./redis-server ../redis-sentinel/sentinel-26381.conf  --sentinel &

启动成功的验证

sys@syl bin % ps -ef|grep redis
  501 77809 12304   0  5:54下午 ttys001    0:00.07 ./redis-server 0.0.0.0:6379 
  501 77810 12304   0  5:54下午 ttys001    0:00.06 ./redis-server 0.0.0.0:6380 
  501 77811 12304   0  5:54下午 ttys001    0:00.06 ./redis-server 0.0.0.0:6381 
  501 78130 12304   0  5:55下午 ttys001    0:00.06 ./redis-server *:26379 [sentinel]  
  501 78351 12304   0  5:56下午 ttys001    0:00.01 ./redis-server *:26380 [sentinel]  
  501 78352 12304   0  5:56下午 ttys001    0:00.01 ./redis-server *:26381 [sentinel]  
  501 78376 12304   0  5:56下午 ttys001    0:00.00 grep redis

看到这里的胖友可能有些疑惑,sentinel的配置文件只是配置了master节点,其他sentinel节点、slave节点的信息都没有配置,他们是怎么感知到的呢?这个一个好问题,sentinel是通过发布订阅功能来自动发现正在监视相同master节点的其他sentinel的(也就是通过发布订阅功能发现了自己的兄弟节点)。那第二个问题,sentinel是如何自动发现slave的呢?事实上sentinel只需要知道master节点就可以了,因为master节点上记录了它对于的slave节点的数据,所以sentinel获取到master节点的时候,就可以问master要注册在它下面的slave节点的信息了。这一点很有用,在redis cluster中也会用到这一点。

几个重要参数说明

还有几个sentinel配置的重要的参数上面没有给出,下面整理一下统一说明

sentinel down-after-milliseconds <服务名称> <毫秒数>

指定哨兵在监控Redis服务时(sentinel会定时向redis服务发送PING命令),当Redis服务在一个默认毫秒数内都无法回答时,单个哨兵认为的主观下线时间,默认为30000(30秒)

sentinel parallel-syncs <服务名称> <服务器数> 

指定可以有多少个Redis服务同步新的主机,一般而言,这个数字越小同步时间越长,而越大,则对网络资源要求越高

sentinel failover-timeout <服务名称> <毫秒数> 

故障切换的毫秒数,超过这个时间,就认为故障切换失败,默认为3分钟

sentinel notification-script <服务名称> <脚本路径> 

指定sentinel检测到该监控的redis实例指向的实例异常时,调用的报警脚本。该配置项可选,比较常用

sentinel client-reconfig-script mymaster /var/redis/reconfig.sh
sentinel client-reconfig-script  

当发生故障转移时,可以调用脚本来执行特定的任务。

主观下线和客观下线的定义

Redis 的 Sentinel 中关于下线有两个不同的概念:主观下线:指的是单个Sentinel对redis服务器做出了下线判断
客观下线:指的是多个Sentinel实例在对redis同一个服务做出了Sdown的判断,并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后, 得出的服务器下线判断。

java程序如何访问Sentinel集群

pom.xml引入

 <dependency>
   <groupId>redis.clientsgroupId>
   <artifactId>jedisartifactId>
   <version>3.1.0version>
dependency>

java代码

public class Main {
    public static String USER_UV = "user_uv";
    public static void main(String[] args) {
        HashSet sentinelList = new HashSet<>(Arrays.asList("127.0.0.1:26379",
                "127.0.0.1:26380","127.0.0.1:26381"));
        JedisSentinelPool sentinelPool = new JedisSentinelPool("mymaster",sentinelList,"123456");
        Jedis jedis = sentinelPool.getResource();
        jedis.set(USER_UV,"123123123");
        String s = jedis.get(USER_UV);
        System.out.println(s);
    }
}






     


推荐阅读
author-avatar
手机用户2502939795
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有