《从零开始学架构》读书笔记(下)

《从零开始学架构》读书笔记(下)

书接上文

思维导图

《从零开始学架构》读书笔记(下)_第1张图片

高可用架构模式

高可用的理论

CAP

在一个分布式系统(指互相连接并共享数据的节点的集合)中,当涉及到读写操作时,只能保证一致性(Consistence)可用性(Availability)分区容错性(Partition Tolerance)三者中的两个,另外一个必须被牺牲

一致性

对某个指定的客户端来说,读操作保证能够返回最新的写操作数据

可用性

非故障的节点在合理的时间内返回合理的响应(不是错误和超时的响应)

分区容忍性

当出现网络分区(发生丢包、连接中断、拥塞等)后,系统能够继续按预期工作

CAP为什么只能选两个

首先,你肯定是要选P分区容忍性的,因为网络本身是无法100%可靠的,所以分区是必然的,你也不想网络一点抖动你系统就挂了吧。如果不选分区容忍性,那么发生分区时,为了保障一致性,系统要禁止写操作,当发生写操作时返回err,这又和可用性冲突了,所以理论上你必须选P分区容忍性

CP一致性+分区容忍性:前面说了,当发生分区时,为了保障一致性,要禁止写操作返回err,所以这时候可用性是不能被满足的,所说CAP只能满足CP。

AP可用性+分区容忍性:为了保障可用性,发生分区时,底层数据无法同步,必然造成数据的不一致,这时系统还要对外提供服务,所以CAP只能满足AP。

CAP还有一些细节需要注意。

  • CAP关注的粒度是数据,而不是整个系统
  • CAP是忽略网络延迟的,这就意味着一致性是不可能完美实现的
  • 正常情况下,可以同时满足CA。分区不存在的时候可用性一致性是可以同时被满足的
  • 分区恢复后,需要为数据的同步做准备

ACID

ACID是数据库管理系统为了保证事务的正确性而提出来的一个理论,包含四个约束:

  • 原子性(Atomicity): 一个事务中所有操作,要么全部完成,要么全部不完成,没有中间状态
  • 一致性(Consistency): 在事务开始之前和事务结束之后,数据库的完整性没有被破坏
  • 隔离性(isolation):允许多个并发事务同时执行
  • 持久性(durability): 事务处理结束后,对数据的修改就是永久的,即使系统故障也不会丢失

BASE

BASE是指基本可用(Basically Available)软状态(Soft State)最终一致性(Eventual Consistency)。其核心思想是即使无法做到强一致性,但可以采用合适的方式达到最终一致性。现实中很多系统大多都是采用的最终一致性,强一致性常见于金融业务。

  • 基本可用:在系统出现故障时,允许损失部分可用性,保证核心业务可用就行,影响范围尽可能小
  • 软状态:也就是短时间的数据不一致
  • 最终一致性:所有数据副本经过一段时间后,最终能够达到一致的状态

FMEA

FMEA(故障模式与影响分析)又称为失效模式与后果分析等,是一套分析和思考的方法。具体分析方法如下:

  1. 给出初始的架构设计图
  2. 假设架构中的某个部件发生故障
  3. 分析此故障对系统功能造成的影响
  4. 根据分析结果,判断架构是否需要进行优化

此方法输出的是一份表格,包含功能点故障模式故障影响严重程度故障原因故障概率风险程度已有措施解决措施后续规划。总结来说就是一份分析报告,列出系统的薄弱点,并提出改进措施,很可能改进之后又会引入新的薄弱点,所以需要不断更新。除此之外也可以当成一份运维手册来看,当发生故障时看看这份表上有没有相应的补救措施。

存储高可用

存储高可用本质都是将数据复制到多个节点,通过冗余来实现高可用。这类方案都要面对的一个问题是复制延迟和中断导致的数据不一致。任何一个存储高可用方案,都要想清楚以下几点:

  • 数据是怎么复制的
  • 各个数据节点的职责是什么,是单纯备份还是对外提供服务还是二者兼有
  • 如何面对复制延迟
  • 如果面对复制中断

主备复制

主机对外提供服务,通过复制通道将数据复制到备机,备机不对外提供服务。发生故障时需要将客户端的请求转到备机上。

缺点是如果主机永久挂了,对于复制延迟和中断造成的数据缺失没啥好的解决方案。由于备机不提供服务,平时会造成资源浪费。

优点就是比较简单,适用于内部管理系统。

主从复制

跟主备复制类似,但是备机是可以对外提供读服务的。

优点就是机器资源得到有效利用,主机挂了,读操作不受影响

缺点就是如果延迟比较高,写完立即读可能读到旧数据。也比较复杂,需要将不同的操作发给不同的机器

适应于论坛新闻类的业务,读多写少,影响范围可以控制

主备倒换和主从倒换

无论是上面哪种模式,发生故障时都要进行角色的转换。需要有状态的判断机制和倒换策略。例如:

  • 状态是怎么传递的
  • 传递的内容是什么?是心跳?还是包含了当前负载状态?
  • 什么时候进行转换?没心跳转换?还是延迟高就转换?
  • 转换手段是什么?人工or自动?
  • 故障节点恢复后,数据冲突怎么解决?永远不恢复,缺失的数据怎么办?

根据状态传递渠道的不同,常见的主备倒换架构有三种形式:

  • 互连式:主备互联。这里操作空间很大,怎么连?单向还是双向?万一通道本身出问题,那备机可就自己决定变成主机了
  • 中介式:主备机分别向中介机发生信息,中介来决定角色。这种模式要简单很多,但是也要注意中介本身挂了的情况
  • 模拟式:备机假装成客户端,向主机发请求,请求异常自己升级为主机。实现比互连简单,但是仅依靠响应信息决策还是有点草率

数据集群

当一台节点存储不下全部数据时,上面的两种方案就用不了了,就要上数据集群了,把数据分散到各个节点上。此方案的复杂点在于如何将数据分配到不同的服务器上,设计时需要考虑以下几点:

  • 均衡性:各个节点的数据大小是均衡的
  • 容错性:部分节点故障时,需要将原来分配给故障节点的数据分区分配给其他节点
  • 可伸缩性:需要扩容时,能够自动迁移数据

既然数据分散到各个节点,那避免不了的问题就是分布式事务。目前分布式事务算法非常多,但再多的算法也不能彻底解决问题,极端情况下还得看人工。目前常用的分布式事务算法有:

  • 2PC: 二阶段提交。分为请求阶段和提交阶段。缺点比较明显,存在同步阻塞、状态不一致和单点故障问题
  • 3PC: 三节点提交。分为提交判断、准备提交和提交执行三个阶段。解决了单点故障导致的系统阻塞问题,但还是没解决数据不一致问题。
  • 消息表:把各个节点的执行情况记录到一张表里,协调者挂了之后新的协调者根据表信息再决定怎么操作,比较复杂。

数据分区

数据分区是指将数据按照一定的规则进行分区,不同分区分布到不同的地理位置上,每个分区存储一部分数据,通过这种方式来规避地理级别的故障。分区规则有很多,你可以选城市分区、国家分区、洲际分区等,一般看业务量决定。同时,即使是数据分区,也要考虑分区数据的备份,万一真发生地理级别的故障,还是要尽可能将数据恢复。一般有以下几种备份规则:

  • 集中式:所有分区备份到一个总的数据中心。简单是简单,但是总的数据中心一旦挂掉,也挺头疼。
  • 互备式:各个数据分区互相备份。稳定性大大上升,但是拓展性很差,后续增加一个新分区,是放到哪里备份呢?
  • 独立式:各个数据分区有自己的数据中心。终极解决方式,但是成本非常高。

计算高可用

计算高可用的主要目的是当部分节点故障时,服务依然能正常对外提供服务。因此和存储高可用的思路是一致的,就是通过冗余来规避风险。这里复杂度主要体现在任务管理方便,即怎么分发任务任务执行失败后怎么处理的问题。架构一般由任务分配器+计算节点组成。
常见的计算高可用架构:

  • 主备:备机平时不干活,主机故障时开始干活。简单但是故障时需要人工操作,也浪费一定的资源
  • 主从:备机平时也干活。缺点是任务分配器会复杂一些
  • 对称集群:目前最常见的负载均衡集群方案。各个计算节点没有角色区别,通过分配器均衡任务。
  • 非对称集群:计算节点区分角色,不同角色执行不同任务,比较少见。

业务高可用

业务高可用主要实现方式就是异地多活,异地多活又分同城异区跨城异地跨国异地,具体采用哪种方案需要根据业务量级以及业务重要程度来选择。另外,核心业务内部也分核心数据和非核心数据,所以在选择方案是也可以根据数据重要程度进行进一步划分。

在发生业务故障时,要使用日志记录并做好用户的补偿,降低影响范围和舆论影响程度。

另外针对接口级别的故障,平时发生的概率比较高,我们一般有以下几种应对方案

  • 降级:将某些业务或接口的功能降低,指提供部分功能或完全不提供功能。例如APP的页面数据,可以只提供核心模块的数据。
  • 熔断:一般是指依赖的下游故障。熔断需要有应对方案,例如熔断后返回缓存数据等等
  • 限流:限流是从用户访问压力的角度来应对。在上线服务时,要设置请求的阈值,超过这个阈值的请求可以被丢弃,避免机器负载过高影响所有用户

可拓展架构

可拓展架构的主要价值在于后续改动时,能尽量降低开发成本,降低改动范围。一般来说,设计方法有很多,但核心思想就是拆分,怎么拆各有各的说法,你可以面向流程拆分,也可以面向服务拆分,也可以面向功能拆分

分层架构

这是非常常见的架构模式,例如C/S架构、B/S架构、MVC架构等等。平常设计时也会习惯性进行分层,进行逻辑的划分,降低整体的复杂度。划分的原则也很简单,就是要保证各层之间的差异足够清晰,边界足够明显,可读性高

但有个缺点就是可能会发生冗余,有时候你只需要调用最底层的一个接口就好,但是为了维持这个分层架构,不得不层次传递,如果各层之间是网络连接,那网络耗时将会大大增加。

SOA架构

SOA是面向服务的架构,现在在传统大企业里面可能比较容易见到。提出的背景是企业内部的IT系统重复建设且效率低下。例如企业里面有很多独立的系统,财务系统、销售系统、HR系统等等,这些系统都需要进行员工的权限管理,也许都要重复开发该能力。

SOA主要有三个概念:

  • 服务:所有业务功能都是一项服务,服务需要对外提供能力,其他系统需要这些能力时,无需重复开发
  • ESB:因为各个服务之间是异构的,所以需要ESB来屏蔽各个系统对外提供各种不同的接口方式
  • 松耦合:目的是减少各个服务间的依赖和互相影响

SOA的瓶颈就在ESB上,因为所有服务都要通过它来进行通信。

微服务

微服务是大家耳熟能详的老伙计了,在国内的互联网公司,稍微大一点的业务都会采用微服务架构。微服务很容易和SOA混淆,主要区别在于服务粒度不同(SOA粒度比较粗)服务通信(SOA使用ESB通信,兼容不同协议,微服务的通信协议是一致的,简单很多)服务交付(微服务的交付成本先易后难,微服务越多,越需要更强的管理手段)应用场景(SOA适用于改动成本高的企业级系统,微服务适用于快速迭代的互联网系统)

采用微服务架构,开发基建一定要跟上,因为随着微服务越来越多,怎么做服务发现,怎么做服务路由,怎么自动部署,怎么排查问题就是实实在在要面对的问题。

那么,微服务要怎么拆分呢,基于什么原则进行拆分?

首先有一个“三个火枪手原则”:

三个火枪手原则:一个微服务三个人负责开发

具体的拆分方法有,可以根据自己的业务特点进行选择:

  • 基于业务逻辑拆分
  • 基于可拓展性拆分
  • 基于可靠性拆分
  • 基于性能拆分

关于微服务有很多其他经典的书籍可以学习,后续可以展开写写。

微内核

就是插件式架构,关键技术有:插件管理插件连接插件通信

应用场景有很多,例如促销规则生成系统,内核就是一个计算逻辑,但是很多商品种类可以封装成插件,新增规则时开发成很低。

互联网架构模板

一张图就可以说明了,内容深度不大。

《从零开始学架构》读书笔记(下)_第2张图片

架构的重构

前面我们介绍架构设计原则的时候,有一条原则就是“演化原则”。

演化优于一步到位

现在就是演化的时候了。在演化时,我们要注意:

  1. 识别当前的主要矛盾
  2. 换位思考推送项目,你得让对方有利可图,才会配合你演化
  3. 分阶段演化

读后感

读完收益良多,以前总是觉得架构挺神秘的,奈何没有一个系统的教程入门,网上资料汗牛充栋,根本无从下手,进行系统设计时脑子都是空白的,没有头绪。这本书介绍的挺全面的,很适合扫盲用,适合那些刚接触架构设计的开发人员。

后续可以在这里练练手:系统设计题

你可能感兴趣的:(系统设计,架构,数据库,大数据)