《从零开始学架构》读书笔记(下)
书接上文
思维导图
高可用架构模式
高可用的理论
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(故障模式与影响分析)又称为失效模式与后果分析等,是一套分析和思考的方法。具体分析方法如下:
- 给出初始的架构设计图
- 假设架构中的某个部件发生故障
- 分析此故障对系统功能造成的影响
- 根据分析结果,判断架构是否需要进行优化
此方法输出的是一份表格,包含功能点、故障模式、故障影响、严重程度、故障原因、故障概率、风险程度、已有措施、解决措施和后续规划。总结来说就是一份分析报告,列出系统的薄弱点,并提出改进措施,很可能改进之后又会引入新的薄弱点,所以需要不断更新。除此之外也可以当成一份运维手册来看,当发生故障时看看这份表上有没有相应的补救措施。
存储高可用
存储高可用本质都是将数据复制到多个节点,通过冗余来实现高可用。这类方案都要面对的一个问题是复制延迟和中断导致的数据不一致。任何一个存储高可用方案,都要想清楚以下几点:
- 数据是怎么复制的
- 各个数据节点的职责是什么,是单纯备份还是对外提供服务还是二者兼有
- 如何面对复制延迟
- 如果面对复制中断
主备复制
主机对外提供服务,通过复制通道将数据复制到备机,备机不对外提供服务。发生故障时需要将客户端的请求转到备机上。
缺点是如果主机永久挂了,对于复制延迟和中断造成的数据缺失没啥好的解决方案。由于备机不提供服务,平时会造成资源浪费。
优点就是比较简单,适用于内部管理系统。
主从复制
跟主备复制类似,但是备机是可以对外提供读服务的。
优点就是机器资源得到有效利用,主机挂了,读操作不受影响
缺点就是如果延迟比较高,写完立即读可能读到旧数据。也比较复杂,需要将不同的操作发给不同的机器
适应于论坛新闻类的业务,读多写少,影响范围可以控制
主备倒换和主从倒换
无论是上面哪种模式,发生故障时都要进行角色的转换。需要有状态的判断机制和倒换策略。例如:
- 状态是怎么传递的
- 传递的内容是什么?是心跳?还是包含了当前负载状态?
- 什么时候进行转换?没心跳转换?还是延迟高就转换?
- 转换手段是什么?人工or自动?
- 故障节点恢复后,数据冲突怎么解决?永远不恢复,缺失的数据怎么办?
根据状态传递渠道的不同,常见的主备倒换架构有三种形式:
- 互连式:主备互联。这里操作空间很大,怎么连?单向还是双向?万一通道本身出问题,那备机可就自己决定变成主机了
- 中介式:主备机分别向中介机发生信息,中介来决定角色。这种模式要简单很多,但是也要注意中介本身挂了的情况
- 模拟式:备机假装成客户端,向主机发请求,请求异常自己升级为主机。实现比互连简单,但是仅依靠响应信息决策还是有点草率
数据集群
当一台节点存储不下全部数据时,上面的两种方案就用不了了,就要上数据集群了,把数据分散到各个节点上。此方案的复杂点在于如何将数据分配到不同的服务器上,设计时需要考虑以下几点:
- 均衡性:各个节点的数据大小是均衡的
- 容错性:部分节点故障时,需要将原来分配给故障节点的数据分区分配给其他节点
- 可伸缩性:需要扩容时,能够自动迁移数据
既然数据分散到各个节点,那避免不了的问题就是分布式事务
。目前分布式事务算法非常多,但再多的算法也不能彻底解决问题,极端情况下还得看人工。目前常用的分布式事务算法有:
- 2PC: 二阶段提交。分为请求阶段和提交阶段。缺点比较明显,存在同步阻塞、状态不一致和单点故障问题
- 3PC: 三节点提交。分为提交判断、准备提交和提交执行三个阶段。解决了单点故障导致的系统阻塞问题,但还是没解决数据不一致问题。
- 消息表:把各个节点的执行情况记录到一张表里,协调者挂了之后新的协调者根据表信息再决定怎么操作,比较复杂。
数据分区
数据分区是指将数据按照一定的规则进行分区,不同分区分布到不同的地理位置上,每个分区存储一部分数据,通过这种方式来规避地理级别的故障。分区规则有很多,你可以选城市分区、国家分区、洲际分区等,一般看业务量决定。同时,即使是数据分区,也要考虑分区数据的备份,万一真发生地理级别的故障,还是要尽可能将数据恢复。一般有以下几种备份规则:
- 集中式:所有分区备份到一个总的数据中心。简单是简单,但是总的数据中心一旦挂掉,也挺头疼。
- 互备式:各个数据分区互相备份。稳定性大大上升,但是拓展性很差,后续增加一个新分区,是放到哪里备份呢?
- 独立式:各个数据分区有自己的数据中心。终极解决方式,但是成本非常高。
计算高可用
计算高可用的主要目的是当部分节点故障时,服务依然能正常对外提供服务。因此和存储高可用的思路是一致的,就是通过冗余来规避风险。这里复杂度主要体现在任务管理方便,即怎么分发任务
和任务执行失败后怎么处理
的问题。架构一般由任务分配器
+计算节点
组成。
常见的计算高可用架构:
- 主备:备机平时不干活,主机故障时开始干活。简单但是故障时需要人工操作,也浪费一定的资源
- 主从:备机平时也干活。缺点是任务分配器会复杂一些
- 对称集群:目前最常见的负载均衡集群方案。各个计算节点没有角色区别,通过分配器均衡任务。
- 非对称集群:计算节点区分角色,不同角色执行不同任务,比较少见。
业务高可用
业务高可用主要实现方式就是异地多活,异地多活又分同城异区
、跨城异地
、跨国异地
,具体采用哪种方案需要根据业务量级以及业务重要程度来选择。另外,核心业务内部也分核心数据和非核心数据,所以在选择方案是也可以根据数据重要程度进行进一步划分。
在发生业务故障时,要使用日志记录并做好用户的补偿,降低影响范围和舆论影响程度。
另外针对接口级别的故障,平时发生的概率比较高,我们一般有以下几种应对方案
- 降级:将某些业务或接口的功能降低,指提供部分功能或完全不提供功能。例如APP的页面数据,可以只提供核心模块的数据。
- 熔断:一般是指依赖的下游故障。熔断需要有应对方案,例如熔断后返回缓存数据等等
- 限流:限流是从用户访问压力的角度来应对。在上线服务时,要设置请求的阈值,超过这个阈值的请求可以被丢弃,避免机器负载过高影响所有用户
可拓展架构
可拓展架构的主要价值在于后续改动时,能尽量降低开发成本,降低改动范围。一般来说,设计方法有很多,但核心思想就是拆分
,怎么拆各有各的说法,你可以面向流程拆分
,也可以面向服务拆分
,也可以面向功能拆分
。
分层架构
这是非常常见的架构模式,例如C/S架构、B/S架构、MVC架构等等。平常设计时也会习惯性进行分层,进行逻辑的划分,降低整体的复杂度。划分的原则也很简单,就是要保证各层之间的差异足够清晰,边界足够明显,可读性高
。
但有个缺点就是可能会发生冗余,有时候你只需要调用最底层的一个接口就好,但是为了维持这个分层架构,不得不层次传递,如果各层之间是网络连接,那网络耗时将会大大增加。
SOA架构
SOA是面向服务的架构,现在在传统大企业里面可能比较容易见到。提出的背景是企业内部的IT系统重复建设且效率低下。例如企业里面有很多独立的系统,财务系统、销售系统、HR系统等等,这些系统都需要进行员工的权限管理,也许都要重复开发该能力。
SOA主要有三个概念:
- 服务:所有业务功能都是一项服务,服务需要对外提供能力,其他系统需要这些能力时,无需重复开发
- ESB:因为各个服务之间是异构的,所以需要ESB来屏蔽各个系统对外提供各种不同的接口方式
- 松耦合:目的是减少各个服务间的依赖和互相影响
SOA的瓶颈就在ESB上,因为所有服务都要通过它来进行通信。
微服务
微服务是大家耳熟能详的老伙计了,在国内的互联网公司,稍微大一点的业务都会采用微服务架构。微服务很容易和SOA混淆,主要区别在于服务粒度不同(SOA粒度比较粗)
、服务通信(SOA使用ESB通信,兼容不同协议,微服务的通信协议是一致的,简单很多)
、服务交付(微服务的交付成本先易后难,微服务越多,越需要更强的管理手段)
、应用场景(SOA适用于改动成本高的企业级系统,微服务适用于快速迭代的互联网系统)
。
采用微服务架构,开发基建一定要跟上,因为随着微服务越来越多,怎么做服务发现,怎么做服务路由,怎么自动部署,怎么排查问题就是实实在在要面对的问题。
那么,微服务要怎么拆分呢,基于什么原则进行拆分?
首先有一个“三个火枪手原则”:
三个火枪手原则:一个微服务三个人负责开发
具体的拆分方法有,可以根据自己的业务特点进行选择:
- 基于业务逻辑拆分
- 基于可拓展性拆分
- 基于可靠性拆分
- 基于性能拆分
关于微服务有很多其他经典的书籍可以学习,后续可以展开写写。
微内核
就是插件式架构,关键技术有:插件管理
、插件连接
和插件通信
。
应用场景有很多,例如促销规则生成系统,内核就是一个计算逻辑,但是很多商品种类可以封装成插件,新增规则时开发成很低。
互联网架构模板
一张图就可以说明了,内容深度不大。
架构的重构
前面我们介绍架构设计原则的时候,有一条原则就是“演化原则”。
演化优于一步到位
现在就是演化的时候了。在演化时,我们要注意:
- 识别当前的主要矛盾
- 换位思考推送项目,你得让对方有利可图,才会配合你演化
- 分阶段演化
读后感
读完收益良多,以前总是觉得架构挺神秘的,奈何没有一个系统的教程入门,网上资料汗牛充栋,根本无从下手,进行系统设计时脑子都是空白的,没有头绪。这本书介绍的挺全面的,很适合扫盲用,适合那些刚接触架构设计的开发人员。文章来源:https://www.toymoban.com/news/detail-406628.html
后续可以在这里练练手:系统设计题文章来源地址https://www.toymoban.com/news/detail-406628.html
到了这里,关于《从零开始学架构》读书笔记(下)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!