Redis-AKF/CAP原则

1. AKF 扩展立方体理论

之前讨论的情况都是单机版单进程下的情况

AKF扩展立方体(Scalability Cube),是《架构即未来》一书中提出的可扩展模型,这个立方体有三个轴线,每个轴线描述扩展性的一个维度,他们分别是产品、流程和团队:

X轴 —— 代表无差别的克隆服务和数据,工作可以很均匀的分散在不同的服务实例上;

Y轴 —— 关注应用中职责的划分,比如数据类型,交易执行类型的划分;

Z轴 —— 关注服务和数据的优先级划分,如分地域划分。

AKF拆分原则 业界对可扩展系统架构设计有一个朴素的概念,就是:通过加机器可以解决容量和可用性问题(如果一台不行就两台)用个段子描述就是:(世界上没有什么事是一顿烧烤解决不了的,如果有,那就两顿)

这一理念在“云计算”概念疯狂流行的今天。得到了广泛的认可。对于一个规模迅速增长的系统而言。容量和性能问题当然是首当其冲的。但是随着时间的向前,系统规模的增长,除了面对性能与容量的问题外,还需要面对功能与模块数量上增长带来的系统复杂性问题。以及业务变化带来的提供差异化服务问题。而许多系统在架构设计时并未充分考虑到这些问题,导致系统的重构成为常态。从而影响业务交付能力,还浪费人力财力。对此《可扩展的艺术》一书提出了一个更加系统的可扩展模型----AKF可扩展立方。


1. 单实例问题

单节点,单进程存在的问题:

  • 单点故障
  • 容量有限
  • 数据承载压力有限

redis akf是什么意思 redis akf划分原则_分布式一致性协议

  • X轴:水平复制。全量镜像数据。
  • Y轴:服务功能拆分。按照不同的业务进行分类,类似于oracle的分库。
  • Z轴:按优先级进行数据分区。比如说某个模块数据过多,可以拆分为多个Redis客户端,全量数据分为多份,每个Redis中存一部分数据。
    此时虽然解决了单实例存在的三个问题,那么又会带来数据一致性问题

2. 数据强弱一致性

  • 同步阻塞方式

强一致性导致服务阻塞,可用性差

  • 异步

redis akf是什么意思 redis akf划分原则_caps_02

异步处理,可用性强,但数据一致性差,容易丢失数据

  • 同步阻塞 + 异步

redis akf是什么意思 redis akf划分原则_redis akf是什么意思_03

主节点与中间件之间同步阻塞,可用性相对来说较好(有可能会有脏读现象),可靠的中间件负责进行异步同步数据,最终一致性

2. CAP理论

补充知识:

主备模式:备用机一般不参与业务,只有在主挂掉之后,才会替代主去提供服务;

主从模式:主从同时提供服务,客户端可以访问主,也可以访问从。

Redis一般使用主从复制的模式,但是此时主自己又是一个单点。


对主做HA高可用:

对主做高可用并不是说不让主出现问题,而是对外表现为没有出现问题。人工可以去把其中一个从机设置为主,让另一个从去追随它。但是人往往是不可靠的,所以需要技术或程序来实现,主要是一个程序就会有单点故障的问题,所以程序也必须是一个集群。

假如说有三个监控程序监控一个主Redis的存活状态,那么也就是说Redis的存活状态由三个监控程序说了算。

  • 强一致性,都给出OK:假如说都给出OK,才表示Redis存活,那么必然会破坏可用性,比如说其中一个监控阻塞了,而实际Redis还存活,这相当于监控不可用,所以不可取。
  • 一部分给出OK,另一部分不算数:那么一部分是几个呢?假如拿三个监控举例,那么就只能是1或者2。

推导过程:

  • 1个:统计不准确,不够势力范围,因为每个都可以做主。可能会导致数据不一致,会有网络分区的问题,对外表现为同一服务拿到的数据不同,也就是脑裂。

并不是说发生脑裂不好,有个概念叫分区容忍性。比如说SpringCloud中的Eureka注册中心,假如说本来有十个服务注册到不同的Eureka中,负载的时候需要打到不同的机器上,每个负载发现的服务机器数不一致,但并不影响,对客户端来说,只要有服务可用即可。

  • 2个:这个时候会有两台结成势力范围,两台之间互相通信,这时候给出的结果就是Redis要么存活,要么挂了,不会有中间状态。

2在3个节点成功解决脑裂问题,3在4/5个节点成功解决脑裂问题,可以得出结论,当有n个节点的时候需要n/2+1,也就是过半,一般使用奇数台。

为什么是奇数台?

  1. 3台、4台能承受的风险都是只允许1台出现问题,4台的成本更高。
  2. 4台的时候比3台更容易出现问题,即1台出现问题的概率更大。

主从复制配置:

  • replica-serve-stale-data yes
    表示一个Redis在启动之后,并且将追随一个主Redis,在主给生成RDB文件到从Redis去load RDB文件之前,是否提供查询服务。no的话,直到全部同步完之前不提供服务。
  • replica-read-only yes
    备机是否开启只读模式。
  • repl-diskless-sync no
    主Redis发送RDB有两种方式,第一种方式是通过落到磁盘,从Redis再去load,第二种方式是直接通过网络发送RDB传给从Redis。这就取决于磁盘IO和网络IO哪个更快一些。配置no的话默认是走磁盘方式。
  • repl-backlog-size 1mb
    主从复制,增量复制。在Redis中,除了写入RDB文件外,还维护一个小的队列。当从Redis loadRDB之后,突然挂掉了,然后服务又好了,这时候又需要去同步数据,但是此时的RDB文件已经过时,可以把RDB文件重新覆盖一遍,但是如果此时文件很大的话,又需要浪费时间。此时可以把一个偏移量给到主Redis,然后根据偏移量去获取增量数据,但是这时候取决于队列大小,默认为1MB,如果写的速度非常慢,在这期间没有超过设置的大小,那么是可以的,但是如果写的数据非常多,超过了设置的大小,那么又会走全量复制,所以要根据实际写入的数据设置合适的队列大小。
  • min-replicas-to-write 3 min-replicas-max-lag 10
    可以设置最少写几个写成功,当关心数据一致性的时候,可以设置。默认是注释掉的,如果设置的话其实是在向强一致性靠拢,所以需根据实际应用场景配置。