• Redis 实战搭建高可用架构


    前言:最近在看关于redis缓存方面的知识,今天就来个 Redis sentinel 高可用架构,实战开始之前,先看看sentinel的概念

    什么是redis-sentinel

      Redis-Sentinel是Redis官方推荐的高可用性(HA)解决方案,当用Redis做Master-slave的高可用方案时,假如master宕机了,
    Redis本身(包括它的很多客户端)都没有实现自动进行主备切换,而Redis-sentinel本身也是一个独立运行的进程,它能监控多个master-slave集群,发现master宕机后能进行自动切换。

    为什么使用sentinel服务

      redis的普通主从模式中,当主数据库遇到异常中断服务后,开发者可以通过手动的方式选择一个从数据库来升格为主数据库,以使得系统能够继续提供服务。然而整个过程相对麻烦且需要人工介入,难以实现自动化。 
    为此,Redis 2.8开始提供了哨兵工具来实现自动化的系统监控和故障恢复功能。 哨兵的作用就是监控redis主、从数据库是否正常运行,主出现故障自动将从数据库转换为主数据库。

    一、首先实现主从复制(一主多从)

    说明:如果这台服务器出现硬盘故障等问题,也会导致数据丢失。为了避免单点故障,通常的做法是将数据库复制多个副本以部署在不同的服务器上,这样即使有一台服务器出现故障,其他服务器依然可以继续提供服务。
       为此, Redis 提供了复制(replication)功能,可以实现当一台数据库中的数据更新后,自动将更新的数据同步到其他数据库上。

    这里,我们把redis.conf作为master,slave_1.conf和slave_2.conf为从
    
    

      1、找到redis.conf,复制出2份(我只有一个服务器,所以通过改变端口来实现)

      

      2、修改以下几项配置

    1、端口号:
            slave_1.conf:6380
            slave_2.conf:6381
    
    2、绑定
            slave_1.conf:slaveof 127.0.0.1 6379
            slave_2.conf:slaveof 127.0.0.1 6379
    
    3、密码(最好跟master一致)
            slave_1.conf:requirepass 123456
        slave_2.conf:requirepass 123456

    4、验证密码(从机对主机验证时,所需的密码)
         
    slave_1.conf:masterauth 123456
          slave_2.conf:masterauth 123456

       

      

      

      

      3、启动主机和从机

       

      

      4、验证结果

      master

      

      slave_1

      

      slave_2

       

      5、流程图

    可以看到主机执行写命令,从机能同步主机的值,主从复制就实现了。

    注意:默认情况下从库是只读的,不能进行修改,需要修改需要设置配置文件中的slave-read-only为no。在命令行里执行slaveof no one可以让一个从库变成主库。

    问题:当主服务器挂了怎么办

    二、引入sentinel(哨兵)模式

    特点:
        1、不时地监控redis是否按照预期良好地运行;
        2、如果发现某个redis节点运行出现状况,能够通知另外一个进程(例如它的客户端);
        3、能够进行自动切换。当一个master节点不可用时,能够选举出master的多个slave(如果有超过一个slave的话)中的一个来作为新的master,
        其它的slave节点会将它所追随的master的地址改为被提升为master的slave的新地址。

      单点sentinel示意图

      集群sentinel示意图(防止单点故障

      

       1、找到sentinel.conf文件

    1、找到sentinel.conf文件,默认在redis源码包里
    2、复制sentinel.conf文件到redis.conf同级目录

      2、配置sentinel.conf

    说明:我这里是单个sentinel,集群sentinel下面方法也通用

    1、port : 当前Sentinel服务运行的端口(注意:多个sentinel,记得修改端口号) 2、dir : Sentinel服务运行时使用的临时文件夹 3、sentinel monitor master001 192.168.110.101 6379 2:Sentinel去监视一个名为master001的主redis实例,这个主实例的IP地址为本机地址192.168.110.101,端口号为6379,
                                    而将这个主实例判断为失效至少需要2个 Sentinel进程的同意(注意:如果是单个sentinel,这里就是1),只要同意Sentinel的数量不达标,
                                    自动failover就不会执行
    4、sentinel auth-pass mymaster 123456:设置连接master和slave时的密码,注意的是sentinel不能分别为master和slave设置不同的密码,因此master和slave的密码应该设置相同。
    4、sentinel down-after-milliseconds master001 30000:指定了Sentinel认为Redis实例已经失效所需的毫秒数。当实例超过该时间没有返回PING,或者直接返回错误,那么Sentinel将这个实例标记为主观下线。
                                    只有一个 Sentinel进程将实例标记为主观下线并不一定会引起实例的自动故障迁移:只有在足够数量的Sentinel都将一个实例标记为主观下线之后,
                                    实例才会被标记为客观下线,这时自动故障迁移才会执行 5、sentinel parallel-syncs master001 1:指定了在执行故障转移时,最多可以有多少个从Redis实例在同步新的主实例,在从Redis实例较多的情况下这个数字越小,同步的时间越长,完成故障转移所需的时间就越长 6、sentinel failover-timeout master001 180000:如果在该时间(ms)内未能完成failover操作,则认为该failover失败 7、sentinel notification-script
    <master-name> <script-path>:指定sentinel检测到该监控的redis实例指向的实例异常时,调用的报警脚本。该配置项可选,但是很常用

      3、启动sentinel

    命令:redis-sentinel  sentinel.conf
    
    说明:redis-sentinel  path (sentinel的配置文件路径) + filename (文件名)
    
    多个sentinel也一样,只需修改filename就行

      

      启动后会在控制台看到如下信息

      

      4、测试sentinel自动切换功能

        1、停止主节点(端口为6379)

         

         2、查看slave节点(端口为6380,6381)

        

        

        可以看到,已经成功切换了

        3、恢复主节点(master)

        

        之前的主节点变成了slave

       5、启动中碰到的问题

    1、redis启动警告问题:WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
      原因:对一个高负载的环境来说tcp设置128这个值,太小了。 
      解决:
          1、临时:执行  echo 511 > /proc/sys/net/core/somaxconn
          2、永久:打开ietc/sysctl.conf,在这里面添net.core.somaxconn= 1024 然后执行sysctl -p 就可以永久消除这个warning
    
    2、在控制台info中没看到* +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379这类的信息,
      而是这个sdown master mymaster 127.0.0.1 6379,Next failover delay: I will not start a failover之类的   原因:没有设置master连接密码   解决:在sentinel.conf上设置 sentinel auth-pass mymaster password(master密码)

    3、启动sentinel出现:
    *** FATAL CONFIG FILE ERROR *** Reading the configuration file, at line 104 'sentinel auth-pass mymaster redis' No such master with specified name.
      原因:这是因为设置sentinel auth-pass的时候没有在sentinel monitor mymaster ... 的下面
      解决:设置在sentinel monitor mymaster ... 的下面就行了

       说明:我上面的例子中,只用了单个sentinel,这会存在单点故障问题。这点需要注意

    三、官方提供的集群高可用架构(redis-cluster)

    前言:关于redis-cluster,这里就不实际操作了,有兴趣的小伙伴可以自己去试试。

      1、这里简单说说redis-cluster的作用   

      即使使用哨兵,redis每个实例也是全量存储,每个redis存储的内容都是完整的数据,浪费内存且有木桶效应。
    为了最大化利用内存,可以采用cluster群集,就是分布式存储。即每台redis存储不同的内容。 采用redis-cluster架构正是满足这种分布式存储要求的集群的一种体现。redis-cluster架构中,被设计成共有16384个hash slot。
    每个master分得一部分slot,其算法为:hash_slot = crc16(key) mod 16384 ,这就找到对应slot。采用hash slot的算法,
    实际上是解决了redis-cluster架构下,有多个master节点的时候,数据如何分布到这些节点上去。
    key是可用key,如果有{}则取{}内的作为可用key,否则整个可以是可用key。群集至少需要3主3从,且每个实例使用不同的配置文件

      示意图

      

      2、redis-cluster架构说明

      在cluster架构下,默认的,一般redis-master用于接收读写,而redis-slave则用于备份,当有请求是在向slave发起时,会直接重定向到对应key所在的master来处理。
    但如果不介意读取的是redis-cluster中有可能过期的数据并且对写请求不感兴趣时,则亦可通过readonly命令,将slave设置成可读,然后通过slave获取相关的key,达到读写分离。

      3、注意事项

    (1)redis-cluster最小配置为三主三从,当1个主故障,大家会给对应的从投票,把从立为主,若没有从数据库可以恢复则redis群集就down了。
    
    (2)在这个redis cluster中,如果你要在slave读取数据,那么需要带上readonly指令。redis cluster的核心的理念,主要是用slave做高可用的,
       每个master挂一两个slave,主要是做数据的热备,当master故障时的作为主备切换,实现高可用的。redis cluster默认是不支持slave节点读或者写的,
       跟我们手动基于replication搭建的主从架构不一样的。slave node要设置readonly,然后再get,这个时候才能在slave node进行读取。对于redis -cluster主从架构,
       若要进行读写分离,官方其实是不建议的,但也能做,只是会复杂一些。 (3)redis-cluster的架构下,实际上本身master就是可以任意扩展的,你如果要支撑更大的读吞吐量,或者写吞吐量,或者数据量,都可以直接对master进行横向扩展就可以了。
       也扩容master,跟之前扩容slave进行读写分离,效果是一样的或者说更好。 (4)可以使用自带客户端连接:使用redis-cli -c -p cluster中任意一个端口,进行数据获取测试。

    以上就是全部内容了,sentinel模式为本人实测

  • 相关阅读:
    LeetCode 404. 左叶子之和
    三年了
    LeetCode 543. 二叉树的直径
    求结点在二叉排序树中层次的算法
    LeetCode 98. 验证二叉搜索树
    LeetCode 236. 二叉树的最近公共祖先
    LeetCode 129. 求根到叶子节点数字之和
    LeetCode 113. 路径总和 II
    LeetCode 107. 二叉树的层次遍历 II
    LeetCode 144. 二叉树的前序遍历 (非递归)
  • 原文地址:https://www.cnblogs.com/chenhaoyu/p/10827054.html
Copyright © 2020-2023  润新知