欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Redis--AKF架构

程序员文章站 2022-03-26 18:18:22
Redis--AKF架构AKF架构由于redis是单进程、单线程、单实例的,所以如果我们只使用一个redis与客户端交互就会带来单点故障、缓存容量、压力等一系列问题,如下图所示基于以上三种问题,人们提出了AKF架构,其中,x轴的扩展为redis的全量镜像,保证当前redis挂掉之后服务依然可以正常提供,而且x轴上的redis实例可以向client提供一些服务,缓解压力x轴的扩展有效的缓解了压力和单点故障的问题,但是依旧没有解决容量的问题,毕竟由于要保持数据一致,其中一个满了,其它的也会满,...

Redis--AKF架构

  1. AKF架构

    1. 由于redis是单进程、单线程、单实例的,所以如果我们只使用一个redis与客户端交互就会带来单点故障、缓存容量、压力等一系列问题,如下图所示
      Redis--AKF架构
    2. 基于以上三种问题,人们提出了AKF架构,其中,x轴的扩展为redis的全量镜像,保证当前redis挂掉之后服务依然可以正常提供,而且x轴上的redis实例可以向client提供一些服务,缓解压力
      Redis--AKF架构
    3. x轴的扩展有效的缓解了压力和单点故障的问题,但是依旧没有解决容量的问题,毕竟由于要保持数据一致,其中一个满了,其它的也会满,所以,y轴的扩展就是基于业务,不同的场景使用不同的redis
      Redis--AKF架构
    4. 同样的道理,z轴的扩展就是将数据根据优先级进行更细粒度的划分,进一步降低数据的耦合度
      Redis--AKF架构
    5. 到了这里AKF的架构图已经画出来了,但其中依旧有许多存在的问题,这里我们首先要明确一点,在一台服务器中,无论我们后面分了多少redis,有多少集群,对用户来说都是不可见的,用户只负责调用服务,因此,这时我们就需要考虑以下的问题
      1. X轴上的全量拷贝怎么实现?如何操作?
      2. Y轴上根据业务场景的划分怎么实现?
  2. 主从复制

    1. 解决上面提出的第一个问题,全量拷贝使用redis提供的RDB方式很容易便可实现,但是所有的redis实例显然不能同时提供读写服务,若是都提供写服务,需要考虑数据同步的问题,这会明显拖慢redis的速度,违背了redis的设计初衷。因此,大部分情况下,是由一个redis实例提供读写服务,其它的redis实例只提供读服务,这就是redis的主从复制,提供完整服务的redis为主,其它为从
    2. 基于主从复制搭建了集群后,我们就需要考虑数据一致性的问题了,主redis写入数据后,从redis如何知道,如何同步?有三种思路
      1. 同步阻塞:主redis写入数据后,从redis进入阻塞状态同步数据,这个状态下不提供服务,但这显然是不可取的,破坏了可用性
        Redis--AKF架构
      2. 异步(redis选择的方式):在同步数据的同时,从redis继续提供服务,但由于是异步的,所以可能导致数据未能成功读取,视作丢失数据
        Redis--AKF架构
      3. 使用中间代理,在主redis和从redis间使用一种其它集群技术(例如kafka),该集群必须拥有高可靠性和响应时间短的特点。在主redis更新完数据后,同步到中间代理上,中间代理阻塞从redis,更新数据,自己代替从redis提供服务。该方法虽然依旧有可能丢失数据,但明显比上面的更可靠。为什么redis不使用该方法?保证redis的快!
        Redis--AKF架构
    3. 了解了数据一致性后,我们会发现一个新的问题:主redis只有一台,它down掉了怎么办?芜湖,又回到最初的起点~(๑´ㅂ`๑)。但其实是有些不一样的,由于我们有了从redis,而数据又和主redis一致,显然我们可以从中挑选一个新的主redis,其它redis继续跟随它,继续提供服务,这就牵扯redis的哨兵机制了。
      1. 首先,显然不可能由用户发现不对后再告诉redis主redis挂了,从redis是可以根据连接来判断主redis的状态的,由于从redis也可能出现故障,所以redis内部规定需要有一半的从redis认为主redis挂了,才能采取相应的操作,这个时候,从redis的数量选择就需要斟酌一下了
        Redis--AKF架构
        Redis--AKF架构
      2. 在主redis挂掉之后,所有的哨兵会通过投票的方式选出一个新的主redis,其它从redis继续追随该主redis
  3. 容量问题解决方案

    1. 回到上面提出的第二个问题,Y轴上根据业务场景划分怎么实现,以下有几个方案以供讨论
      1. 在有多台服务器的情况下,我们可以通过逻辑代码的控制,将不同类型的数据交给不同的redis服务端处理,但是当数据无法分类,或者没有多台服务器的情况下,我们该如何划分呢?
      2. 采用hash算法,对所有的数据进行取模运算,再根据结果来划分该存入到哪个redis实例中。但模数值显然是我们一开始就需要指定的,这样当后期遇到什么情况时,扩展就会变得相对困难。
        Redis--AKF架构
      3. 采用随机的方式,将数据随机分不到不同的redis实例中。但使用该方法将导致数据不能精确取出,毕竟你无法判断最近的数据存到了哪个redis中,该模式最常用的地方是消息队列
        Redis--AKF架构
      4. 采用kemata一致性哈希算法
           一致性哈希算法是一种映射算法,将key和设备进行哈希计算,映射到一个哈希环上。在哈希环上绝大部分点是虚拟的,但有一部分点是物理的,即设备与环的映射点。增加虚拟节点的主要目的是为了解决数据倾斜的问题。当我们想设备中存数据的时候,实际上是对数据的key做一致性哈希算法,将得到的值映射到哈希环上,并向左右两边分别寻找设备,找到离他最近的一台设备的物理点,通过物理点将数据写入设备
        Redis--AKF架构
           但是这里存在一个问题,当device3插入到哈希环上的时候,假设我们刚刚把数据存到了device2,这个时候由于device3的加入,有些数据就查不到了,因为查询时是寻找离他最近的物理点。因此,该算法可能造成redis的击穿,即redis中有数据但依然像数据库中进行查找。由于相同的问题,使用该算法的redis更倾向于缓存而不是数据库,因为数据库必须保证数据的完整性!
      5. 在client端和server间添加代理层,由代理来实现上面所述的逻辑代码,这样我们只需要关注代理的性能便可以了,当然,代理也必须是集群,不然依旧会出现单点故障的问题。但是redis并不推荐这种方法,原因依旧是redis想尽可能的保证轻量,尽可能的快!
        Redis--AKF架构
      6. 说了这么多,redis自身到底是使用哪种方式来解决该问题的呢?答案是预分区
        Redis--AKF架构
        如上图,假设在client端采用取模算法得到了hash值有0-9十个数,现在有三台redis,每一台redis都有一个哈希映射,client端可以通过映射去redis寻找数据,并且每台redis还有其他两台redis的映射表。客户端如果想找key为3的数据,那么先随机找一个redis,redis对key进行取模然后去自己的映射表找有没有能和取模后的数对应上的,有的话直接返回数据,没有的话在其他两个redis的映射表中去寻找是否还有该key,没有的话告诉没找到,有的话返回客户端让他重定向到另一个redis,定位到了redis3。基于此方式,redis自身很难实现事务相关操作,需要由用户控制。
  4. 零碎知识点

    1. replicaof host port : 将当前redis实例作为从redis,host为主redis ip地址,port为端口号,若输入replicaof no one则代表当前redis实例脱离主redis
    2. 当初次完成追随后,从redis中的数据会被清空,将用RDB的方式从主redis中拿取数据
    3. 当从redis挂掉后,若在一段时间内再次联系上主redis,则会有以下两种情况
      1. 若在配置文件中配置了必须使用AOF方式来转移数据,则一定会导致从redis中原有数据被清空,重新读入数据,因为AOF文件中并不会记录相关的主从信息
      2. 若配置文件中没有指定必须用AOF方式转移数据,则会判断此时的数据是否超过repl-backlog-size配置的值,没超过则使用AOF添加数据,超过了则重新读入数据。比如若repl-backlog-size设置的值为5m,则当从redis重新追随主redis时,判断从它挂掉的时间点到现在主redis是否写入了超过5m的数据,未超过则代表还有救,可以使用AOF往后追加数据,超过了则表示没救了,重新写入!
    4. 启动哨兵:redis-server 配置文件路径(里面写需要监控的redis) --sentinel,下面是配置文件最简单的写法
      Redis--AKF架构
    5. 哨兵与哨兵间通过订阅和发布的方式交流信息

本文地址:https://blog.csdn.net/qq_45489824/article/details/107355046

相关标签: redis