这 2 篇文章是我在学习架构的过程中,总结的笔记:
- 第一篇 架构学习笔记1
- 0,什么是架构师
- 1,软件架构出现的历史背景
- 2,架构设计的目的
- 3,架构设计三原则
- 4,架构复杂度的六个来源
- 5,架构设计流程
- 6,常用的高性能架构模式
- 第二篇 架构学习笔记2
- 7,常用的高可用架构模式
- 8,常用的可扩展架构模式
- 9,架构师如何判断技术演进的方向
- 10,互联网架构模板
CAP 定理是埃里克·布鲁尔在 2000 年的 ACM PODC 上提出的一个猜想。2002 年,赛斯·吉尔伯特和南希·林奇发表了布鲁尔猜想的证明,使之成为分布式计算领域公认的一个定理。
布鲁尔在提出 CAP 猜想的时候,并没有详细定义 Consistency、Availability、Partition Tolerance
三个单词的明确定义。
这里参考 Robert Greiner 的文章,其有两篇文章,第二篇比第一篇更精准:
https://robertgreiner.com/2014/06/cap-theorem-explained/
https://robertgreiner.com/2014/08/cap-theorem-revisited/
下面都是采用第二篇文章的解析
CAP 定理:在一个分布式系统(指互相连接并共享数据的节点的集合)中,当涉及读写操作时,只能保证一致性(Consistence
)、可用性(Availability
)、分区容错性(Partition Tolerance
)三者中的两个,另外一个必须被牺牲。
其中的关键点有:
CAP 的含义:
Consistence
):对某个指定的客户端来说,读操作保证能够返回最新的写操作结果Availability
):非故障的节点在合理的时间内返回合理的响应Partition Tolerance
):当出现网络分区后(集群中的节点之间不能互相通信),系统能够继续提供服务在分布式网络中,网络本身无法做到完全可靠,所以分区是一个必然的现象,也就是 P 必然存在,因此,有两种选择:
CP 架构:当发生网络分区时,保证一致性,可用性无法保证。
AP 架构:当发生网络分区时,保证可用性,一致性则无法保证。
FMEA,中文翻译为“故障模式与影响分析”,是一种广泛应用的可用性分析方法,通过对系统范围内潜在的故障模式加以分析,并按照严重程度进行分类,以确定失效对于系统的最终影响。
在架构设计领域,FMEA 的具体分析方法是:
FMEA 分析就是一个 FMEA 分析表,常见的 FMEA 分析表包含下面部分(11项):
例如,对如下架构进行架构分析:
下图是 FMEA 分析的结果:
改进后的架构图:
存储高可用方案的本质都是通过将数据复制到多个存储设备,通过数据冗余的方式来实现高可用,其复杂性主要体现在如何应对复制延迟和中断导致的数据不一致问题。
因此,对任何一个高可用存储方案,我们需要思考以下问题:
常见的高可用存储架构有:
主备复制是最常见也是最简单的一种存储高可用方案,几乎所有的存储系统都提供了主备复制的功能,例如 MySQL、Redis、MongoDB 等。
主备方案架构图:
主备架构中的“备机”主要还是起到一个备份作用,并不承担实际的业务读写操作,如果要把备机改为主机,需要人工操作。
主备架构的优缺点:
内部的后台管理系统使用主备复制架构的情况会比较多,例如学生管理系统、员工管理系统、假期管理系统等
主机负责读写操作,从机只负责读操作,不负责写操作。
主从方案架构图:
主从架构的优缺点:
一般情况下,写少读多的业务使用主从复制的存储架构比较多。例如,论坛、BBS、新闻网站这类业务。
主备和主从方案存在两个共性的问题:
双机切换就是为了解决这两个问题而产生的,包括主备切换和主从切换两种方案。这两个方案就是在原有方案的基础上增加“切换”功能,即系统自动决定主机角色,并完成角色切换。
要实现一个完善的切换方案,必须考虑这几个关键的设计点:
切换方案比复制方案不只是多了一个切换功能那么简单,而是复杂度上升了一个量级。
常见的主备切换架构有三种形式:互连式、中介式和模拟式。
互连式
互连式就是指主备机直接建立状态传递的渠道,其架构图如下:
中介式
中介式指的是在主备两者之外引入第三方中介,主备机之间不直接连接,而都去连接中介,并且通过中介来传递状态信息,其架构图如下:
MongoDB 的 Replica Set 采取的就是这种方式,其基本架构如下:
中介式架构的关键在于如何实现中介本身的高可用,开源方案已经有比较成熟的中介式解决方案,例如 ZooKeeper 和 Keepalived。ZooKeeper 本身已经实现了高可用集群架构。
模拟式
主主复制指的是两台机器都是主机,互相将数据复制给对方,客户端可以任意挑选其中一台机器进行读写操作。
主主复制架构具有如下特点:
主主复制架构对数据的设计有严格的要求,一般适合于那些临时性、可丢失、可覆盖的数据场景。例如,用户登录产生的 session 数据(可以重新登录生成)、用户行为的日志数据(可以丢失)、论坛的草稿数据(可以丢失)等。
单台机器的存储和处理能力是有极限的,集群是多台机器组合在一起形成一个统一的系统,可存储更多的数据。
根据集群中机器承担的不同角色来划分,集群可以分为两类:
数据集中集群
数据集中集群为 1 主多备或者 1 主多从。数据都只能往主机中写,而读操作可以参考主备、主从架构进行灵活多变。
下图是读写全部到主机的一种架构:
由于集群里面的服务器数量更多,导致复杂度更高一些:
数据分散集群
数据分散集群指多个服务器组成一个集群,每台服务器都会负责存储一部分数据;同时,为了提升硬件利用率,每台服务器又会备份一部分数据。
数据分散集群的复杂点在于如何将数据分配到不同的服务器上,需要考虑这些设计点:
数据分散集群中的每台服务器都可以处理读写请求,因此不存在数据集中集群中负责写的主机那样的角色。
但在数据分散集群中,必须有一个角色来负责执行数据分配算法,这个角色可以是独立的一台服务器,也可以是集群自己选举出的一台服务器。
Hadoop 的实现就是独立的服务器(NameNode)负责数据分区的分配。Hadoop 的数据分区管理架构如下:
与 Hadoop
不同的是,Elasticsearch
集群通过选举一台服务器来做数据分区的分配,叫作 master node
,其数据分区管理架构是:
数据集中集群与数据分散集群的区别:
数据分区指将数据按照一定的规则进行分区,不同分区分布在不同的地理位置上,每个分区存储一部分数据,通过这种方式来规避地理级别的故障所造成的巨大影响。
设计一个良好的数据分区架构,需要考虑以下方面:
常见的分区复制规则有三种:
集中式:
互备式:
独立式:
计算高可用的主要设计目标是当出现部分硬件损坏时,计算任务能够继续正常运行,其本质是通过冗余来规避部分故障的风险。
计算高可用架构的设计复杂度主要体现在任务管理方面,即当任务在某台服务器上执行失败后,如何将任务重新分配到新的服务器进行执行。
计算高可用架构设计的关键点有下面两点:
常见的计算高可用架构:主备、主从和集群。
主备架构
详细设计:
根据备机状态的不同,主备架构又可以细分为冷备架构和温备架构:
主从架构
从机也是要执行任务的。任务分配器需要将任务进行分类,确定哪些任务可以发送给主机执行,哪些任务可以发送给备机执行,其基本的架构示意图如下:
详细设计:
集群架构
高可用集群方案能够自动完成切换操作,根据节点角色的不同,可以分为两类:
对称集群
详细设计:
负载均衡集群的设计关键点在于两点:
非对称集群
非对称集群中不同服务器的角色是不同的,承担不同的职责。
详细设计:
非对称集群的复杂度主要体现在两个方面:
无论是高可用计算架构,还是高可用存储架构,其本质的设计目的都是为了解决部分服务器故障的场景下,如何保证系统能够继续提供服务。
异地多活的关键在于异地与多活:
实现异地多活架构的代价很高,具体表现为:
异地多活的方案:
跨城异地多活架构设计的 4 大技巧:
软件的可扩展性让我们可以通过修改和扩展,不断地让软件系统具备更多的功能和特性,满足新的需求或者顺应技术发展的趋势。
可扩展性架构设计的基本思想是,将原本大一统的系统拆分成多个规模小的部分,扩展时只修改其中一部分即可,无须整个系统到处都改,通过这种方式来减少改动范围,降低改动风险。
合理的拆分,能够强制保证即使程序员出错,出错的范围也不会太广,影响也不会太大。
不同的拆分方式,决定了系统的扩展方式。常见的拆分思路有如下三种:
不同的拆分方式,将得到不同的系统架构,典型的可扩展系统架构有:
当然,这几个系统架构并不是非此即彼的,而是可以在系统架构设计中进行组合使用的。
分层架构也叫 N 层架构,N 至少是 2 层:
分层架构设计最核心的一点是要保证各层之间的差异足够清晰,边界足够明显。如果两个层的差异不明显,很容易导致分层混乱。
分层架构使得每个层中的组件只会处理本层的逻辑,并且强制将分层依赖限定为两两依赖(不建议绕过分层,时间长了,容易混乱),降低了整体系统复杂度。
SOA 的全称是 Service Oriented Architecture
,中文翻译为面向服务的架构。
SOA 更多是在传统企业(例如,制造业、金融业等)落地和推广,在互联网行业并没有大规模地实践和推广。SOA 出现的背景是企业内部的 IT 系统重复建设且效率低下。
典型的 SOA 架构如下:
2014 年,James Lewis
和 Martin Fowler
合写了关于微服务的一篇学术性的文章,详细阐述了微服务。
关于 SOA 和微服务的关系和区别,有下面几个典型的观点:
SOA 和微服务对比如下:
微服务有哪些坑:
微内核架构,也被称为插件化架构,是一种面向功能进行拆分的可扩展性架构,通常用于实现基于产品的应用。
微内核的架构本质就是将变化部分封装在插件里面,从而达到快速灵活扩展的目的,而又不影响整体系统的稳定。
微内核架构包含两类组件:
架构示意图:
核心系统 Core System
功能比较稳定,不会因为业务功能扩展而不断修改,插件模块可以根据业务功能的需要不断地扩展。
OSGi 架构
OSGi 是一个非盈利的国际组织,旨在建立一个开放的服务规范,为通过网络向设备提供服务建立开放的标准,这个标准就是 OSGi 规范。
OSGi 是一个插件化的标准,它的架构图如下:
说明:
规则引擎
规则引擎也属于微内核架构的一种具体实现,基本架构如下:
目前最常用的规则引擎是开源的 JBoss Drools,采用 Java 语言编写,基于 Rete 算法。
几个典型的派别(都存在一定的问题):
互联网公司发展的不同阶段:
互联网的标准技术架构如下图所示:
有以下几种:
DBProxy
、淘宝的 TDDL
。MySQL Router
、360 开源的数据库中间件 Atlas
。主要有:
服务层的主要目标是为了降低系统间相互关联的复杂度。
配置中心:集中管理各个系统的配置。
服务中心:是为了解决跨系统依赖的“配置”和“调度”问题,一般有两种实现方式:
消息队列:是为了实现跨系统异步通知的中间件系统。
网络层技术的关键架构设计点:
负载均衡:为了应对大容量的访问,将请求均衡地分配到多个系统上。
dig baidu.com
CDN:CDN 是为了解决用户网络访问时的“最后一公里”效应,本质上是一种“以空间换时间”的加速策略,即将内容缓存在离用户最近的地方,用户访问的是缓存的内容,而不是站点实时的内容。
多机房:多机房是为了解决单机房的单点问题。
多中心:多中心必须以多机房为前提,多中心相比多机房是本质上的飞越,难度也高出一个等级。
用户管理
用户管理的第一个目标:单点登录(SSO),又叫统一登录。单点登录的技术实现手段较多,例如 cookie、JSONP、token 等,目前最成熟的开源单点登录方案当属 CAS,其架构如下:
用户管理的第二个目标:授权登录(第三方应用接入)。现在最流行的授权登录就是 OAuth 2.0 协议,基本上已经成为了标准。
用户管理的基本架构如下:
消息推送
消息推送根据不同的途径,分为短信、邮件、站内信、App 推送。
App 目前主要分为 iOS 和 Android 推送,iOS 系统比较规范和封闭,基本上只能使用苹果的 APNS;但 Android 就不一样了,在国外,用 GCM 和 APNS 差别不大;但是在国内,情况就复杂多了:首先是 GCM 不能用;其次是各个手机厂商都有自己的定制的 Android,消息推送实现也不完全一样。
存储云、图片云
存储云和图片云通常的实现都是“CDN + 小文件存储”,现在有了“云”之后,除非 BAT 级别,一般不建议自己再重复造轮子了,直接买云服务可能是最快也是最经济的方式。
普通的文件基本上提供存储和访问就够了,而图片涉及的业务会更多,包括裁剪、压缩、美化、审核、水印等处理,因此通常情况下图片云会拆分为独立的系统对用户提供服务。
面对业务层的技术挑战,最有效的方法就是,化整为零、分而治之,将整体复杂性分散到多个子业务或者子系统里面去。具体的方式就是可扩展架构模式部分的分层架构、微服务、微内核等。
例如下面的系统拆分演变过程: