redis sentinel高可用性方案

参考:redis官方文档Redis 复制、Sentinel的搭建和原理说明

Redis Sentinel(哨兵) 是redis自带的集群管理工具。目前官方推荐使用redis2.8或3.0及以上版本,一个稳定的Sentinel 2已经包括在这些版本中,redis2.6不建议使用。

主要功能

  • 监控(Monitoring)
        Sentinel会不断检查redis主服务(master)与从服务(slave)是否正常工作
  • 提醒(Notification)
          当被监控的某一个redis服务出现故障时,Sentinel会通过api通知管理员或应用程序
    
  • 灾难自动恢复(Automatic failOver)
          当主服务出现故障,Sentinel会开始灾难恢复,选出一个从服务升级为主服务继续向提供服务
          同时其他的从服务改为监听最新的主服务,当之前的主服务故障恢复后,Sentinel会自动把恢复的服务改成从服务
    
  • 主redis配置提供(Configuration provider)
          客户端通过连接Sentinel来获取当前主redis服务的地址,如果主redis服务挂了,Sentinel会自动报告最新的主redis服务地址
    

简介

Sentinel是一个分布式系统:

多个Sentinel进程相互协作,每一个Sentinel都在自己的配置中运行,Sentinel必须通过配置文件启动,这样做的优势:

  1. 当已知的主redis不可用时,多个Sentinel会对主redis进行故障检测,减少误判
  2. 即使个别Sentinel不可用,整个分布式系统还是可以使用
  3. 通过配置文件保存当前的服务状态,Sentinel重启的时候可以重新加载这些状态
名词解释:
  • 主观下线(Subjectively Down, 简称 SDOWN)
    单个 Sentinel 实例对服务器做出的下线判断
  • 客观下线(Objectively Down, 简称 ODOWN)
    多个Sentinel对同一个服务器做出SDOWN判断,并且互相交流之后, 得出的服务器下线判断。
工作原理:
  1. Sentinel集群通过给定的配置文件发现的master,启动时监控master,同时通过向master发送info来获得所有的slave
  2. sentinel通过命令连接向被监视的主从服务器发送hello信息(每秒一次),以此来向其他sentinel宣告自己的存在
  3. sentinel通过订阅接收其他sentinel发送的hello信息,以此来发现监视同一个master的其他sentinel
  4. sentinel使用ping命令来检测服务的状态,如果在指定的时间内(down-after-milliseconds)没有正确回复,判定SDOWN,触发failover
  5. failover被触发后,不会马上进行,还需要集群中大多数sentinel授权后才可以进行,即进行failover的sentinel会去获得指定个数的sentinel的授权,成功后进入ODOWN。如在5个sentinel中配置了2,等到2个sentinel认为master死了就执行failover。
  6. sentinel向选为master的slave发送SLAVEOF NO ONE命令,选择slave的条件是sentinel首先会根据slaves的优先级来进行排序,优先级越小排名越靠前。
  7. sentinel被授权后,它将会获得宕掉的master的一份最新配置版本号(config-epoch),当failover执行结束以后,这个版本号将会被用于最新的配置,通过广播形式通知其它sentinel,其它的sentinel则更新对应master的配置。


    image.png

配置

目录结构
directoryStructure.png
master redis
#编辑/masterRedisPath/redis_master.conf文件 
bind 10.0.2.190 #默认为127.0.0.1,通过Sentinel获得redis主服务器地址时会映射成此地址,外部链接将无法连接到redis服务
protected-mode no #默认为yes,即只有本机可以访问,关掉保护模式,可以使外部应用访问该redis, 设置为no后一定要设置redis连接密码
port 6379 #默认端口号,当部署主从redis时,需要设置不同的端口
daemonize yes #守护进程
pidfile "/var/run/redis_6379.pid" #pid文件,redis主从服务器需设置不同pid文件路径
logfile "/home/log/redis_6379.log" #redis日志文件
masterauth utry1234 #主服务器验证密码
requirepass utry1234 #redis连接密码
slave redis
#基本与主redis配置相同,只解释不同部分
#slaveof <master-ip> <master-port> 这个是slave的关键,配置后即可成为master的slave
#即redis会采用异步复制的方式将数据从master热备到slave
#默认下slave是只读的,可以通过配置关闭
#编辑/slaveRedispath/redis_slave.conf
bind 10.0.2.190 
protected-mode no 
port 6380 #从redis服务器端口
daemonize yes 
pidfile "/var/run/redis_6380.pid" 
logfile "/home/log/redis_6380.log" 
masterauth utry1234
slaveof 10.0.2.190 6379 #设置从属的主redis服务器访问地址,即以这个配置文件启动的redis为slave
requirepass utry1234
Sentinel
#根据官方推荐配置至少3个Sentinel以保证系统稳定工作
#redis安装目录下提供了sentinel.conf的配置示例,在主redis目录下复制该示例3份,分别命名sentinel63791.conf,sentinel63792.conf,sentinel63793.conf
port 63791 #sentinel端口
protected-mode no #sentinel.conf默认是没有这个配置的,需要手动添加
daemonize yes #守护进程
logfile "/home/log/sentinel_63791.log" #运行日志,可以在此查看主从状态
sentinel monitor mymaster 10.0.2.190 6379 2 #配置监控主服务器,mymaster:定义主服务器名, 10.0.2.190:主服务ip 6379:主服务端口 2:设置当有2个sentinel判断master故障后才真正认为master无法继续提供服务,即开始容灾措施
sentinel down-after-milliseconds mymaster 60000 #指定sentinel认定一个服务器断线的毫秒数,即一个sentinel认定服务SDOWN,在这个配置时间内需要获得指定个数的Sentinel判定ODWON,才开始failover
sentinel failover-timeout mymaster 180000 #在触发failover多少秒后任未执行任何failover,则被认为failover失败
sentinel parallel-syncs mymaster 1 #选项指定了在执行故障转移时, 最多可以有多少个从服务器同时对新的主服务器进行同步,这个数字越小, 完成故障转移所需的时间就越长
sentinel auth-pass mymaster utry1234 #主redis服务器验证密码

启动服务

主redis: redis-server /masterRedisPath/to/redis.conf
从redis: redis-server /slaveRedisPath/to/redis.conf
访问redis: redis-cli -h 10.0.2.190 -p 6379 -a utry1234 #-h:ip地址,-p:访问端口,-a:连接密码
进入redis客户端之后,通过info命令查看redis主从状态: info replication
sentinel: redis-sentinel /path/to/sentinel.conf 
          或 redis-server  /path/to/sentinel.conf  --sentinel
访问sentinel:与访问redis一样,可以用info命令查看集群状态: info

测试

启动master与slave之后
查看master的状态:role:master,同时显示了slave的信息

master_redis.png

查看slave状态:role:slave,同时显示了所属的master redis信息

slave_redis.png

查看Sentenel状态:status =ok,同时显示了当前的master访问地址,以及slave和sentinel数量

sentinel_63791_conf.png

down掉master redis 进程,查看sentinel日志,sentinel自动把slave选举为新的master,同时slave的状态信息role:master

sentinel_63791_log.png
过程解释:
  1. Sentinel发现master不可用判定主观下线(SDOWN)
  2. 与集群中其他的Sentinel交流后判定为客观下线(ODWON)
  3. Sentinel投票选举出一个领头羊Sentienl,由这个领头羊来进行failover
  4. 领头羊将选出一个slave升级为master,同时修改这个被升级的slave的配置使其成为master的配置
  5. 将其他的slave配置改成最新master的slave,同时通知其他Sentinel进行修改
  6. 当之前的master从故障中恢复后,sentinel会自动发现,并采用最新的配置,将这个恢复的redis改成最新master的slave
new_slave.png

与Jedis集成

jedis支持Sentinel+redis形式的高可用redis方案
gradle
compile 'redis.clients:jedis:2.6.3'
compile 'org.springframework.data:spring-data-redis:1.6.0.RELEASE' 
spring XML configuration
<bean id="sentinelConfig" class="org.springframework.data.redis.connection.RedisSentinelConfiguration">
    <property name="master"><!-- 配置master的名字,和Sentinel中配置的master名字一致 -->
      <bean class="org.springframework.data.redis.connection.RedisNode">
        <property name="name" value="mymaster"></property>
      </bean>
    </property>
    <property name="sentinels"><!-- 配置可用的Sentinel -->
         <set>
            <bean class="org.springframework.data.redis.connection.RedisNode">                   
                <constructor-arg name="host" value="10.0.2.190"/>
                <constructor-arg name="port" value="63791"/>               
            </bean>
            <bean class="org.springframework.data.redis.connection.RedisNode">                   
                <constructor-arg name="host" value="10.0.2.190"/>
                <constructor-arg name="port" value="63792"/>               
            </bean>
            <bean class="org.springframework.data.redis.connection.RedisNode">                   
                <constructor-arg name="host" value="10.0.2.190"/>
                <constructor-arg name="port" value="63793"/>               
            </bean>
        </set>
    </property>
</bean>
<!-- 配置redis连接工厂 -->
<bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
    <constructor-arg ref="sentinelConfig" /><!--  sentinel配置-->
    <property name="password" value="utry1234"/><!-- redis连接密码 -->
</bean>
<!-- redis操作模板,在代码中注入这个模板,就可以进行redis的相关操作了  -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
    <property name="connectionFactory" ref="jedisConnectionFactory" />
</bean>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容