看了几本分布式系统架构的书和文章,对分布式系统的架构认知清晰了些。之前只知道分布式系统「要这样做」,但对「为什么这样做」和「这样做解决什么问题」一直懵懵懂懂,这次结合书中所讲、前人经验和一点点自己的理解,对分布式系统架构中所涉及的一些关键知识做一些归纳。
架构
软件架构指的是软件系统的顶层结构,其出现的目的是为了解决软件系统复杂度所带来的问题,而我们常说的高性能、高可用、可扩展恰恰是软件系统复杂度的三个主要来源。
高性能
- 单机高性能:利用多进程、多线程编程充分提高单台计算机的性能。
- 多机高性能:利用增加机器形成集群来解决单机性能瓶颈,复杂度在于任务分配和任务分解。
高可用
指的是系统无中断地执行其功能的能力,目前的解决思路万变不离其宗,即通过冗余解决可用性问题。高可用带来的复杂度主要在于
- 故障检测 failure detection
- 故障转移 failover
- 故障恢复 recover
常用的解决上述问题的决策策略有以下几种
- 独裁式 即存在独立的决策主体负责收集信息与决策
- 协商式 即常用的主备决策,个体间互相交流进行决策
- 民主式 个体间通过投票方式选举leader(多数取胜)进行决策
可扩展
采用灵活的设计正确预测变化,合理封装变化
CAP理论
CAP从理论上论证了分布式系统高可用的复杂度,具体阐释为在⼀一个分布式系统(指互相连接并共享数据的节点的集合)中,当涉及读写操作时,只能保证一致性 (Consistence)、可用性(Availability)、分区容错性(Partition Tolerance)三者中的两个,另外一个必须被牺牲。
- 一致性:对于指定客户端,读操作能返回最新的写操作结果。
- 可用性:非故障节点能在合理的时间内返回合理的结果(非错误和超时)。
- 分区容错性:当出现网络分区(包括丢包、连接中断、拥塞),系统能够继续履行职责。
CAP理论的一些细节:
- 网络分区是必然现象,因此分区容错性P是必须的选项,即要么CP,要么AP。
- CAP关注的是数据,而非系统。即同一个系统里,有的数据要保证CP,有的需要保证AP。
- CAP是忽略网络延迟的。
- 无网络分区时,需要保证CA。
- 牺牲不代表什么都不做,需要考虑补偿策略(如记录日志)。
CAP的扩展和补充BASE:
- 基本可用 Basically Available:保证核心业务可用
- 软状态 Soft State:允许系统存在中间态
- 最终⼀致性 Eventual Consistency:系统中的数据副本在经过一定时间后达到一致。
高可用的一般架构
计算高可用架构
主备
任务分配器不会将请求发送给备机,故障后需要人工干预将备机变为主机。
- 冷备:备机上的业务系统没有启动。
- 温备:备机上的业务系统启动完成,一般采用温备便于快速切换。
主从
进行任务拆分,将一部分任务发送给从机,故障后同样需要人工干预将备机变为主机。
集群
多台服务器节点进行冗余
- 对称集群:所有服务器节点角色相同,也叫负载均衡服务器,任务调度器(负载均衡器)需采取负载均衡算法分配请求。
- 非对称集群:服务器节点存在角色划分,不同角色执行不同的任务,如常见的Master-Slave模型。
常见的负载均衡器:
- DNS负载均衡:实现地理级别的负载均衡
- 硬件负载均衡:实现集群级别的负载均衡
- 软件负载均衡:实现机器级别的负载均衡
常见的负载均衡算法:
- 轮训
- 加权轮训
- 负载最低优先
- 性能最好优先
- Hash
存储高可用架构
双机架构
主要实现储存系统的高可用架构。
- 主备复制:备机不承担业务读写,只是一个备份,故障后需要人工干预将备机变为主机。
- 主从复制:master-slave 备机可读,存在主从延迟,故障需要人工干预。
- 双机切换:解决上述两种需要人工干预切换的缺点,实现自动切换,但需要状态传递和状态决策。
- 主主复制:multi-master 两台均可读写,不存在切换,但须解决同时写入时的数据冲突问题。
集群
- 数据集中集群:与主备、主从类似,也叫一主多从或一主多备,数据只写入主机,如ZooKeeper。
- 数据分散集群:每台服务器都会储存一部分数据,如Hadoop。
数据分区
按照一定的规则将数据进行分区,不同分区位于不同的地理位置上,避免地理级别的故障造成的损害。分区的数据同样要进行复制已进行故障恢复,复制规则有:
- 集中式:将数据复制到一个总的备份中心。
- 互备式:每个分区都会备份不同分区的数据。
- 独立式:每个分区都有自己的备份。
分布式系统的集大成之作 - 异地多活
如果系统希望实现地理级别的容灾,即如果某地的机房发生灾难性故障,业务也不应受影响或短时间内可恢复,就应该实现异地多活(multi-datacenter)。异地多活的复杂度有质的提高,是分布式系统的技术高峰。
标准
判断一个系统是否满足异地多活,有两个条件:
- 正常情况,不论访问哪个地点的业务系统都应得到正确的业务服务。
- 某个地点业务异常,用户访问其他地点的业务系统,能够得到正确的业务服务。
意义
- 实现地理级别的容灾(fault tolerant),这是异地多活最重要的意义
- 可以实现无限扩展(scale out),异地多活每个地点均存在独立的存储master,理论上可以无限扩展,避免single-master的性能瓶颈
- 可以提高单机房性能
实现难点
- 流量路由:请求应该被打到哪个机房
- 数据同步:多个机房之间如何进行数据同步,如何克服同步延迟,对数据强一致有较高要求的业务如何解决
- 灾难恢复:在failover切换流量时如何解决一个机房内新写入数据与复制数据不一致的问题
异地多活的实现成本较高,需要根据业务判断是否有必要实现,不通业务模式下的实现方式也不同,下篇文章将借助饿了么的异地多活架构对异地多活的实现思路进行简单说明。
参考资料
(End)