前言

分布式系统是一门讲究实践的软件工程,只有PK过设计方案,从微观处手把手的敲过一行行的代码,才能知道细节在哪里,难点在哪里,痛点、挑战点在哪里。同时,分布式系统也是一门讲究理论的软件工程,从宏观处着眼深刻理解系统设计的理论,将理论与实践相结合,想好、做好、说好才是真的好。因此,宏观处着眼,微观处着手,才能真正掌握分布式系统。自此,本系列文章开始讲诉分布式系统设计里的基础理论,本文为CAP与PACELC理论。

CAP理论与PACELC理论

CAP理论

CAP理论是分布式系统最为基本的指导理论之一,是分布式系统设计时最为基本的取舍依据,CAP理论认为一致性、可用性、分区容忍性不能同时满足,即:

  • 一致性(Consistency): 所有的节点在同一时刻看到同样的数据;

  • 可用性(Availability): 节点失效不会影响系统的读写;

  • 分区容忍性(Partition Tolerance): 系统能支持网络分区,即使分区之间的消息丢失系统也正常工作。

但是,CAP理论也有其自身的局限性。在工程实践中CAP理论的应用可以一分为二:系统整体以及系统内部。比如,系统整体可以选择CA或者CP,但是系统内部微观处有些特性却可以同时满足CAP三要素,因为分区是件极少发生的事,为了追求卓越的设计理念可以尽量同时满足CAP三要素。根据业务场景的不同,不同的分布式系统会根据自身业务的需求在CAP三者中进行取舍, CAP理论的意义是一种在分布式系统设计时取舍的参考因素,而非绝对的三者必舍其一。

此外,在CAP理论中是没有提到系统的时延(Latency)的,而访问时延(Latency)却是很重要的可用性(Availability)因素,因此又延申出了PACELC理论。

PACELC理论

PACELC理论是CAP理论的扩展,PACELC理论在wiki上的定义是:

It states that in case of network partitioning (P) in a distributed computer system, one has to choose between availability (A) and consistency (C) (as per the CAP theorem), but else (E), even when the system is running normally in the absence of partitions, one has to choose between latency (L) and consistency (C).

意思就是:

如果有分区partition (P),系统就必须在availability 和consistency (A and C)之间取得平衡; 否则else (E) 当系统运行在无分区情况下,系统需要在 latency (L) 和 consistency (C)之间取得平衡

如下图,在PACELC里添加了Latency要素:

cap-pacelc

当前分布式系统设计指导理论应当采用PACELC理论替代CAP理论,理由如下:

  • PACELC更能满足实际操作中分布式系统的工作场景是更好的工程实现策略;

  • 当partition (P)存在的场景下,需要在availability 和consistency (A and C)之间取舍,但是实际上分布式系统中绝大多数时间里partition (P)是不存在的,那么就需要在latency (L) 和 consistency (C)之间作取舍;

  • Availability在不存在partition (P)的场景下跟 latency关联,在partition (P)时跟”可靠性“指标相关联;

  • PACELC 可以在 latency 与 consistency之间获得平衡;

  • CAP 理论忽略了 一致性和时延之间的取舍;

PACELC理论是建立在CAP理论之上的,二者都描述了一致性(Consistency)、可用性(Availability)和分区容忍性(Partition Tolerance)之间的约束与取舍。而PACELC理论则更进一步描述了即使在没有Partition的场景下,也存在Latency和Consistency之间的取舍,从而为分布式系统的Consistency模型提供了一个更为完整的理论依据。

理论应用

要保证系统数据的高可用(high availability)那么有个技术方案是采用数据冗余备份的方式,那么就涉及到复制数据,而进行分布式系统的数据复制,就会出现在Consistency和Latency之间做个取舍的要求。举个例子,如下图所示:

consistency-latency

在强一致性复制场景下,需要三副本都下盘才能返回OK确认信息给client端,假设Master节点向 Slave 节点复制数据,时延的限制是 20ms,有时候,slave 2 硬盘或网络出现故障,Master 往 Slave 复制数据的时延超过 了20ms,这个时候如果还一直等待 slave 2 返回结果再通知给client就会出现性能和时延抖动,而且这种抖动是经常会发生的长尾效应。

依据PACELC理论,我们可以在 consistency和Latency之间做个取舍,比如 slave 2 节点的时延超过 20ms了,就不等待slave 2 返回,master 和 slave 1 返回结果给client即可,如果 slave 2 出现 超时的 次数超过 5次那么就认为 这个节点可能出现故障,打个故障标签,进行后续的处理。采用这种方式可以消除写时的长尾抖动,获得更优雅的写时性能曲线。

小结

本文遵循理论与实践相结合的指导思想讲述了CAP理论与PACELC理论。日拱一卒,功不唐捐,分享是最好的学习,与其跟随不如创新,希望这个知识点对大家有用。另作者能力与认知都有限,”我讲的,可能都是错的“,欢迎大家拍砖留念。

作者简介

常平,中国科学技术大学硕士研究生,深度学习首席软件主管工程师,前EMC 大数据资深首席工程师,主要从事Linux内核以及分布式产品的架构设计、开发以及交付工作。

参考文献

[1] https://en.wikipedia.org/wiki/PACELC_theorem

[2] CAP理论与分布式系统设计,S先生

版权申明

本文的版权协议为 CC-BY-NC-ND license:https://creativecommons.org/licenses/by-nc-nd/3.0/deed.zh

在遵循署名、非商业使用(以获利为准)以及禁止演绎的前提下可以自由阅读、分享、转发、复制、分发等。

前言

编程是一种创造性解决问题的能力, 其本质上是一种思维体操,可以大大的提升人的逻辑能力、推理能力以及解决问题的能力, 那么什么是分布式系统的编程思维呢?

编程思维模型

具体来看分布式系统的编程思维包含11大内容:

抽象、分层、解耦、拆分、聚合、治理、取舍、模型、演化、质量、边界。

这个主题的解读,留待以后完善了再补充

//TODO

小结

本文解读了分布式系统的编程思维模型。日拱一卒,功不唐捐,分享是最好的学习,与其跟随不如创新,希望这个知识点对大家有用。另作者能力与认知都有限,”我讲的,可能都是错的“,欢迎大家拍砖留念。

作者简介

常平,中科大硕,DELL EMC 资深首席工程师,曾就职于Marvell、AMD,主要从事Linux内核以及分布式产品的交付、架构设计以及开发工作。

参考资料

[1]

版权申明

本文的版权协议为 CC-BY-NC-ND license:https://creativecommons.org/licenses/by-nc-nd/3.0/deed.zh

在遵循署名、非商业使用(以获利为准)以及禁止演绎的前提下可以自由阅读、分享、转发、复制、分发等。

前言

懂得很多道理,仍旧过不好这一生。懂得很多分布式系统的概念以及设计方法,依旧做不好分布式系统。分布式系统设计是一门实践软件工程,只有你PK过设计方案,手把手的敲过一行行的代码,才能知道细节在哪里,难点在哪里,痛点、挑战点在哪里,不是看书或者看文章就可以完全掌握的。因此,宏观处着眼,微观处着手,才能完全掌握分布式系统设计的道理。本文抽象出分布式系统的思维模型,当你看到这个模型里的字眼与图画,就可以从脑海里分解出一个个设计方案、一行行代码的时候,那才是真的掌握了分布式系统的精髓。

分布式系统八卦思维模型

这里我提出一个分布式系统八卦思维模型,如下图,其要义如下:

分布式系统思维模型

方法论

核心:在前面的文章里讲到可以用一句话来描述分布式系统:

分布式系统是指其组件位于不同的网络计算机上的系统,这些组件通过相互传递消息来进行通信和协调其动作,且彼此相互交互以完成一个共同的任务目标。

并且提到了“系统 = 要素 + 连接 + 目标” , 这个思维模型的核心即分布式系统的第一性原理, 公式:“分布式系统 = 计算机 + 网络 + 协同”,要素是计算机(新的虚机、容器也算),连接是网络,目标是协同以完成共同任务。

提供:即服务接入的提供,指的是对外提供restful 接口服务:权限、多组合、监控、审计、计费等,对外提供SQL服务接入接口服务、对外提供自然语言接入接口服务等
注册:即服务注册,将集群的工作负载注册到集群注册中心
配置:即配置管理,将集群的配置管理在配置中心;
调用,即服务调用,各种RPC调用,系统内的消息传递
路由:即服务路由,目的是集群的负载均衡与扩伸缩性
观测:指的是集群内部指标的可观测性,即监控、告警、追踪、日志
治理:指的是集群内部的服务治理:熔断、降级、限流、隔离、容错
编排:即服务编排,基于k8s+ docker,完成安装、升级、扩容、运维、调度等;
质量:指的是安装部署运维质量、客户质量、用户质量与开发质量
边界:指的是系统内的约束条件,涵盖 硬件资源、客户约束、用户约束以及团队约束

这10个功能与核心之间是互相联系、互联影响的,因此类似于一个八卦图。

底层思维

1
抽象、分层、解耦、拆分、聚合、治理、取舍、质量、边界、模型、演化

抽象、分层、解耦、拆分、聚合、治理、取舍、质量、边界、模型、演化是分布式系统设计的底层思维,也是软件工程的底层思维,这个主题很难掌握,目前,这里不展开讲。

基石假设

分布式系统有两个隐含的基石假设,即 “资源协同与质量可预测”,资源即计算机、虚拟机、容器以及网络,基于此,分布式系统的第一性原理 即: “分布式系统 = 计算机 + 网络 + 协同 ,以质量为度量”。

小结

本文提出一个分布式系统八卦思维模型。分布式系统不是我首创,用这个类八卦图形来表示思维模型也不是我首创,但是用这个类八卦图形表示分布式系统思维模型应该是我首创,目前不管是书籍还是网络都找不到这样的分布式系统思维模型。日拱一卒,功不唐捐,分享是最好的学习,与其跟随不如创新,希望这个知识点对大家有用。另作者能力与认知都有限,”我讲的,可能都是错的“,欢迎大家拍砖留念。

作者简介

常平,中科大硕,DELL EMC 资深首席工程师,曾就职于Marvell、AMD,主要从事Linux内核以及分布式产品的交付、架构设计以及开发工作。

版权申明

本文的版权协议为 CC-BY-NC-ND license:https://creativecommons.org/licenses/by-nc-nd/3.0/deed.zh

在遵循署名、非商业使用(以获利为准)以及禁止演绎的前提下可以自由阅读、分享、转发、复制、分发等。

前言

本文的动机在于应用物理学思维模型破解分布式系统背后不变的本质,并以此解读分布式系统里的各种算法设计、功能设计以及非功能设计。在“分布式系统” 这个词语里,关键词可以分为“分布式”及“系统”,而“系统 = 要素 + 连接 + 目标”,在这个公式里,要素的变化不会影响系统的本质,而“连接或目标”的变化就会改变系统的本质,其中“分布式”是系统的连接方式,挖掘分布式系统背后的本质即是挖掘“分布式系统”的要素、连接以及目标的本质。

物理学的价值观在于追求所有物理现象背后的共同的底层规律,并以此解读各种物理现象,并且其具有“可解释、可重复、可预测”的可度量性,这种共同的底层规律,被称之为元认知,即第一性原理:“任何变化的背后都有不变的本质”。将这种思维模型应用于挖掘分布式系统的本质,需要解决两个问题,即:“ 什么是分布式系统的第一性原理?以及如何度量分布式系统?”

分布式系统的价值与目的

分布式系统的出现是为了解决一个主要矛盾,即:“日益增长的数据计算、传输与存储的需求与当前单点计算机能力无法满足这个需求之间的矛盾”。分布式系统可以通过伸展集群规模解决这个矛盾,因此这就是分布式系统的价值,而可伸缩性(Scalability,避免与可扩展性extensibility混淆)也是分布式系统的根本目的。

分布式系统必知的基础理论与算法

分布式系统必须理解、必须会的基础理论算法有:CAP/PACELC、BASE、2PC、3PC、TCC、ACID、PAXOS、RAFT这9个:

  • CAP: CAP理论认为以下三者不能同时满足:
    • 一致性(Consistency): 所有的节点在同一时刻数据是完全一样的;
    • 可用性(Availability): 节点失效不会影响系统的IO;
    • 分区容忍性(Partition Tolerance): 系统能支持网络分区(网络连接故障),即使分区之间的消息丢失系统也正常工作。
  • PACELC: PACELC理论是CAP理论的扩展,如果有分区partition (P),系统就必须在availability 和consistency (A and C)之间取得平衡; 否则else (E) 当系统运行在无分区情况下,系统需要在 latency (L) 和 consistency (C)之间取得平衡”;
  • BASE: BASE是基本可用(Basically Available)、软状态(Soft state)和最终一致性(Eventually consistent)三个短语的缩写;
  • 2PC:two-phase commit protocol,两阶段提交;
  • 3PC: three-phase commit protocol ,三阶段提交,其在两阶段提交的基础上增加了CanCommit阶段,并引入了超时机制;
  • TCC: Try-Confirm-Cancel,又称补偿事务,其核心思想是:”针对每个操作都要注册一个与其对应的确认和补偿(撤销操作)”;
  • ACID: 原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durablity);
  • PAXOS/RAFT :PAXOS与RAFT算法都是最有效的解决分布式一致性问题的算法。

这几条基础理论与算法需要自己深入学习理解,其是分布式系统的必备知识点。

分布式系统的功能与非功能

功能

功能可按职责划分为服务功能与算法功能:

  • 分布式系统里的最主要的服务功能有:服务提供,服务注册,服务配置,服务调用、服务路由、服务治理设计,服务观测、服务安全这8项;
  • 分布式系统里的最主要的算法功能有:幂等性设计、事务算法设计、端到端的校验算法设计、路由算法设计、分区分配算法设计、集群视图变更算法设计、心跳算法设计、注册算法设计、复制一致性算法设计以及容量规划算法设计。

非功能

非功能可划分为质量与约束:

  • 质量是分布式系统在约束条件下的度量方式,其涵盖:合适的性能(Performant)、可用性(Availability)、可靠性(Reliability)、可伸缩性(Scalability)、韧性(resilience)、可观测性(Observability)、安全性(security)、易用性(usability)、可运维性(operability)、可测试性(testability)、可维护性(maintainability)、可扩展性(extensibility)、可读性(readability)等。

  • 约束是分布式系统的资源限制:网络物理容量与计算机节点的物理容量,以及客户、用户、团队的边界约束。

分布式系统交付的目的是功能的价值,但是产品的功夫却体现在非功能,分布式系统的质量是分布式系统的度量方式,分布式系统要可度量就需要具有“可解释、可复制、可预测”的质量保证。

分布式系统的第一性原理

依据李善友老师的定义: “第一性原理思维 = 逻辑奇点 + 公理化方法 ”,逻辑奇点即基石假设,公理化方法我认为是”定公理、推定理、再公式化应用”。因此欲找出分布式系统的第一性原理,就需要先挖掘出分布式系统的公理化定义及其逻辑奇点。

首先把分布式系统概念化,Google 出来的对分布式系统的定义有:

1
2
3
A distributed system is a system whose components are located on different networked
computers, which communicate and coordinate their actions by passing messages to one
another. The components interact with one another in order to achieve a common goal.

即:

分布式系统是指其组件位于不同的网络计算机上的系统,这些组件通过相互传递消息来进行通信和协调其动作,且彼此相互交互以完成一个共同的任务目标。

拆解这句话,从中可以看到分布式系统里的要素即为组件,连接即网络,目标是共同的任务,并且还可以看出4个要点:

  • 分布式系统的组件是位于不同的网络计算机上;

  • 分布式系统的组件通过传递消息进行通信其动作;

  • 分布式系统的组件通过传递消息进行协调其动作;

  • 分布式系统的组件是通过相互交互以完成一个共同的任务目标;

其中最最重要的可以看作是分布式系统的基石假设的要点是:

1,分布式系统的组件是位于不同的网络计算机上;

2,这些组件通过相互传递消息来进行通信和协调其动作,且彼此相互交互以完成一个共同的任务目标。

这两点即为分布式系统的逻辑奇点,破除了这两点那就不是分布式系统,比如去掉网络计算机的定义,那就是单机系统,去掉协调以完成共同的任务目标,那就只是一个计算机网络。这两点基石假设构成分布式系统的逻辑奇点。

到此,可以得出分布式系统的公理化定义:

分布式系统是指其组件位于不同的网络计算机上的系统,这些组件通过相互传递消息来进行通信和协调其动作,且彼此相互交互以完成一个共同的任务目标。

以及分布式系统的逻辑起点:

  • 分布式系统是指其组件位于不同的网络计算机上的系统:即计算机网络;

  • 这些组件通过相互传递消息来进行通信和协调其动作,且彼此相互交互以完成一个共同的任务目标:即协同:“谐调一致,和合共同,协调两个或者两个以上的不同资源或者个体,一致地完成某一共同目标”;

再进一步抽象,可以推断出“分布式系统就是通过计算机网络进行协同工作的系统”, 至此,可以推出分布式的公理化定义公式:

1
分布式系统 = 计算机 + 网络 + 协同,其以质量为度量。

这个公式就是分布式的第一性原理公式,是分布式的本质理论定义,其中“计算机”是分布式系统的要素,“网络”是分布式系统的连接,“协同”是分布式系统的目标,从这公式里可以看出分布式系统的3个原生的难题:

  • 分布式系统是基于网络的系统,那么网络自身所具有的所有的优点与缺点它都有,那么如何提高服务的可靠性?如何保证服务的可用性?如何保证网络可运维?

  • 分布式系统是基于消息传递的系统,消息传递是不可靠的,那么如何保证消息的正确性?如何保证消息传递的可靠性?如何传递消息到目的地?如何保证消息传递的负载均衡?

  • 分布式系统是协同工作的系统,那么如何协调大量的计算机节点的完成一个共同的目标,如何解决协调的复杂性以及提高协调的可靠性、可用性?那么如何一起交互完成一个共同的目标任务?如何拆分目标?如何聚合目标,如何度量完成任务的质量与边界?

因此还需要依据分布式系统的公理化定义推导出定理化定义。

分布式系统的定理化推导

“公理是不证自明的,而定理是以若干的公理或其他定理为基础而推导的”。由公理推定理,从分布式的公理化公式“分布式系统 = 计算机 + 网络 + 协同”,可知分布式系统是组件位于“不同的计算机网络”上一起“协同”工作的系统,这句话得出分布式系统三要素:“计算机、网络,协同”。其中计算机是系统要素,改变计算机为虚机或者容器,不会改变分布式系统的本质。网络是系统的连接,改变连接就会改变系统的本质,当连接一台计算机时,就是单机,当连接两台计算机时就是镜像,当连接 多于两台计算机时就是分布式。协同是系统的目标,当改变协同的目标也就改变了系统的功能,比如共同计算与共同存储、共同调度,其功能目标是不一样的。

计算机

分布式系统是基于不同的计算机上的系统,计算机也是分布式系统的要素之一,因此分布式系统也继承了计算机的原生缺点,

  • 计算机节点是会出故障的,主板、CPU、网卡、硬盘、内存、电源等都会出故障,比如老化、失效等;
  • 计算机节点内的操作系统是会突然奔溃不能提供服务的;
  • 计算机节点是会突然掉电的;
  • 计算机节点里的内存下电是不保数据的;
  • 计算机节点的资源是有限的:CPU是有算力上限的、内存是有大小限制的、网卡有吞吐量限制、硬盘有空间大小限制以及速率限制;

这几个计算机的原生缺点意味着分布式系统需要能够知道计算机节点是失效的,以及在计算机节点失效的同时保证服务质量设计,那么就应当进行以下几点保证:

  • 可观测性(observability)设计:监控、告警、日志、追踪;

  • 可靠性(Reliability)设计:冗余设计、分区分配设计、复制算法设计、幂等性设计、一致性算法设计;

  • 容量(capacity)规划设计:计算机节点资源资源有限,就需要分布式系统进行进行容量规划;

  • 服务治理(Service governance)设计:CPU算力有限、内存有限、网卡吞吐量有限、磁盘IO有限,因此需要进行服务治理之隔板设计以及限流、限并发设计。

网络

分布式系统是基于不同的网络上的系统,网络是分布式系统的连接方式之一,连接一台计算机的系统就是单机系统,连接两台计算机的系统就是镜像系统,连接三台及以上数目的计算机的系统就是分布式系统,因此分布式系统也继承了网络的原生缺点,即:

  • 网络是不可靠的;
  • 网络是会出故障的;
  • 网络是有时延的;
  • 网络是会抖动的;
  • 网络是不安全的;
  • 网络是会丢包的;
  • 网络是有带宽限制的;
  • 网络消息是会乱序的;

由此,为了保证分布式系统的服务质量:性能、可用性、可靠性、安全性等,那么就需要进行服务质量保证设计,其可以划分为:

  • 网络是不可靠以及会出现断网之类的故障的,因此分布式系统需要进行服务治理容错设计;

  • 网络乱序以及丢包,因此分布式系统需要幂等性算法设计、端到端的校验算法设计;

  • 网络带宽有限,因此分布式系统需要网络容量设计以及服务治理限流设计;

  • 网络不安全:因此分布式系统需要服务安全设计;

  • 网络是有时延的,因此分布式系统需要进行性能设计:更好的硬件、跟短的IO路径;

  • 网络是会抖动的,因此分布式系统需要进行服务治理容错之超时处理设计。

协同

协同是指:“谐调一致,和合共同,协调两个或者两个以上的不同资源或者个体,一致地完成某一共同目标“,这些组件通过相互传递消息来进行通信和协调其动作,且彼此相互交互以完成一个共同的任务目标

协同又可以拆分为协调动作与共同完成任务,即:

协调动作

分布式系统的组件通过传递消息进行通信及协调其动作,即:因此依据消息传递的特性以及缺点需要进行相应的协调动作设计:

  • 传递消息特性意味着需要进行RPC调用设计;
  • 网络里传递的消息是经常不一样的,因此需要序列化编解码设计;
  • 消息传递具有丢消息、丢处理的弊端,为了解决这个弊端就需要进行 :幂等性设计、事务处理设计、日志设计;
  • 消息的传递是会超时的,因此就需要服务治理容错之超时处理设计;
  • 消息是基于网络传输的,而网络是可能随时出故障的,因此需要对消息进行可观测性设计即消息追踪设计;
  • 需要知道消息从哪里来,往哪里去就需要一个配置中心管理集群各个计算机的信息,比如IP,因此需要进行配置中心设计;
  • 光知道可以发往哪里还不够,还要知道发往的节点是活着的可服务的,需要知道计算机节点的服务状态,还需要保证消息路由的负载均衡,因此这就就需要一个协调的服务注册中心,进行服务组件的注册与心跳检测、消息路由以及按集群视图变更算法管理集群状态表,那么就需要注册中心设计、注册算法设计、负载均衡算法设计,心跳算法设计、集群视图变更算法设计以及集群状态表管理设计。

共同完成任务

分布式系统的组件是通过相互交互以完成一个共同的任务目标,因此需要解决共同完成任务并且保证任务完成质量带来的难题:

  • 整个分布式系统需要能接收任务以及返回完成的任务,那么就需要有提供服务的能力,需要有服务调用接口设计,服务调用客户端以及可视化界面;

  • 为了能让网络里的N台计算机相互交互完成一个共同的目标,就需要对任务进行拆分以及聚合设计;

  • 任务拆分后要能知道发给哪个节点,那么就需要一个配置中心, 从配置中心获取目标节点信息;
  • 任务拆分后分发给节点同时要保证处理的性能,那么就需要进行可伸缩性设计,一台机器处理不过来就需要N台机器一起处理从而保证处理的性能质量,因此又衍生出需要路由算法设计或分区分配算法设计,这样拆分后的任务可以被分发到不同的独立的节点进行处理,并且,但一个节点不可用时,还可以分发到其他的可用的节点,从而提升了系统性能与可用性;
  • 任务又可以分为计算任务与存储任务,如果是存储任务,为了保证数据的可用性以及可靠性,就需要对分区进行冗余设计,即节点副本设计,如果需要节点副本设计又引入了选主算法设计、数据一致性复制算法设计与幂等性设计;
  • 为了解决选主与复制一致性问题,又出现了PAXOS,RAFT,2PC,3PC 等,这样的基础一致性协议算法。

至此,依据分布式的公理化公式:“分布式系统 = 计算机 + 网络 + 协同”,推导出了分布式的定理化推论,解读了分布式系统里为什么需要进行这些功能与非功能设计的问题,接下来还需要讲述分布式系统的度量。

分布式系统的度量

分布式系统是依据分布式公理定义的质量进行度量的,其涵盖以下几项内容:

  • 合适的性能(Performant),性能指标一般包括 TPS, QPS, Latency, IOPS, response time等,这里用”合适的性能“作为表达,指的是性能合适即可、够用即可,高性能当然好,但是高性能也意味着更高的成本,有些场景高性能反而是一种浪费行为,性能需求需要理解业务场景适可而止;

  • 可用性(Availability),可用性指的是系统长时间可对外提供服务的能力,通常采用小数点后的9的个数作为度量指标,按照这种约定“五个九”等于0.99999(或99.999%)的可用性,默认企业级达标的可用性为6个9。但是当前从时间维度来度量可用性已经没有太大的意义,因为设计得好的系统可以在系统出现故障得情况下也能保证对外提供得服务不中断,因此,当前更合适得可用性度量指标 是请求失败率;

  • 可靠性(Reliability),可靠性一般指系统在一定时间内、在一定条件下可以无故障地执行指定功能的能力或可能性, 也是采用小数点后的9的个数作为度量指标,通常5个9的可靠性就可以满足企业级达标;

  • 可伸缩性(Scalability),是指通过向系统添加资源来处理越来越多的工作并且维持高质量服务的能力,其受可用性以及可靠性的制约,集群规模越大出故障的概率越高从而降低可用性、可靠性,为了保证可用性以及可靠性达标,需要适配合理的可伸缩性指标;

  • 韧性(resilience),通常也叫容错性(fault-tolerant),也就是健壮和强壮的意思,指的是系统的对故障与异常的处理能力,比如在软件故障、硬件故障、认为故障这样的场景下,系统还能保持正常工作的能力;

  • 可观测性(Observability),是一种设计理念,包括告警、监控、日志与跟踪,可以实时地更深入地观测系统内部的工作状态;

  • 安全性(security),指的是阻止非授权使用,阻止非法访问以及使用,保护合法用户的资产的能力;

  • 易用性(usability),指的是软件的使用难易程度,对于产品的易用性来说, 易用性不仅仅 是软件使用角度的易用,还包括安装、部署、升级上的易用,升值还包括硬件层面的易用,比如产品的外观,形状等;

  • 可运维性(operability),可运维性指的是运维人员对系统进行运维操作的难易程度,主要包含以下几个方面的难以程度: 系统的部署、升级、修改、监控以及告警等;

  • 可测试性( testability),指的是单元测试,集成测试,打桩测试等的难易;
  • 可维护性(Maintainability), 指的是代码升级,部署,定位bug,添加功能的难易;
  • 可扩展性( extensibility), 指的是未来增加新的功能与模块的难易;
  • 可读性( readability),指的是代码的易理解程度。

  • 边界约束:集群规模、计算机的容量等物理资源的限制,以及客户、用户、团队的约束需求。

依据这几项质量度量指标,可以保证分布式的“可解释、可复制、可预测”。其中要保证质量的核心思想是“共享资源、消除资源竞用性以及平衡负载。”,共享资源需要注册中心,消除资源竞用性就需要服务治理,平衡负载需要好的路由算法。

分布式系统的反熵增与数据守恒

熵增

熵增定律是物理学的基本定律之一,其被定义为:

1
2
3
1, 熵(Entropy)是用以度量一个系统“内在的混乱程度”,即系统中的无效能量;
2, 熵增定律:在一个孤立系统里,如果没有外力做功,其总混乱度(熵)会不断增大;
3,熵增过程是一个自发的由有序向无序发展的过程并且具有必然性,为了保证有序就必须逆熵增做功。

分布式系统也是一个孤立的系统,其中的网络与计算机节点(涵盖电源、主板、CPU、内存、网卡、硬盘等)等硬件会老化、会出故障,组件之间协同工作也会遇到负载过高、软件系统出现BUG等问题,这也是一个熵增的过程,并且因为熵增的必然性,分布式系统总是自发地或非自发地不断由有序走向无序,最终不可逆地走向失效不可用。为了保证分布式系统是有序可用的就必须逆熵增做功,即对其反熵增,分布式系统的反熵增过程与方法是:

  • 可运维设计:软硬件的部署与升级设计、可视化设计、可观测性(监控、告警、日志、追踪)设计;
  • 可服务设计:由团队解决故障以及提供服务的支持;
  • 服务治理设计:熔断、限流、降级、隔离、容错,触使分布式系统保持在有序状态;
  • 智能化设计:参数自我优化、故障自我判断、工作负载自我预测等;
  • 动态平衡设计:动态平衡是一种设计理念,有进有出;

因此其中在分布式系统里将需要将可运维、可服务、可治理、可智能化、动态平衡的思想融合到架构设计与开发中。

数据守恒

能量守恒定律也是物理学的基本定律之一,其被定义为:

1
2
3
1,能量既不会凭空产生,也不会凭空消失,它只会从一种形式转化为另一种形式,或者从一个物体转移到其它物体,
而能量的总量保持不变;
2,孤立系统的总能量保持不变。

在分布式系统里“数据”即是分布式系统的能量,因此参照“能量守恒”定义,这里我给分布式系统一个“数据守恒”定义:

1
2
孤立系统的总数据量保持不变。数据既不会凭空产生,也不会凭空消失,它只会从一种形式转化为另一种形式,
或者从一个物体转移到其它物体, 而数据的总量保持不变;

依据上节的定理推导,我们知道分布式系统里网络是不可靠的、消息传递是不可靠的、计算机节点是不可靠的、磁盘是不可靠的、内存是不可靠的、软件组件是不可靠的等等,这些过程都会丢数据,因此为了保证分布式系统里的“数据守恒”就需要对分布式系统进行数据可靠性设计:即:

  • 分区设计、冗余设计、幂等性设计、端到端的校验设计、日志设计、事务处理设计,缓存的MESI设计等。

因此在分布式系统里将也需要将“数据守恒”的思想融合到架构设计与开发中。

小结

本文以物理学思维挖掘分布式系统的本质,推导出了分布式系统为什么需要这样的设计的缘由,并且文中阐述了分布式系统的基础理论、功能非功能、反熵增与数据守恒。日拱一卒,功不唐捐,分享是最好的学习,与其跟随不如创新,希望这个知识点对大家有用。另作者能力与认知都有限,”我讲的,可能都是错的“,欢迎大家拍砖留念。

作者简介

常平,中科大硕,DELL EMC 资深首席工程师,曾就职于Marvell、AMD,主要从事Linux内核以及分布式产品的交付、架构设计以及开发工作。

版权申明

本文的版权协议为 CC-BY-NC-ND license:https://creativecommons.org/licenses/by-nc-nd/3.0/deed.zh

在遵循署名、非商业使用(以获利为准)以及禁止演绎的前提下可以自由阅读、分享、转发、复制、分发等。

动机

架构设计人员需要有产品的商业意识,作为软件开发人员在工作过程中往往离不开开源项目,但是能回答好“为什么开源的项目不如商业产品?”这个问题的并不多,因此本文就为此做个解读。

为什么开源的项目不如商业产品

开源的项目从产品化的角度来看可分为三个层次:

项目与社区锲合

项目与社区锲合,即开源项目在社区内的锲合程度,度量指标是点赞数、fork数、社区的技术文章阅读量,提升项目于社区的锲合度需要通过运营推广的方式,比如参加技术大会、发布技术文章以及发布完整的项目文档等;

产品与市场锲合

产品与市场锲合,即开源产品在市场的锲合程度,是否满足市场的真正需求,度量指标是下载量、使用量,通常来说开源项目能做到这一步就非常成功了,比如ceph,k8s,Tensorflow, Flink等;

价值与市场锲合

价值与市场锲合,即客户愿意买单的点,度量指标是收入。其一般指的是开源项目里的增值功能以及企业级特性,即项目自身的商业价值,例如:更好的性能、更好的可用性、可靠性、更加易用的部署与升级功能,更加易用的可视化功能、安全、可观测、质量的可度量性、额外的服务支持以及解决方案化。

至此,我们可以看出商业模式的差异决定了开源的项目往往不如商业的产品,这是商业模式带来的差异。开源的项目若是完成了第一层次与第二层次就可以认为是非常成功的一个项目,如果把第3层次也完成了反而是个失败的开源项目,因为这不利于项目的商业化,开发团队赚不到钱没有存活下去的可能性。但是商业化的产品必须涵盖这三个层次,开源的项目还只能算是一个项目还不是产品,它只完成了第1、第2两个层次,因此商业化就要求我们需要把开源的项目产品化。

小结

本文解读了一个问题:为什么开源的项目不如商业产品?日拱一卒,功不唐捐,分享是最好的学习,与其跟随不如创新,希望这个知识点对大家有用。另作者能力与认知都有限,”我讲的,可能都是错的“,欢迎大家拍砖留念。

作者简介

常平,中科大硕,DELL EMC 资深首席工程师,曾就职于Marvell、AMD,主要从事Linux内核以及分布式产品的交付、架构设计以及开发工作。

参考资料

[1] https://a16z.com/2019/10/04/commercializing-open-source/

版权申明

本文的版权协议为 CC-BY-NC-ND license:https://creativecommons.org/licenses/by-nc-nd/3.0/deed.zh

在遵循署名、非商业使用(以获利为准)以及禁止演绎的前提下可以自由阅读、分享、转发、复制、分发等。

动机

依据李善友老师的定义“第一性原理思维 = 逻辑奇点 + 公理化方法”,逻辑奇点即基石假设。根据这个第一性原理思维 ,本文解读了tensorFlow 2.0的架构设计,其涵盖了tensorFlow2.0的第一性原理、设计原则以及架构视图,本文的动机是展示第一性原理的架构设计思想在分布式系统架构设计中的应用。

TensorFlow 的第一性原理

欲从本质上理解Tensorflow,那么就需要找出tensorflow的第一性原理定义,再依据演绎法,从这个公理性质的定义演化出tensorFlow的设计理念、设计原则以及功能实现。这里首先把tensorFlow概念化,找出它的公理化定义以及基石假设,即TensorFlow是什么的定义。

通过tensorFlow官网以及Google,得到的6条关于tensorFlow的定义:

1.A machine-learning library based on dataflow programming.

2.TensorFlow is a free and open-source software library for dataflow and differentiable programming across a range of tasks.

3.TensorFlow is an end-to-end open source platform for machine learning.

4.TensorFlow computations are expressed as stateful dataflow graphs.

5.TensorFlow is an end-to-end open source platform for machine learning. It has a comprehensive, flexible ecosystem of tools, libraries and community resources that lets researchers push the state-of-the-art in ML and developers easily build and deploy ML powered applications.

6.TensorFlow Enterprise incorporates: Enterprise-grade support, cloud scale performance,managed services

从这6个定义中,可以概括出tensoFlow的公理化定义

TensorFlow is an scalable end-to-end machine-learning platform based on stateful dataflow graphs programming,it has a comprehensive, flexible ecosystem.

tensorFlow是一个可伸缩的端到端的面向有状态的数据流图编程的机器学习平台,其具有一个全面而灵活的生态系统。

以及两个基石假设,即逻辑奇点:

  • 可伸缩(scalable):可伸缩性是分布式的目的,分布式能力是TensorFlow的构建与运维能力,分布式能力是tensorFlow的隐性基石假设;
  • 机器学习(machine learning):机器学习是Tensorflow的领域功能,是tensorFlow的显性基石假设。

从这个公理化的定义以及两个基石假设里可以推导出设计tensorFlow的作者们的对tensorFlow的几条类似定理性质的设计理念:

  • 机器学习(machine learning): 指的是功能领域定位,依据这个设计定位,因此tensorFlow提供的是机器学习相关的功能,其涵盖数据、模型、策略、训练、推理等核心功能。

  • 分布式:分布式能力是tensorFlow的构建与运维能力,从抽象的技术实现视角来看tensorFlow就是分布式框架+机器学习的lib库;

  • 端到端(end-to-end): 端到端指的是“全程都包”的一种设计理念,用户输入原始数据,经过tensorFlow处理即可以直接得到可用的结果,这个结果可以直接服务于用户,用户无需关注tensorflow的中间过程如何。在tensorFlow里端到端的设计理念体现在 “准备数据 、定义模型、 训练模型、 评估模型、 保存模型以及使用模型”这几个过程,用户只要输入数据即可以得到可用的结果模型。

  • 平台(platfrom):平台化,通常的软件平台指的是能够让用户自己在上面进行业务开发的软件系统,它将业务与技术解耦,用户可以基于这个平台开发自己的业务。其具有可用户自我定义的灵活性、用户可二次开发的开放性、以及接口标准化的特性。在tensorFlow里的平台化的设计理念体现在用户可以自由的定义自己的业务模型而无需关注里头的技术实现即可以得到想要的输出结果。

  • 有状态(stateful):状态是指事物处于产生、发展、消亡时期或各转化临界点时的形态,有状态是指

    “该服务的实例可以将一部分上下文的数据随时进行备份,并且在创建一个新的有状态服务时,可以通过备份恢复这些数据,以达到数据持久化的目的。”。

    有状态服务在功能上可以保证数据的恰好一次,可以保证数据服务的强正确性,但是有状态服务需要维护大量的信息和状态,因此又引入了数据存储的复杂性,并且多了数据存储加载的过程,在性能方面要弱于无状态服务。而无状态服务不能保证数据的恰好一次处理,但是易于处理实例规模的伸缩性。tensorflow是有状态的设计理念,表明了tensorFlow可以保证数据处理的恰好一次的强正确性,但是又引入了数据存储与IO性能上的复杂性,需要平衡有状态服务下的正确性与复杂性就需要针对数据存储进行专门的设计。

  • 数据流图(dataFlow graphs): 数据流图指的是用节点和有向边描述数学运算的有向无环图,其要素有数据源或宿、数据流、数据处理节点以及数据存储,其中节点代表数学运算等,而有向边代表节点之间的输入与输出关系、数据在边上流动。依据这个设计理念,TensorFlow依据下图的工作过程计算数据:

    计算流图示例

    在这个数据流图里,tensorFlow里需要事先准备数据,接着定义运算操作,然后计算单元被同步或者异步地分配到不同的计算设备上比如CPU、GPU、TPU进行计算,其在边上流动的数据叫tensors。

  • 编程(programming):可编程性,“编程就是指导计算机执行任务的行为”,编程是个动词,是为了让计算机干你想要干的事情。在面向对象编程里,程序=算法+数据结构+方法,依据这个设计理念,即用户可以依据一定的数据结构通过输入算法以及相应的工程方法,就可以指导tensorFlow执行用户想干的事情,其可以二次开发,具有灵活性以及开放性的特征。

  • 生态系统(ecosystem):生态化,指的是tensorFlow的产品商业模式理念,围绕tensorFlow为核心建立一个完整的工具、库以及社区资源生态系统。

通过以上的分析,可以得出tensorFlow的第一性原理,即:tensorFlow是一个端到端的面向有状态的数据流图编程的机器学习平台,自带完整的产品生态系统,其逻辑基石为“分布式及机器学习”。就是这么简单的一句话,但是却是tensorFlow作者们的设计理念,整个tensorFlow的所有设计理念、设计原则以及功能实现都是依据这一句话来做指导的。

TensorFlow的设计原则

从tensorflow的官网可以看到几个关键词“easy,robust,powerful,ecosystem”,这几个词即是temsorflow的设计原则,tensorFlow的设计原则是定理性质的定义,其也从tensorFlow的第一性原理定义中推导出来。“端到端”代表了易用性,“平台化”、“可编程”代表了功能强大,“分布式”代表可高可用性、高可靠性,另外tensorFlow还有一个生态化的运营理念,灵活、开放、完整。

易用(Easy)

易用性的设计原则体现在与用户打交道的API接口层、模型的使用以及分布式训练:

  • 模型制作简单,API容易调用,TensorFlow 提供多个级别的抽象接口,可以使用高阶的 Keras API 轻松地构建和训练模型

  • 开发过程可调试,支持Eager Execution 进行快速迭代和直观的进行调试

  • 训练过程简单,可以使用 Distribution Strategy API 在不同的硬件配置上进行分布式训练而无需更改模型定义

可靠(Robust,鲁棒性、可靠)

  • 支持随时随地进行可靠的机器学习生产。支持在本地服务器、边缘设备、云端、web端轻松地训练和部署模型,而无需关注开发语言。TensorFlow Extended (TFX)可用于生产型机器学习, TensorFlow Lite可用于移动设备和边缘设备的推断, 而 TensorFlow.js 支持在web端中训练和部署模型

强大(powerful)

  • 架构简单而灵活,支持最先进的模型,并且可以保证性能。借助 Keras Functional API 和 Model Subclassing API 等功能,TensorFlow 可以灵活地创建复杂拓扑并实现相关控制。TensorFlow 还支持强大的附加库和模型生态系统,包括 Ragged Tensors、TensorFlow Probability、Tensor2Tensor 和 BERT。

生态化(ecosystem)

  • 生态化是产品的商业模型,灵活、开放、强大,tensorFlow具有完整的一个生态环境,其拥有一个包含各种工具、库和社区资源的全面灵活生态系统,可以让研究人员推动机器学习领域的先进技术的发展,并让开发者轻松地构建和部署由机器学习提供支持的应用

从tensorFlow 1.0 到tensorFlow 2.0 的升级,涵盖了API的易用性升级,动态图的支持、算法的更新、功能迭代以及文档完善,其本质目的还是遵循这四个设计原则,即简单、可靠、强大、生态化。如果只是追寻tensorFlow的版本迭代而不理解其背后的设计理念、设计原则,只会疲于奔命、知其然而不知其所以然。

TensorFlow 架构视图

逻辑架构视图

TensorFlow的逻辑架构视图体现了tensorflow的功能需求,如下图,tensorFlow的功能可分为训练、部署、可视化以及模型仓库。

逻辑架构图

训练

  • tf.data用于加载训练用的原始数据
  • tf. Keras 或 Premade Estimators 用于构建、训练和验证模型
  • eager execution 用于运行和调试
  • distribution strategy 用于进行分布式训练,支持单机多卡以及多机多卡的训练场景
  • SavedModel用于保存导出的训练模型,并且将训练模型标准化,作为 TensorFlowServing、TensorFlow Lite、TensorFlow.js、TensorFlow Hub 等的交换格式

部署

  • TensorFlow Serving,即TensorFlow允许模型通过REST以及gPRC对外提供服务
  • TensorFlow Lite,即TensorFlow针对移动和嵌入式设备提供了轻量级的解决方案
  • TensorFlow.js,即TensorFlow支持在 JavaScript 环境中部署模型
  • TensorFlow 还支持其他语言 包括 C, Java, Go, C#, Rust 等

可视化

  • TensorBoard 用于TensorFlow可视化

模型仓库

  • TensorFlow hub用于保存训练好的TensorFlow模型,供推理或重新训练使用

处理架构视图

TensorFlow的处理架构视图表明了数据处理的流程,其具有tensorFlow的运行期间的质量需求。

处理架构视图

本图是分布式工作模式,“/job:worker / task:0” 和 “/ job:ps / task:0” 都是工作节点上执行的任务。“PS” 表示 “参数服务器”,负责存储和更新模型参数。

处理流程

1)客户端负责将整个计算过程转义成数据流图,并且启动计算发送到分布式主节点;

2)分布式主节点基于用户传递给的参数对整个完整的图形进行修剪,提取其中的子图,接着将子图拆分成不同部分,并将其分发到不同的进程和设备当中;

3)工作节点执行其收到的主节点分发给它的数据图片段,并且与其他工作节点 相互发送和接收计算结果;

4)内核计算单元,执行单个图形操作的计算部分。

数据处理期的质量与约束

TensorFlow分布式模式是构建在分布式之上的,其具有分布式系统自身的质量与约束需求:

  • TensorFlow的质量需求:性能指标:TPS、QPS、IOPS、Latency、ResponseTime、缓存抖动指标、缓存命中指标,可靠性指标: 6个9企业级代表,可用性指标:6个9企业级达标,数据一致性指标,可伸缩性,韧性,可观测性,可服务性,安全性,易用性,可运维性等

  • TensorFlow的约束需求:其可以是资源容量约束:CPU、磁盘、网络、线程、文件描述符个数,也可以是客户的约束、用户的约束等。

TensorFlow 2.0 的缺点

  • 网络,开源的TensorFlow默认采用gRPC作为基础通信组件,违背“最佳物种”里的最佳原则设计哲学,机器学习本身是高吞吐量高性能要求的生产场景,而gRPC是基于HTTP2/Protobuf 协议通信的,而且发送接收都需要序列化,增加了网络传输的延时,并不是机器学习场景的最佳选择,但是好在TensorFlow也支持让你“DIY”的设计理念,例如在网络通信上支持GDP(GPU DIRECT)VERBS(IB,RDMA)以及MPI的扩展(“https://github.com/tensorflow/networking: Currently support building GDR, VERBS, and MPI extensions),这相当于把这一部分产品化的工作给了用户或者GPU、TPU之类的芯片原厂。优化手段:将PS算法、RING ALLREDUCE算法融合进MPI,再根据工程实践情况取舍“容错、可服务化、可运维化、智能化“的设计理念,抽象出一个新的分布式调度中间件以替换gRPC,目的是获取更好的性能、更高的GPU、TPU性价比。

  • 计算,计算架构很有限还不能榨尽各种硬件的最佳性能。目前的分布式计算视图架构成熟的方案有:Parameter Server 架构以及Ring AllReduce架构,那么是否还有其它更好的架构,比如区块链的去中心化架构。

  • 存储,存储应用容易被忽视,系统太过于复杂。TesnorFlow里涉及到存储的地方有:海量或非海量的原始数据存储、ETL好的数据的存储、PS架构中的训练参数以及模型的存储,训练好的模型的存储,如果这四个存储需求都是分散的存储系统,其实复杂度挺高,可以专门针对这种场景以及数据特性设计一个专门的机器学习存储系统,除了可以同时满足这四个场景的质量指标外,还将四个系统统一成一个,减少机器学习场景下的系统复杂度。

  • 功能,功能的优化是无止境的,原则是要遵循客户需求适可而止。TensorFlow本质上也是分布式系统+机器学习领域的能力,除了机器学习的各种算法魔法的持续优化,分布式系统里的各种分布式算法也是适合迁移过来挖掘的,比如服务治理、路由负载均衡算法、集群视图变更、消息传输等。比如这么一个工程课题:“如何支持上万张训练卡的规模以及如何保证其质量可以达标?如何保证系统性能可以随着训练的卡数线性增长并且保证卡子的利用率在90%以上,同时可以保证训练过程的可靠性?”

  • 产品,一个开源项目的功能特性大多是取舍的结果,就算是缺点往往也会很快演化迭代掉,因此从技术角度看待一个开源项目缺乏可持续性。但是从产品的角度来看,开源项目自带开源的先天弊端,其缺乏“价值与市场的锲合“度,这是开源项目的先天缺点,越成功的开源项目越无法避免,如果避免了这个缺点,开源项目反而是失败的,因为做的太好反而无法收费,团队没法存活,TensorFlow2.0开源版是一个开源的项目因此也逃脱不了这个缺点。从“项目与社区锲合”以及“产品与市场锲合”的角度来看,依据点赞数、fork数、下载量、用户使用量、社区文章阅读量这几个指标做度量,TensorFlow 2.0 开源版是一个非常成功开源的软件,但是从”价值与市场锲合“这个角度看,其离商业产品还是有一段距离。

    开源项目往往是靠一些增值功能、企业级特性以及服务的支持收费而存活,这些特性即为价值与市场的锲合点,是商业客户愿意买单的地方,是商业产品与开源项目差异化所在,这些特性有:更好的性能、更加易用的部署与升级功能,可运维化、更加易用的可视化功能、安全、可观测、质量的可度量性,此外客户往往需要的不只是一个产品,更进一步需要的是行业解决方案。例如,tensorFlow企业版就说明了支持企业级特性、可云端伸缩性能以及无缝管理的支持,而TensorFlow2.0 开源版只是一个开源项目,还没达到这个层度。

    因此,从产品的角度看,开源的tensorFlow2.0开源版只能算是一个成功的开源项目还不是商业产品以及解决方案,它只完成了“项目与社区锲合”以及“产品与市场锲合”这两个层次,因此商业化就要求我们需要把开源的tensorFlow2.0产品化、解决方案化。

小结

本文依据第一性原理架构设计思维模型解读了TensorFlow2.0。第一性原理思维模型我不是首创,分布式系统架构设计我不是首创,第一性原理思维模型在分布式系统架构设计中的应用我是首创。日拱一卒,功不唐捐,分享是最好的学习,与其跟随不如创新,希望这个知识点对大家有用。另作者能力与认知都有限,”我讲的,可能都是错的“,欢迎大家拍砖留念。

作者简介

常平,中科大硕,DELL EMC 资深首席工程师,曾就职于Marvell、AMD,主要从事Linux内核以及分布式产品的交付、架构设计以及开发工作。

参考资料

[1] https://blog.tensorflow.org/2019/09/tensorflow-20-is-now-available.html

[2] https://github.com/tensorflow/tensorflow

[3] https://en.wikipedia.org/wiki/TensorFlow

[4] https://www.tensorflow.org/about

[5] https://tensorflow.google.cn/guide/?hl=zh-CN

版权申明

本文的版权协议为 CC-BY-NC-ND license:https://creativecommons.org/licenses/by-nc-nd/3.0/deed.zh

在遵循署名、非商业使用(以获利为准)以及禁止演绎的前提下可以自由阅读、分享、转发、复制、分发等。

动机

万事万物逃脱不出“不易、简易、变易”这三个层次,演绎法认为“道生一、一生二、二生三、三生万物”,而归纳法也可以认为“万物合三,三合二、二合一、一合道”。本文的目的之一是通过归纳法找出分布式系统架构设计最为本质的“道”,使之可以用于解读各式各样的分布式系统架构设计。

从应用领域来看分布式系统可以分为三大类:分布式计算、分布式存储以及分布式调度,本文做的是从这三大领域的”变易”中找出“不易、简易”,“以”不变“应”万变“,从而抽象出一种分布式架构思维使之可以应用于这三大领域的架构设计。

架构思维模型

在面向对象编程有四个最高的思想,即“抽象、封装、继承与多态”,将这个思想迁移应用到本文,可以解读为架构思维是第8式“火箭技术思维模型”的以及第0式”设计总决“的继承,这里我把它定义为“分布式系统火箭架构思维模型”,如下图:

架构思维模型

火箭架构思维模型

这个架构思维模型用图形是一个内部分层的三角形,类比为一个5级火箭体,它包括“势 道 法 术 器 界”这六个要素,其下一级为上一级的提供动力的同时又受三条边的约束。

狭义上的分布式系统架构通常指的是架构的技能,其属于“术”的范畴,而广义的分布式系统架构则是市场趋势、架构理念、架构方法论、架构技能、架构用的工具以及架构的边界这几个方面的组合体,应用抽象思维,即“势、道、法、术、器、界”这六个字 ,简称架构思维六元组。

势:时势,是架构的方向

“势”是架构的方向。从宏观处着眼,“势”是产品架构设计的市场趋势、是客户需求趋势也是技术的应用趋势;从微观处着手,“势”是功能设计的价值与目的。架构设计需要从宏观处着眼微观处着手,看清客户的需求趋势、市场趋势以及技术趋势,功能设计需要分析清楚当前功能的价值与目的。除了明白架构的是什麽的问题,还需要明白为什麽需要做这个架构设计,这就需要从“势”处定义问题、分析问题、过滤问题以及解决问题。

团队一起讨论架构选型与功能设计的问题,经常会遇到A说A有理,B说B有理,最终方案无法达成一致致使项目拖延甚至失败的情形。这就需要梳理清楚架构的目的、原则、质量与边界,对方案进行方向上的约束,那么“势”就是架构选型与功能设计的约束条件之一,其用于定义架构的目的。

道:理念,是架构的认知

“道”是架构的认知,是架构师的设计理念、设计意图,是产品架构的灵魂。美国学者布卢姆认为认知有六层次:识记、理解、应用、分析、评价、创造。产品架构是由人设计的,那么不可避免的就会带有人的因素在里头,”见其所欲“,你所看到的架构都是架构师欲让你看到的,对分布式系统认知层次不同的人,理念也是不同的,欲深入理解一个产品的架构必须要能找到设计它的人的设计”理念“。

进行分布式系统的架构设计,首先我们要知道分布式系统的第一性原理是什么?即分布式系统的类似公理性质的定义,Google 出来的对分布式系统的定义有:

1
2
A distributed system is a system whose components are located on different networked computers, which communicate and coordinate their actions by passing messages to one another. The components interact with one another in order to achieve a common goal.
分布式系统是一个组件分布在不同的联网的计算机上,彼此之间仅仅通过消息传递进行通信和协调的系统,这些组件相互交互以实现一个共同的目标。

这句话就是分布式系统的第一性原理,是分布式系统的类公理性质的理论定义,其非常重要,默认不变的公理性定义,解读开来就是:“分布式系统是由建立在网络上的通过消息进行通信和协调的系统,各个机器相互交互一起完成一个共同的目标。”,从这句话里可以推理出分布式系统的几个类似定理性质的特征定义:

  • 分布式系统是基于网络的,网络所具有的毛病它都有,网络会丢包、网络有带宽限制、网络有安全隐患、网络有负载均衡问题等,那么这些问题在分布式系统里需要怎么解决?那么如何提高服务的可靠性?如何保证服务的可用性?

  • 分布式系统是基于消息传递的,那么如何保证消息的幂等性?如何保证消息的正确性?如何保证消息传递的性能?如何保证消息传递的可靠性?

  • 分布式系统是协调工作的,那么如何协调大量的计算机节点的完成一个共同的目标,如何解决协调的复杂性以及提高协调的可靠性?
  • 分布式系统是一起相互交互完成一个共同的目标的,那么如何一起交互?如何拆分目标?如何聚合目标,如何提高完成目标的性能?
  • 分布式系统是分布式的,其具有分布性的特点,那么如何保证分布式所要求的负载均衡、可伸缩性、韧性等功能与质量需求?

依据分布式系统的第一性原理,本文解读了分布式系统的理论认知,除此之外还可以依据个人对分布式系统的工程经验推理出分布式系统的实践认知,依据工程实践经验,这里我定于分布式系统为:

1
分布式系统是面向集群状态的编程, 它是抽象、分层、解耦、拆分、聚合、治理、取舍、模型、质量、边界、演化思维的创造性应用,其要交付的是功能价值,但功夫却体现在非功能。

不同于教科书以及一些论文对分布式系统的理论定义,这个定义来源于个人工程经验,是认知的创造。分布式系统的功能、质量与约束都来自于这两个理论定义与工程定义。

法:方法论,是架构的套路

”法“是方法论,是架构设计的方法论,是架构设计的套路,它是认知论的上一级,方法论体现在产品的设计原则、设计心法以及设计功能。从工程经验的角度,本文认为分布式系统设计可以依从以下的”9法10项2原则“ 作为方法论。

9法
1
2
3
少读少写少依赖,业务拆业务合,功能拆性能聚,时空换同异换

硬件顺天性,服务需治理,数据保一致,哪都不可靠,事事慎权衡
  • 少读少写少依赖: 少读,即减少读放大,减少需要读的数据量;少写,即减少写放大,减少需要写的数据量;少读少写的策略可以是提高cache命中率也可以是进行数据压缩,还可以是合适的读写算法与数据结构等,少依赖,即解耦,拆分,高内聚低耦合
  • 业务拆业务合:分布式系统里要有拆有合,拆的目的是为了解耦、是为了集群业务可伸缩,是为了组件上的小可以支持集群规模上的大;合的目的是为了内聚,聚合拆分的服务返回的子结果,从而返回大结果;“业务拆业务合”,其理论依据来源于“康威定律”,即: 设计系统的组织其产生的设计等价于组织间的沟通结构,软件架构的拆合关系来源与团队的组织结构。

  • 功能拆性能聚:在分布式系统里有拆有合,那么拆与合的取舍依据在哪里?这句话讲的就是拆与合的取舍关系:依据功能进行拆分,但是也要依据性能进行聚合,拆开后会影响性能的地方最好不拆

  • 时空换同异换: 时空换同异换讲的是性能优化的路数,解读开来说即是:时间换空间、空间换时间、同步换异步、异步换同步。例如:采用cache的功能可以减少计算的时间,这是存储空间换时间从而提升性能;采用批处理的方式提升性能,这是减少计算时间;采用异步换同步的方式提升性能也是减少计算时间;减少IO的数据量从而提升性能,这是存储空间换时间;减少IO路径提升性能,这也是网络空间换时间;采用最新的硬件提升性能,这可以是计算换时间,也可以是存储或网络空间换时间

  • 硬件顺天性:硬件顺天性讲的是软件设计要遵循硬件的原生特性,CPU的分核调度、机械盘性能不如固态硬盘、磁盘分块需要对齐、磁盘是有可能会电子位飘逸丢数据的、内存性能好适合做缓存但是下电就丢数据、网络是不可靠的并且有带宽限制、RDMA网络比IP网络性能好,机器学习采用GPU比CPU更能获得高计算性能;不同的应用场景要依据硬件的不同特性做架构选型以及架构设计等。

  • 服务需治理:指的是分布式系统是由各种不同的组件进行组合连接而成,其需要服务治理设计,服务需治理背后的原因来源于分布式系统式搭建在网络上的,其继承了网络的毛病,背后的指导思想是“墨菲定律”,即“会出错的事总会出错”,服务治理的具体解决方案可分为容错、降级、限流、熔断、隔板这五个模式
  • 数据保一致:要保证分布式系统对外提供的服务的数据的一致性,cache掉电会丢数据、网络不可靠会丢数据、磁盘电子不可靠会丢数据,计算丢请求会丢数据,各种场景下都需要保证数据的一致性,比如缓存的MESI算法保数据、掉电刷内存保数据、网络端到端的校验、磁盘扫描校验、数据副本保数据等
  • 哪都不可靠:指的是磁盘不可靠、网络不可靠、计算不可靠、运维的人不可靠,何种场景都需要进行系统的韧性设计
  • 事事慎权衡:指的是架构设计本身的设计方法论,即trade-off
10项
1
2
提供 注册 配置 调用 路由
观测 治理 编排 质量 边界
  • 提供:即服务接入的提供,指的是对外提供restful 接口服务:权限、多组合、监控、审计、计费等,对外提供SQL服务接入接口服务、对外提供自然语言接入接口服务等
  • 注册:即服务注册,将集群的工作负载注册到集群注册中心
  • 配置:即配置管理,将集群的配置管理在配置中心;
  • 调用,即服务调用,各种RPC调用,系统内的消息传递
  • 路由:即服务路由,目的是集群的负载均衡与扩伸缩性
  • 观测:指的是集群内部指标的可观测性,即监控、告警、追踪、日志
  • 治理:指的是集群内部的服务治理:熔断、降级、限流、隔离、容错
  • 编排:即服务编排,基于k8s+ docker,完成安装、升级、扩容、运维、调度等;
  • 质量:指的是安装部署运维质量、客户质量、用户质量与开发质量
  • 边界:指的是系统内的约束条件,涵盖 硬件资源、客户约束、用户约束以及团队约束
2原则:
  • 最佳物种原则
  • 功能非功能原则
最佳物种原则

最佳物种原则其来源是生物的物种进化理论,讲的是产品原则,其可以一分为二:

1,最佳原则,做产品架构设计的时候要挖掘不同的业务特性以及其业务本质,从而设计出与业务最为匹配的架构。天上飞的是鸟儿,地上奔跑的是走兽,水里游的是鱼儿。架构设计由大及小,由外及内也是如此。比如计算用的是分布式计算、存储用的是分布式存储,调度用的是分布式调度,其负责的领域各不相同,不存在一个全能的分布式中间件可以最佳的完成计算、存储、调度三合一的功能。从小处来讲也是如此,比如分布式系统内部的注册、路由、成员管理、服务提供、复制、安全、算法模型、存储等各有其自己最佳的设计方案,再依据这些最佳组件、最佳方案组合出一个最佳分布式中间件。

2,进化原则,万物由微而显,由简而繁,物竞天择,优胜劣汰,好的架构是根据业务演化而来,而不是一开始就完美的设计好的。但是不管是微还是显,其最本质的功能还是不变的,一个产品从POC到MVP再到企业级达标其最核心的功能是不变的,比如计算、存储与调度。

功能非功能原则

功能非功能原则,讲的是技术原则,从大体上来说,分布式系统的架构设计都是围绕其功能与非功能的量化设计来进行的,非功能又可以一分为二,即:质量与约束,比如:

客户对产品质量的需求一般可以用四个字概括,即”多、快、好、省“,然而客户在产品交付的时间、质量与成本上的取舍,客户原来遗留的系统,当前国家的法律法规,市场上的技术趋势以及竞争对手与行业标准等都属于当前客户需要考虑的约束条件。

用户的产品质量需求一般称为使用质量需求,其一般包括:性能、可用性、可靠性、可伸缩性、韧性、可观测性、可服务性、安全性、易用性、可运维性等,而用户的约束需求包括 用户的业务环境、用户的能力以及用户群的特征等。

团队的质量需求指的是产品开发周期内的质量需求,高质量的代码几个最重要的要素有:可测试性、可维护性、可扩展性、可读性等,而团队的约束需求有:资源预算、上级要求、开发团队的能力、产品规划、此外还有信息安全以及产品运行环境 的约束等。

术:技能,是架构技能

术,技能,是架构技能,其可以分为需求分析、设计哲学定义、设计方法论定义、设计原则定义、架构制图、基础理论理解与应用、基础数据结构理解与应用、基础算法设计、基础组件设计、质量达标设计以及边界约束设计。即:

  • 分布式系统的需求分析:这里可以依据需求分析公式:需求 = [客户,用户,团队] x [功能,质量,约束],进行全面的架构需求分析。

  • 分布式系统的设计思想:抽象、 分层、 解耦、 拆分 、聚合、治理、取舍、模型、质量、边界、演化

  • 分布式系统的设计原则:最佳物种原则,功能非功能原则

  • 分布式系统的架构视图:我们在学习画法几何或机械制图的时候,要描述一个物体可以采用视图法来表示,比如机械制图里要制造一个零件的时候,需要依据这个零件画出可以根据这个图形加工的视图,其通常采用正视图、俯视图、侧视图,加上额外的细节视图与质量指标、材料约束的方法。同样我们做软件架构设计的时候,也需要将具体的”软件体“抽象成视图来表示,同时也需要标记上质量与边界约束。

    4+1架构模型

    如上图常用的4+1视图:物理视图、逻辑视图、处理视图、开发视图以及用例视图,其中与用例视图交叉的部分是描述共同的细节,同时每种视图中又有各自的需求,比如物理视图有安装、部署、升级、运维的需求,逻辑视图有功能需求,处理视图有非功能里的用户运行质量需求,开发视图有团队的开发质量需求。

  • 分布式系统的基础理论:CAP/PACELC、BASE、ACID、2PC、3PC、PAXOS、RAFT

  • 分布式系统的基础数据结构:Array、List、Map、Hash、Tree,及其变种

  • 分布式系统的基础算法:负载均衡算法(一致性hash算法、分区分配算法)、选主算法、心跳算法、集群视图变更算法、幂等算法、复制算法、缓存MESI算法

  • 分布式系统的基础组件:服务提供(Restful接口,SQL接口,自然语言接口)、服务注册(zookeeper,etcd,consul,etc)、服务配置(zookeeper,etcd, consul,etc)、服务调用(brpc,netty,etc)、服务路由(一致性Hash算法、分区分配算法)、服务追踪(zipkin,pinpoint,skywalking,cat,etc)、服务监控(Metrics)、服务治理(容错、降级、限流、熔断、隔板)、服务编排(k8s、docker)、服务安全(keycloak,etc)

  • 分布式系统的质量指标:性能指标:TPS、QPS、IOPS、Latency、ResponseTime、缓存抖动指标、缓存命中指标,可靠性指标: 6个9企业级代表,可用性指标:6个9企业级达标,数据一致性指标,可伸缩性,韧性,可观测性,可服务性,安全性,易用性,可运维性,可测试性,可维护性,可扩展性,可读性等,质量指标要能可度量化,可执行化

  • 分布式系统的约束边界:其可以是资源容量约束:CPU、磁盘、网络、线程、文件描述符个数,也可以是客户的约束、用户的约束以及团队的约束

器:工具,架构设计用的工具

”器“是工具,是架构设计用的工具,”工欲善其事必先利其器“,常用的架构设计制图工具有MS Visio、Draw.io,UML制图用的Enterprise Architect、starUML等,当然组织提供的资源支持也可以算是工具之一。

界:是边界,是架构的约束

”界“是边界,是架构的约束限制,火箭架构思维模型里的三角形的三条边代表着“界” ,是技术边界、也是技术约束与技术限制,也是架构的取舍因素之一,是架构能做什麽不能做什麽的解读,对市场来说它是技术壁垒,对产品来说它是法律法规、是功能约束,对团队来说它是资源约束、是自我能力约束。

小结

本文讲述了分布式系统的架构思维模型,其目的希望以此架构思维模型应用于各种领域的分布式架构系统设计。日拱一卒,功不唐捐,分享是最好的学习,与其跟随不如创新,希望这个知识点对大家有用。另作者能力与认知都有限,”我讲的,可能都是错的“,欢迎大家拍砖留念。

作者简介

常平,中科大硕,DELL EMC 资深首席工程师,曾就职于Marvell、AMD,主要从事Linux内核以及分布式产品的交付、架构设计以及开发工作。

版权申明

本文的版权协议为 CC-BY-NC-ND license:https://creativecommons.org/licenses/by-nc-nd/3.0/deed.zh

在遵循署名、非商业使用(以获利为准)以及禁止演绎的前提下可以自由阅读、分享、转发、复制、分发等。

动机

“不易、简易、变易”这三个范畴里,技术是属于“变易”范畴的,其千变万化;“方法论”是属于“简易”范畴的,其具有领域普适性的指导能力;而架构设计总决属于“不易”的范畴,其具有第一性原理的本质指导能力。本文的目的之一即是挖掘出分布式系统架构设计的第一性原理,使其可以应用于千变万化的不同的技术领域。

架构是由人设计出来的,其与设计的人的架构理念强相关,欲彻底了解一个产品的架构必须要能量化它的设计理念,从而才能更好的由现象到本质了解一个技术,因此本文的目的之二即是量化人的架构设计理念。

分布式系统

软件设计的第一性原理是“定义问题,分析问题,过滤问题以及解决问题。”,其最重要的第一步是“定义问题”,问题定义的准确与否直接决定了后面的分析问题,过滤问题以及解决问题的方向与准确性。那么,什么是分布式系统?各种论文以及书籍都有过自己的定义,比如《分布式系统原理与范型》定义分布式系统为:

1
分布式系统是若干独立计算机的集合,这计算机对用户来说就像单个相关系统。

还有Google出来的定义:

1
2
A distributed system is a system whose components are located on different networked computers, which communicate and coordinate their actions by passing messages to one another. The components interact with one another in order to achieve a common goal.
分布式系统是一个组件分布在不同的联网的计算机上,彼此之间仅仅通过消息传递进行通信和协调的系统,这些组件相互交互以实现一个共同的目标。

这是分布式系统理论的第一性原理,不同于这些从理论角度的定义,这里,我从工程实现的角度给分布式系统一个新的定义,即:

1
分布式系统是面向集群状态的编程, 它是抽象、分层、解耦、拆分、聚合、治理、取舍、模型、演化、质量、边界思维的创造性应用,其要交付的是功能价值,但功夫却体现在非功能。

从工程的角度来看,这个定义是分布式系统实践的第一性原理,分布式系统都是围绕着集群状态表来进行编程的,集群状态表是分布式系统的核心功能中的核心。因此本系列分布式系统文章都是依据理论结合实践的原则,从工程交付的角度来看待分布式系统的。

设计哲学

什么是分布式系统的设计哲学?首先这里的设计哲学不是产品的设计哲学,它是一种工程哲学,是分布式系统架构设计原则以及设计方法论的指导思想,是架构师的内功。其目的是为了指导架构设计的过程,克服架构设计难题从而达到最终的架构设计目标。不同的架构师有自己不同的设计哲学观,这里我提出分布式系统架构设计哲学9式,即:

1
抽象 分层  解耦 拆分 聚合 治理 模型 取舍 质量、边界 演化

这9个词每个词展开来讲都可以是一篇大论,不同的架构设计师有自己不同的设计哲学观,也就形成了不同的架构设计原则以及设计方法论,并不存在一个普适的、统一的架构设计哲学,适合自己的才是最好的,每个人的领悟不同,因此这里也就不展开来讲。

设计原则

同设计哲学一样,不同的架构设计师有着自己不同的设计原则观,在这里,我认为最合适的分布式系统的架构设计原则有二,即:

  • 最佳物种原则
  • 功能非功能原则

最佳物种原则

最佳物种原则其来源是生物的物种进化理论,讲的是产品原则,其可以一分为二:

1,最佳原则,做产品架构设计的时候要挖掘不同的业务特性以及其业务本质,从而设计出与业务最为匹配的架构。天上飞的是鸟儿,地上奔跑的是走兽,水里游的是鱼儿。架构设计由大及小,由外及内也是如此。比如计算用的是分布式计算、存储用的是分布式存储,调度用的是分布式调度,其负责的领域各不相同,不存在一个全能的分布式中间件可以最佳的完成计算、存储、调度三合一的功能。从小处来讲也是如此,比如分布式系统内部的注册、路由、成员管理、服务提供、复制、安全、算法模型、存储等各有其自己最佳的设计方案,再依据这些最佳组件、最佳方案组合出一个最佳分布式中间件,从而计算的归计算、存储的归存储、调度的归调度。

2,进化原则,万物由微而显,由简而繁,物竞天择,优胜劣汰,好的架构是根据业务演化而来,而不是一开始就完美的设计好的。但是不管是微还是显,其最本质的功能还是不变的,一个产品从POC到MVP再到企业级达标其最核心的功能是不变的,比如计算、存储与调度。

功能非功能原则

功能非功能原则,讲的是技术原则,架构的目的是提供该领域的功能,然而功夫却是体现在非功能。比如常见的几个深度学习框架在功能上都具有深度学习训练与推理的能力,但是让用户决定是否选择这个框架的主要决定性因素却体现在其非功能,比如性能、可用性、可靠性、易用性、服务支持以及版权等。

从大体上来说,分布式系统的架构设计都是围绕其功能与非功能的量化设计来进行的,非功能又可以一分为二,即:质量与约束,比如:

客户对产品质量的需求一般可以用四个字概括,即”多、快、好、省“,然而客户在产品交付的时间、质量与成本上的取舍,客户原来遗留的系统,当前国家的法律法规,市场上的技术趋势以及竞争对手与行业标准等都属于当前客户需要考虑的约束条件。

用户的产品质量需求一般称为使用质量需求,其一般包括:合适的性能(Performant)、可用性(Availability)、可靠性(Reliability)、可伸缩性(Scalability)、韧性(resilience)、可观测性(Observability)、可服务性(Serviceability)、安全性(security)、易用性(usability)、可运维性(operability)等,而用户的约束需求包括 用户的业务环境、用户的能力以及用户群的特征等。

团队的质量需求指的是产品开发周期内的质量需求,高质量的代码几个最重要的要素有:可测试性( testability)、可维护性(Maintainability)、可扩展性( extensibility)、可读性( readability)等,而团队的约束需求有:资源预算、上级要求、开发团队的能力、产品规划、此外还有信息安全以及产品运行环境 的约束等。

设计方法论

同设计哲学与设计原则一样,不同的架构设计师有着自己不同的设计方法论,在这里,我认为分布式系统的架构设计方法论可以总结成以下口诀,即分布式9法10功能口诀,如下:

分布式9法:

1
2
3
4
5
6
7
8
9
少读少写少依赖
业务拆业务合
功能拆性能聚
时空换同异换
硬件顺天性
服务需治理
数据保一致
哪都不可靠
事事慎权衡

分布式10项:

1
2
提供 注册 配置 调用 路由
观测 治理 编排 质量 边界

在分布式系统里几乎所有的功能与设计思路都可以用这个“9法10项”口诀来解读,例如:

1,“业务拆业务合”,其理论依据来源于“康威定律”,即:

1
2
> 设计系统的组织其产生的设计等价于组织间的沟通结构。
>

软件架构的拆合关系来源于团队的组织结构。

2,“功能拆性能聚”,在分布式系统里有拆有合,那么拆与合的取舍依据在哪里?这句话讲的就是这个拆与合的取舍关系:依据功能进行拆分,但是也要依据性能进行聚合,拆开后会影响性能的地方最好不拆。

3,“时空换同异换”, 讲的是性能优化的路数,解读开来说即是:时间换空间、空间换时间、同步换异步、异步换同步。例如:采用cache的功能可以减少计算的时间,这是存储空间换时间从而提升性能;采用批处理的方式提升性能,这是减少计算时间;采用异步换同步的方式提升性能也是减少计算时间;减少IO的数据量从而提升性能,这是存储空间换时间;减少IO路径提升性能,这也是网络空间换时间;采用最新的硬件提升性能,这可以是计算换时间,也可以是存储或网络空间换时间。

小结

本文讲述了分布式系统架构设计总决,其可分为设计哲学、设计原则以及设计方法论,从而可以依据这三个方面量化人的设计理念。日拱一卒,功不唐捐,分享是最好的学习,与其跟随不如创新,希望这个知识点对大家有用。另作者能力与认知都有限,”我讲的,可能都是错的“,欢迎大家拍砖留念。

作者简介

常平,中科大硕,DELL EMC 资深首席工程师,曾就职于Marvell、AMD,主要从事Linux内核以及分布式产品的交付、架构设计以及开发工作。

版权申明

本文的版权协议为 CC-BY-NC-ND license:https://creativecommons.org/licenses/by-nc-nd/3.0/deed.zh

在遵循署名、非商业使用(以获利为准)以及禁止演绎的前提下可以自由阅读、分享、转发、复制、分发等。