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模式为本人实测

posted @ 2019-05-09 10:12  陈浩宇人呢  阅读(1053)  评论(0编辑  收藏  举报