为什么需要写文档

软件工程师有两大难:1,没有文档;2,写文档。设计文档是用于描述如何去解决一个产品或特性的问题的,好的设计文档可以确保正在做的是正确的事情。

架构设计文档通常又可以分成概要设计文档以及详细设计文档。概要设计文档把握产品架构的宏观方向,而详细设计文档确定微观的代码实现。通常详细设计文档应该由具体负责这个模块实现的人员来完成,只有负责代码落地的人员才最清楚具体的微观问题,其他人员可以参与审阅设计方案、把握正确的方向。在工作中经常会遇到这样的情况:设计人员写完详细设计文档再把文档交付给写代码的人,去要求按这个文档写代码,经常会遇到的矛盾是:负责具体写代码的人觉得这个文档脱离实际没价值,而写文档的人又指责写代码的人员不理解他的意图。 因此,比较合适的方案是 谁负责写代码谁就负责详细设计(这对技术人员的能力要求也较高),其他人员提供检阅与建议,把握风险与方向。

那么如何撰写一个好的架构设计文档呢?这里提出一个常用的架构设计模板,以供参考,如下:

架构设计文档模板

动机介绍

描述需要完成的内容,介绍上下文以及需要达到的目标。

需求分析

以三三制需求分析模型分析客户、用户以及团队的功能、质量与约束需求,首要方针是“价值优先”。

类别 功能 质量 约束
“大”客户 业务目标: 商业成功 业务质量: 多、快、好、省 业务约束: 时间、质量、成本,法律法规,信息安全,技术趋势,竞争对手,行业标准等
“大”用户 业务需求:比如AI模型训练 运行时质量: 精度、线性度、收敛性,性能、可用性、可靠性,可伸缩性、可观测性、可运维性、易用性、兼容性、安全性 使用时约束: 遗留系统,业务环境,用户能力,用户群特征等
“大”团队 功能需求: 基本功能P0 、增值功能P1、潜在功能P2 、可有可无功能P3 、有害无益功能P100 编程时质量: 可扩展,可读性,可测试性,可维护性,可移植性 编程时约束:开发进度,资源预算、上级要求、开发团队能力、产品规划、运行环境

目标非目标

目标与非目标主要是解释本文档做什么与不做什么,定义需要完成的任务与约束边界。

1
2
3
目标:定义本设计文档需要解决的问题以及需要达到的质量指标,是说明需要做什么。

非目标:说明本设计文档的约束,是说明不做什么。

里程碑

计划本身是“无用”的,但是没有计划却是万万不能,通过制定里程碑可以让文档的其他用户知道项目所需要的大概的时间周期。例如,可以按如下格式定义里程碑:

1
2
3
4
开工日期:2020年10月10日
里程碑 1 - 2020年10月30日,完成概要设计文档
里程碑 2 - 2020年11月30日,完成详细设计文档,并且编写完代码
结束日期: 2020年12月30日,完成自我测试、文档、质量保证以及特性交付

设计哲学

产品的设计哲学是产品的宪法,也是产品的灵魂与价值观,是产品的不可违背的最高指导思想,其把握了架构设计的方向,例如:

1
2
3
设计哲学
- 以客户价值为中心
- 以持续创新为竞争力

设计原则

架构交付的是功能需求,但是真正的差距体现在非功能需求(质量与约束),因此可以通过制定设计原则确定产品的非功能要素,设计原则是产品的法则,也是架构取舍的依据,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
设计原则
- 最佳物种原则
- 高内聚低耦合原则
- 可用性原则
- 可靠性原则
- 稳定性原则
- 可服务化原则
- 兼容性、可迁移原则
- 服务化、组件化
- 接口隔离与服务自治
- 用户触达成本原则
- 用户体验原则
- 持续演进原则

设计提案

设计提案可以从三个方面进行考虑:客户想要的、对手怎么做以及自身打算怎么进行,还需要分析每个方案的优点、缺点以及方案取舍的依据。

当前提案

当前方案需要分当前已有的提案、也可包括当前竞争对手的方案,以及客户/用户所期待的方案。

自身提案

提出自身的设计方案,可以提出多个设计方案:比如 提案1,提案2等,确定大的架构设计方向。

提案比较

提出以上方案后,制定技术提案评审表,分析提案的优缺点,确定最终的可选方案。

架构设计

这一部分是最重要、最核心的内容,属于架构设计文档的核心。在确定设计提案后进行概要设计,通常可以采用 4+1 架构设计法完成这一部分内容。如下图:

4+1视图

常用的4+1视图涵盖有物理视图、逻辑视图、处理视图、开发视图以及用例视图,其中与用例视图交叉的部分是描述共同的细节,同时每种视图中又有各自的需求,例如:

  • 物理视图关注安装、部署、升级、运维的需求;
  • 逻辑视图关注架构设计的功能需求;
  • 处理视图关注非功能里的用户运行质量需求;
  • 开发视图关注团队的开发质量需求;

跨团队影响

这里阐述需要的团队依赖以及对其他团队的影响。

详细的交付计划

这里可以以表格的方式,制定详细的交付计划。

开放问题讨论

提出需要讨论的问题。

作者与评审人员

确定作者与评审人员信息,例如:

类目 修改 时间 作者 评审
类目 1 init 2020/09/26 xxxxxxxxx xxxxxxxxx
类目 2 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxx xxxxxxxxx xxxxxxxxxx
类目 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxx xxxxxxxxxx xxxxxxxxxxx

小结

本文提出了一个常用的架构设计模板,希望这个设计模板对大家有用。另作者能力与认知都有限,”我讲的,可能都是错的“[1],欢迎大家拍砖留念。

作者简介

常平,中科大硕,某AI独角兽深度学习首席软件工程师,前EMC 大数据资深首席工程师,主要工作背景在深度学习、流式大数据、云计算、分布式中间件以及Linux内核。

版权申明

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

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

参考资料

[1] https://www.freecodecamp.org/news/how-to-write-a-good-software-design-document-66fcf019569c/

什么是奇点

物理学认为宇宙从无到有始于一个点,这个点叫做“奇点”,它积聚了形成现有宇宙中所有物质的势能,当这一个点的能量平衡被破坏后,宇宙大爆炸发生,从而生成我们现在的宇宙。如果把宇宙比作我们的产品,奇点就是这个产品赖以出现与存在的关键点。

产品创新与奇点理论

一个问题

奇点是这个产品赖以出现与存在的关键点,那么第一个需要回答的问题是:“你的产品的奇点是什么?”。一个企业就是一个产品,那么使命就是这个企业的第一原理点,价值观就是这个企业的奇点,是这个企业赖以存在的关键点。一个软件平台是一个产品,那么以客户为中心可以是这个产品的第一原理点,逻辑基石可以使这个产品的奇点,这个基石是这个产品赖以生存的关键点。

因此将奇点理论应用于产品创新的第一个关键步骤在于 找出你的产品的”逻辑奇点“,比如在AI训练市场,GPU是原来的产品的奇点,是原有的产品赖以依存的关键点,而XPU就是新生的产品的奇点,是新生产品赖以生存的基石,他们的第一原理都是客户的AI训练。

两重境界

创新 = 更好 | 不同 | 新生

  • 更好,指的是市场是明确存在需求的,但是提供的新产品在质量、功能、渠道、价格等方面比原有产品更具优势,是用更好的体验来满足客户的真需求;

  • 不同,指的是差异化竞争,”与其更好不如不同”,不同不只是技术面的不同,而是处处差异化不同,理念、技术、渠道,运营,销售等处处差异化竞争;

  • 新生,指的是 从0到1,从无到有的创造一个新物种,是指用凭空创造出一个新产品来满足客户需求,这种形态的产品要么是颠覆式的创造带来巨大的商业上的成功,要么就是没有真实客户需求的新事物,商业上完全失败。

这里,AI训练芯片采用的是“更好与不同”这两个产品创新方法论,组合原有的技术开拓出新产品,规避风险,满足客户真实的需求。从GPU到XPU 体现的是“不同”的创新理念,而从XPU1.0到 XPU 2.0 再到N.0 体现的是“更好”的创新理念。

因此,这里提出:创新的第一重境界是“与其更好不如不同”,第二重境界是“与其不同不如更好”

与其更好不如不同

生物学家通过分析人与猩猩的遗传基因发现人与猩猩的基因相比较仅有约1.2%的差异,但是就是这约1.2%的差异却造就出两个完全不同的物种以及生态位,猩猩呆树上吃果子,人类败走树上行走平地却成了万物之灵长。决定你是猩猩还是人类的差异只有那约1.2%的差异而已。

“与其更好不如不同”这句话讲的是错位竞争,远古时期要是人类跟猩猩拼命的争树上的好位置,做得再好也不过还是猩猩,也许如今都还在树上跟别的猩猩抢香蕉而已,但是,人类不跟猩猩争抢树上的位置,其不爬树了,开始出走平原,环境因素逼迫其直立行走进而进化成万物之灵长。

与其更好不如不同

同样的道理,在AI训练芯片的产品市场里,如上图之左,GPU是其奇点,它有自己的生态位,有自己的壁垒,也有自己的第一原理点。一款产品要是跟GPU抢占同样的生态位,做得好也还在它的那个圈圈里,后来者再怎么的努力也难以突破它的那个圈圈。然而错位竞争,从GPU到XPU,击破GPU的奇点位置,从新定义自己的那个壁垒与圈圈,却使得产品有了新的生态位,新的可能。

与其不同不如更好

与其不同不如更好

“与其不同不如更好”讲的是在重新定义好自己的奇点后,再进行进化,从奇点1.0到奇点2.0,再到奇点3.0。人类的进化也是经历了猿人类、原始人类、智人类、现代人类这四个阶段,体现的是一步步的更好。而不是一会不同成猩猩、一会不同成大鱼、一会不同成大鸟,这样永远难以出现代人类,或者需要多付出几百万年的代价才能得到现在的结果。

在AI训练芯片重新定义了自己XPU的奇点之后,需要的是以“市场需求”为进化的引力与方向,从XPU1.0到XPU2.0再到XPU3.0,从而才能进化出未来的XPU N.0。

三个步骤

如上面两图里的”奇点下移,破界创新“,依据奇点理论进行创新的步骤是奇点破界的三个步骤:“破坏,外延,重生”

1,破坏,找到产品奇点并加以破坏。产品缺点不是奇点,奇点是产品赖以出现与存在的点,找到它,然后破坏它,类似于使得宇宙奇点能量失去平衡;

2,外延,产品奇点下移,产品边界外延,类似于宇宙大爆炸从而造成宇宙边界外延;

3,重生,重构产品奇点,形成新的产品体系,类似于新宇宙的形成。

以AI训练芯片的创新为例,这里只涉及技术面的创新,销售、渠道、运营、管理、商业模式等方面的创新不在本文范围。可以知道的是目前市面上的AI芯片的最大竞争对手是GPU,对其应用奇点创新思维模型的步骤有:

1, 破坏,找出产品奇点,然后破坏它的奇点。例如,我们知道GPU的赖以依存的关键点有:提供图像视频处理功能,依赖于图像视频横向扩展出AI训练功能,依据初代版本时间点的硬件特性进行软件的设计;

2,外延,产品奇点下移,破界,新的产品边界外延。针对以上GPU的三条关键点,提出AI芯片的新奇点:去除图像视频的处理功能简化软硬件的设计,从而节约成本。抓住技术进步的福利,去除历史包裹,依据当前最新的软硬件特性进行产品设计,使之更符合现代的市场需求;

3, 重生,最后更新的、更具有成本竞争力以及技术竞争力的、针对AI训练而实现的新产品”XPU“诞生。

这一套创新思维模型的关键点在于找出原有的产品赖以出现以及存在的“奇点”,然后破界重生。

阿基米德产品思维模型

阿基米德产品思维模型灵感来自于阿基米德的一句话:”给我一个支点,我可以撬起地球。“,因此我定义它为阿基米德产品思维模型,奇点创新思维模型是 阿基米德产品思维模型的子集,如下图:

在阿基米德产品思维模型里产品是一个圆,圆内的三角形是打造产品所需的技术,在产品圆里除了技术三角、还补充了企业文化、企业制度以及组织结构这三个要素,在圆之外还有奇点、壁垒、价值网以及一个支点、一个杠杆、一个作用力。

在这个模型里,支点可以认为是“以客户为中心”,关键能力可以是团队也可以是资本,还可以是二者的组合,产品离客户越远,需要的作用力就越大,产品离客户越近,需要的作用力就越小。企业文化、制度、组织关系是产品的关键要素,但不是决定要素,技术才是产品打造的决定要素,其面积占产品圆的近2/3,狭义上的技术指的是技能,但这里的技术不是,它是广义的,其涵盖:大势、理念、方法论、技能、工具与边界。

小结

本文结合奇点理论讲述了产品的创新思维模型,日拱一卒,功不唐捐,分享是最好的学习,与其跟随不如创新,希望这个思维模型对大家有用。另作者能力与认知都有限,”我讲的,可能都是错的“[1],欢迎大家拍砖留念。

作者简介

常平,中科大硕,某AI独角兽深度学习首席软件工程师,前EMC 大数据资深首席工程师,主要工作背景在深度学习、流式大数据、云计算、分布式中间件以及Linux内核。

版权申明

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

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

参考资料

[1]《第二曲线创新》 李善友

导言

架构师是业务与产品之间的桥梁,其应该具备技术与产品的商业意识并且需要有将技术转化为产品的能力。而当前软件架构师在工作过程中往往离不开开源的软件项目,因此经常面临两个问题:”什么是产品?“以及“如何将一个开源的软件项目产品化?”

一套科学技术分析方法的背后有一定有着深刻的理论基础和哲学背景。找到了这套技术分析的源头,才能从本质上把握这套技术,看清其全貌,明了其长处和短处,这样在具体应用中,才能得心应手,提高胜算,并不断的丰富和发展这套技术。基于此,本文提出了一套如何将开源软件项目产品化的方法论。

然而理论与实践是相互作用的,宏观角度知道方法论之后还需要从微观上进行实践,不然就如同知道很多道理却过不好这一生,知道很多原则却写不好代码一样一样的。

什么是产品

产品的定义:

产品是指做为商品提供给市场,被人们使用和消费,并能满足人们某种需求的任何东西,包括有形的物品、无形的服务、组织、观念或它们的组合。

从产品的定义中我们可以看到以下几点:

  • 属性:有形的物品、无形的服务、组织、观念或它们的组合,因此产品自带有形或无形属性;

    • 有形属性:狭义上产品是被生产出的能满足人们需求的具有物理属性的有形的物品。在绝大多数人的认知里,对产品的理解是停留在这一层次的,产品具有看得见、摸得着的物理形态;
    • 无形属性:广义上产品是可以满足人们需求的任何东西,无形的服务、组织、观念或者它们的组合也是产品。广义上的产品定义对人的认知有更高的要求。服务是产品、企业是产品、团队是产品、认知是产品、本文是产品,这些东西的组合也是产品。万物皆产品,它目前不是产品,那只是没被产品化、或者不在对的时间与空间里;
  • 价值:产品首先是商品,其具有交易的价值,能提供给市场,供人们使用与消费,所有不能交易的东西不在产品的定义范围之内,因此这里可以推导出产品是具有价值的,没有价值的东西不属于产品的范畴;

  • 交易:产品是做为商品提供给市场,被人们使用和消费,因此具有交易的价值,能满足市场的某种需求;

因此基于以上的产品的公理化定义以及定理化推导得出产品的第一性原理定义:

1
产品 = 属性 + 价值 + 交易

从以上公式中可以认为产品是以属性为要素,以价值为连接,以交易为目的,属性又可分为有形属性与无形属性,二者之间有时候并不是割裂的,价值是能满足人们的某些需求,是物品与货币之间的连接关系,交易是产品生产的目的。

然而这些都是教科书式的 定义,对产品的认知到这一层次已经可以超越绝大部分人,但它也只是停留在”产品“层次,而不是“作品”,更不是“艺术品”。

在我看来 产品 还是具有灵魂的,产品是由人创造的,其自然会带有人的思想、人的创造、人的理念在里头,宗师与学徒画同样的一幅画,虽然东西都一样但是那个味道往往是不一样的。因此,要理解一款产品还需要理解其背后的人的设计理念,在此,我给产品注入人的灵魂,即“理念”,从而进一步扩展产品的第一性原理:

1
产品 = 属性 + 价值 + 交易 + 理念

开源软件是信息的载体,其表现形式是具有无形的信息属性,是作为计算机程序的形式而存在的,要将开源软件产品化就需要将开源软件的属性价值化、可交易化以及注入人的设计理念。

如何将一个软件产品化

价值与交付

如何将一个软件产品化回答的是“How” 的问题,在此之前还应该搞明白“Why”的问题,一个软件产品或者其特性为什么需要做也有一套方法论,这里我称之为 “产品交付之双轮驱动模型”(如下图):

价值与交付

在这个双轮驱动思维模型里有以下几个原则:

  • 以客户价值为前轮,前轮把握方向,解决的是需求探索、价值确定、特性探讨以及价值精炼的过程。首先是以客户价值为导向输入客户需求、但是这个需求还需要去伪存真、去粗纯精、过滤提炼,才能作为产品交付轮的输入,而不是只要是客户需求,不管是真需求还是假需求、也不管是有价值的、还是无价值的都全部输出到产品交付轮,无效的消耗产品交付资源;
  • 以产品交付为后轮,后轮提供驱动力,解决的是开发、测试、运维以及获取客户反馈,再根据这个客户反馈的结果作为开发的输入的过程。在产品交付轮中很重要的一环是“反馈“,其角色是作为客户与交付之间的桥梁,开发需要依据”客户反馈”作为输入,而不是自个闭门造车;
  • 客户价值又可分为主动式客户价值与被动式客户价值,获取客户需求的方式也需要合理取舍:

    • 主动式客户价值:有些客户”久病成医“,非常清楚自个痛点、难点、挑战点在哪里,也非常清楚自个需要什么样的解决方案可以药到病除,从而可以精确的输出自我的需求。这种客户对产品交付来说可遇而不可得,成本最低,需求最精确;
    • 被动式客户价值:这种情况下,光是在那里等待,从而期望客户能给出明确的需求作为输入,那是缘木求鱼、刻舟求剑,效率也非常低下。如同医院里的医生给病人看病一样,绝大多数客户其实只能知道表征,而不知道根因,因此就需要由产品交付轮以客户专家的角色提出解决方案,作为客户价值需求输入给客户,再看客户的使用效果得出反馈,再依据这个反馈调整解决方案。
  • 在双轮驱动模型里,二者谁都离不开谁,不是厚此薄彼的关系,而是二者互相协作从而推动产品往商业成功这个目标前进的关系;

  • 先有买家需求再有产品交付,而不是先有产品交付再找买家需求,需要明晰这个先后关系,为客户找出差异化需求才是产品交付的本质,寻求差异化、避免同质化,才是真正的以客户为中心。

因此,在将一个技术产品化之前,先花几分钟时间问问其价值在哪里,为什么需要做这个,这一点很重要,要能区分客户要的是能马上就能解决痛点的止痛片还是可有可无的无关紧要的维生素,从而以此进行任务排序,明晰产品交付与客户价值的双轮驱动关系,要能清楚的理解“以客户为中心”的价值理念以及让产品的获得“商业成功”的终极目标。

技术产品化

通常来讲开源软件的产品化可以从价值、交易以及理念这三个方面进行。价值:可服务化、无形化有形、价值竞争,交易:可度量化、个性标准化,以及融入人的设计理念:复杂简单化等。

可服务化

可服务化指的是从技术实现上支持可服务化,ToB产品常常是半产品半服务的,而且一般会签约服务质量保证协议SLA,因此除了团队需要有替客户解决问题的能力外,还需要从技术与流程上支持可服务化,其中包括:

  • 可运维性:易用的部署(步骤量化)、升级(AB测试、in-place、replace、rolling-back等)、数据迁移、自动化运维支持等。在一个产品的全生命周期里,开发也许只占20%不到的时间,而将近80%的时间都需要运维,因此需要拿出近4倍比的开发重视程度,重视可运维的设计与实现;
  • 可观测性:可观测性主要分为四大类: 监控、告警、日志、追踪;
  • 可操作性:支持远程接入、开放服务接口、后台管理UI、CLI、特性参数配置开关;
  • 健康管理:健康检查支持、健康报告支持、自动提交故障问题单支持;
  • 安全性:安全性是企业级产品必备,数据保护、密码安全、连接检查、LIB库授权协议等;
  • 多租户:多租户可以支持多团队、多部门小规模部署,进行业务隔离,也是非常重要的企业级特性;
  • 可视化:提供易用的用户UI、CLI;
  • 可支持:如何指定进行客户支持规则?如何升级成工程师团队介入提供服务定位问题或者排除问题?

当看到以上类目,脑海里就能闪现出需要怎么去实现这些以及用什么组件可以最佳实践的快速完成交付,而不是停留在概念的阶段,那才算对可服务化有了自己的理解。

无形化有形

无形化有形指的是将无形的软件硬件化或者云化,单单一个软件包是难以让用户买单的,需要把它硬件化,打包到服务器里以有形产品的形态销售出去,或者云化后以服务的无形形态销售出去。

价值竞争

价值竞争指的是“参与到客户的购买周期中,在每个阶段为客户创造价值”[3],从单纯的销售产品到提供整套生态化的解决方案。单纯的依靠销售产品往往已经难以给客户提供差异化的价值,并且也会面临低利润的同质化竞争,那么这个时候就需要更进一步的提供生态化的解决方案,针对行业需求做端到端的全生态化的解决方案。

生态化的解决方案化能给客户提供差异化的价值关系。比如,一份药品在药店里只能卖30块,而且只是一次销售无法挖掘后续价值。但是到了医院就不一样了,其依据客户的”恐惧“为刚需的基石,提供一整套的类生态化的医疗解决方案,从挂号预约、望闻问切、到各种仪器设备过一遍、再到开出药方、再依据客户的反应效果把这个过程再来几遍,因此在药店里30块钱的药,在医院里就能卖到 300块、3000块,获取十倍、百倍、千倍利润。

PS: 做生意要走正道,有良心的医院“以客户为中心”药到病除,无良医院“以利润为中心”无尽压榨客户,祝早日倒闭。

可度量化

可度量化指的是质量要可以量化,可预测的业务指标(比如AI训练里的精度、加速比、收敛时间、训练次数等)、性能、可靠性、可用性、可伸缩性、稳定性、容错性、可测试性等,这些很抽象的指标要能量化。在产品功能同质化的场景下,质量是最重要的差异化竞争力。

业务性能、可靠性、可用性、可伸缩性这几者之间页互相制约,质量与成本、时间也互相制约,同时在云化的场景下客户又有SLA要求,不满足SLA要求的服务,除了要赔钱,还严重影响商业信誉,因此质量指标之间也需要合理取舍。

个性标准化

个性标准化指的是将个性化的、“DIY”化的开源项目转成标准化的、可复制的、可量化的,同时依据资源的规格约束进行标准化,比如依据服务器规格、虚机规格,机架规格等进行标准化,例如AI服务器的配置就需要定义CPU、内存、磁盘、带宽以及训练卡的标准的规格,这样才能提供可预测的性能、可预测的加速比等质量指标,再比如云端场景下的服务监控,除了定义指标的名称之外,还需要定义监控指标的类型、故障码、输出的标记以及对应的处理措施等,所有的这些都要能标准化、可操作性化。

复杂简单化

复杂简单化指的是把复杂的体验简单化, 抽象及简化API、量化的安装步骤、高内聚低耦合的设计、易用的UI等,这里又涉及到产品设计哲学、人类的心理学等,也跟人的设计理念相关。

小结

本文以方法论的形式解读了软件开发过程当中经常会遇到的两个问题:”什么是产品以及如何将一个开源的软件项目产品化“,讲的是“无用”的知识。

日拱一卒,功不唐捐,分享是最好的学习,与其跟随不如创新,希望这个知识点对大家有用,另作者能力与认知都有限,”我讲的,可能都是错的“,欢迎大家拍砖留念。

作者简介

常平,中科大硕,某AI独角兽深度学习首席软件工程师,前EMC 大数据资深首席工程师,主要工作背景在深度学习、流式大数据、云计算、分布式中间件以及Linux内核。

参考资料

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

[2] https://baike.baidu.com/item/%E4%BA%A7%E5%93%81/105875

[3] 《价值竞争:以客户为中心的销售转型》 - 付遥

版权申明

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

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

前言

分布式系统是一门讲究实践的软件工程,只有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

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