云端的兴起促使人们以自下而上的视角重新看待应用程序的基础架构——进而催生了小型、无状态、隔离和容器化的微服务,和可独立扩展并移植的无服务器函数。反过来,将应用程序打包到容器中,可以实现大规模的部署编排和 DevOps 风格的自动化。云原生服务本身并不是解决方案,而是要成为高度模块化的客户端应用程序的可扩展构建块。
云原生架构中隔离的“无共享”设计是对传统的单体软件实现的回应,后者将自身的功能紧密耦合到了数据库上,因此必须作为一个整体来扩展、分布和进化。
但是,企业仍然需要符合自身环境需求、互相之间紧密关联的各种解决方案来支持自己的核心使命。将应用程序简化为离散的“包”和隔离的“负载”是很容易的,但产生价值的是跨解决方案元素的端到端业务逻辑,这些方案元素可以是基于容器、VM 或是基于服务器的。除非你是主流 IT 供应商或云托管厂商,否则基础架构只是实现目标和管理成本的一种手段。
在最近的 InfoQ 演讲 " 超越微服务:流,状态和可扩展性 " 中,Gwen Shapira 指出了在云原生负载之间建立上下文的困难之处——“我想念状态,因为有时我的规则是动态的。我无法硬编码这些规则,我必须在某处查找它们。有时,我的事件包含其中一些我需要的数据,比如说一个 ID,但没有包含他们需要的那些数据,因此我必须在某处查找它。有时我必须联接多个事件。”本质上来看,无状态云原生服务之所以可扩展,是因为它们将状态和信息管理问题推给了使用它们的客户端应用程序。
能快速有效地访问信息(也就是建模的、可寻址和持久的实体)的应用程序有着更高的智能化程度,并且应用程序之间的“共识”促进了互操作性、协作和流程自动化。每个人都希望能以数据为中心,但是没有人希望回到臃肿且紧密耦合的单体架构上。这种明显的矛盾需要得到解决。缺乏对有状态云原生应用程序行为的支持,是扩展云用例道路上的一大障碍。
这里要明确的一点是,“无状态”并不意味着没有状态。这是一种夸张的表述。微服务和无服务器函数通常会保持某种状态,往往是一份配置文件和它们离散活动的日志。
通常,无状态应用程序不会在请求或事件之间保留任何客户端应用程序状态。“无状态”解耦了云原生服务与客户端应用程序,以实现所需的隔离。微服务和无服务器架构的宗旨明确禁止保留会话状态或全局上下文的做法。但是,尽管状态不在容器中,但它还是必须处在某个地方。毕竟,无状态函数要将状态作为输入。应用程序状态没有消失,它只是移动到了其他位置上。这里的代价是每次执行时都必须重新加载状态以及所有全局上下文。
无状态在实践中带来的后果是网络使用量的激增,从而带来了大量零碎的、带宽和 I/O 密集的进程间通信。这是有代价的,体现在云服务支出的增长,以及客户端应用程序的延迟与性能影响。
分布式计算作为一种久经考验的设计原则已经弱化了数据重力的约束,迫使应用程序与越来越多地与外部数据源集成在一起。云原生架构则完全颠覆了规则——现在是数据传递给函数。应用程序被从内至外翻转了过来。对于云原生服务而言,状态和信息管理已经外部化了——正所谓“Intel Outside”。
分离数据和函数是很好的设计,但是没有针对分布式域中共享状态和架构的应用程序层抽象,开发人员就要针对每个微服务,对这些问题进行一次性、点对点的处理,这种操作是不可扩展的。
传统的 3 层应用程序正在迅速消失。隐式的云原生模型要抽象得多。从概念上讲,应用程序正在转变为一组带有关系的分布式数据源和功能的集合——也就是一幅“应用程序图”,它处理起来则是一条管道。这听起来可能很简单,甚至像田园诗歌般惬意,但是如何将所有这些离散元素以一致的端到端流程组合在一起,而又不用将它们之间的关系硬编码为一个 CRUD 大球 呢?
尽管最近出现了很多关于 Kubernetes 中有状态应用程序的文章,但它们大多讨论的是部署、配置和管理数据库的存储原语的主题,而不是应用程序层所关注的状态重建和信息管理主题。共享内存和逻辑数据访问领域出现了一些很有想法的方法,例如 UC Berkeley 的 Anna db 项目 和 Zhamak Dehghani 提出的 分布式数据网格 架构。但是,它们一般不包含用于跨服务推理的一致性层。在以数据为中心、事件驱动的应用程序中将松散耦合的云原生服务连接起来,以融合微服务和无服务器函数的解决方案,需要的不止是让应用程序高效访问状态。
为了实现分布式解决方案元素与异构解决方案元素之间的互操作性,需要用某种方式将它们的不同架构映射到更高级别模型的共享概念、数据类型和关系上。在这样的需求推动下,将多个数据源聚合在单个 API 下的 GraphQL 流行了起来。GraphQL 在战术上是很方便的,但是其范围和功能很有限——它实际上只是一组特定的集成服务上的静态、分层数据模型(在任何层面上都算不上是一个图)。就像被扔掉的脚本一样,它是一种一次性的手动解决方法,不能提供更好的透明度、复用性、自动化能力或治理能力。
为了解决端到端问题,并实现 IT 生产力提升和业务敏捷性增强等战略目标,我们需要的是更强大的抽象,而不是一个瘦实体服务。它需要为负责开发跨企业孤岛、IT 层和生态系统合作伙伴的企业范围解决方案的开发人员服务,为具备良好可读性的代码与依赖项,以及清晰的组合提供支持。它必须是一个灵活、可扩展和适应性强的模型,以适应各种变化,并随着时间的推移而进化。
在这样的背景下,人们重新拾起了图知识库这个起源于 1970 年代的专家系统概念,以支持复杂分布式环境中的高层抽象。
根据维基百科的介绍, 知识库 (KB)是一种用来显式存储复杂信息的技术,它是一组事实及它们与其他事实和规则(也就是一个图)的松散耦合(而非强制性的)的集合。“知识库的理想表示是一个具有类、子类和实例的对象模型(在人工智能文献中通常称为 本体 )。”这一术语是为了和之前的常规数据库区分开来而出现的,后者一般来说是自然分层的。图知识库是原始的 NoSQL 数据库!
图是灵活的、可扩展的和可适应的,是用来对复杂的现实世界域建模的理想数据结构。此外,图具有众所周知的数学特性(关联性、邻接性等),并支持很多计算优化方法(最快路径算法等)。
专家系统 将知识库与推理引擎结合在一起,后者将利用图对象模型来解决复杂问题。“知识库提供有关世界的事实和规则……推理引擎则可以推断出新的知识。最常见的是,它可以采用 IF-THEN 规则的形式,再加上前向或后向链接方法。”早期的 基于知识的系统 (KBS)的作用范围有限——它们一般用来回答特定的科学和医学问题。它们模仿了人类的决策过程来自动化处理专家任务。但它们不是事务性的,计算任务被固定在单台计算机上,并且描述一个复杂域所需的存储资源对当时的技术来说太庞大了。
随着互联网的兴起,人们对知识库有了新的兴趣;因为人们普遍意识到,分布式信息源已被链接和索引起来,因此可以轻松地进行导航和查询。Tim Berners-Lee 爵士等人在“ 语义 Web ”中应用了这些概念,语义 Web 通过术语和数据结构的标准化实现了信息概念之间显式标准化的关系,从而改善了发现、推荐和分析能力。十年后,谷歌发布了其 知识图谱 ,其愿景是建立一个丰富的信息对象网络——“不是字符串的事物”。
云扩展了互联网的使用范围,超越了以人为中心的 Web,并公开了一众服务和功能,让系统可以通过 API 访问它们。知识库再次成为一种理解复杂性的方法。eBay 最近宣布了一个知识图项目—— 使用知识图管理 eBay Vast 服务架构 。
eBay 图中的建模关系为他们提供了复杂和分布式环境的整体表示。但是,与基于语义 Web 的技术一样,它通常侧重于数据发现和分析,而不是系统的互操作性和自动化,这也是 OLAP 与 OLTP 的古老分歧的体现。
要真正启用云原生应用程序层,需要对图知识库进行概念的扩展;将众多模式映射到一个统一的更高级别的模型(也就是有界上下文的并集)是不够的。为了使数据在服务之间无缝地流动,需要使用丰富的分布式对象声明式模型来处理云原生(“ 12 要素 ”)问题,包括:发现(地址、唯一 ID 等)、连接性(端口、密钥、验证等)和语法(协议、格式)。
此外,知识库应该为参与的元素(不仅是瘦描述符和一堆 YAML 配置)建模接口和软件协定。如果应用层正在协调部署和配置,则知识库还必须针对基础架构需求(也就是计算、存储和网络)、约束(依赖项、affinity 等)、应用程序生命周期管理操作(启动、停止、扩展、移动等)和目标主机端点来建模。类似的要求也适用于工业物联网,这种网络必须实例化、监视和控制众多传感器和执行器,以实现智能制造、智能城市和智能供应链。
结果将诞生一系列分布式解决方案元素组成的的丰富模型,这些模型可以灵活地组合成更高级别的服务,并可以在事件驱动的数据流程中链接起来。知识库将提供共享的域语义和元数据,以实现运行时自动化和基于策略的管理。通过抽象高级别的域和低级别的技术细节,图知识库可以作为一类新的实时分布式应用程序的基础,并用于“上下文即服务”。
总结一下:
实现这类基于图知识的系统的关键是一些重要的设计注意事项。云原生应用程序的设计对运营会产生影响,因为它迫使开发人员处理所有关于数据争用、一致性和安全性的问题,这些问题以前是由单体负责为每个参与的微服务和无服务器函数管理的。它暴露了互操作性、状态管理和消息传递方面的问题,这些问题现在必须由开发人员明确处理,这正是分布式系统在技术上如此复杂的原因所在。为了使这个 IT 领域自动化,知识库必须 虚拟化 环境。
如上所述,图知识库是对分层数据库和命令式编程的一种回应。图知识库显式化了域,让域更易于检查和导航。它们的机器可读数据结构和分类模式天然支持声明式语言进行映射,而不是单独编码对象内部和对象之间的所有关系。
声明式建模提供了一种标准化解决方案元素的方法;对象被自我描述为指向知识库中共享域概念、类型和策略的一组指针。这种高级抽象实现了针对异构元素的通用方法。它创建了一个一致性层,在其中可以发现、组合、协调、配置和管理各种对象,将这些对象视为同样的存在。底层实现的复杂性(连接、通信、语法等)可以从开发人员那里抽象出来,让他们可以专注于组合和应用程序逻辑。互操作性问题由语言运行时处理。
在运行时,图知识库可作为机器可读的唯一事实来源,用于自动化端到端 IT 和业务流程。但是,知识库的扩展角色(用于建模分布式系统域)意味着人们必须重新设计最初构想的,以查询为中心的推理引擎,以加入对协调和状态管理(命令和转换)的支持。
这种声明式建模方法将对象的模型与实现对象所需的面向消息的中间件(MoM)功能区分开来。这些函数可以通过图知识库中的“类型”来附加,并可以在运行时编排。将类型映射到领域概念,使基于图知识的系统能够驱动基于模型、事件驱动和策略控制的自动化过程,从而实现以数据为中心的实时行为。这使基于知识的图系统更接近于应用程序图的函数式组合视图,但是状态管理和消息传递问题仍然需要得到解决。
有状态与无状态的争论是无意义的二元对立;组织希望用状态来理解事件、自动化决策并优化流程。除了数据结构外,图知识库的基础设计是像数据库一样来存储信息。但是,用于无状态分布式应用程序和 Web 级流程的数据服务需要一个不变的持久模型。
不变性是一种将信息存储为针对具有唯一标识符的持久实体的带日志事件流的方法。与传统数据库那样通过替换值来“更新”状态的做法不同,现在事件是 " 插入(insert)",用来创建一个链接的历史记录。对象或应用程序的状态是从不可变存储的历史记录中预测的;状态是从事件中派生的。
这种方法算不上什么全新的方法,也没那么玄妙,只是和过去的方法略有区别。它是基于分类帐的会计处理和全球银行系统的基础。银行帐户这个概念具有唯一标识符,它的当前状态,也就是银行余额,是一种从借记和贷记活动历史中计算出来的要素。
不变性将状态与对象区分开来,以专注于可靠地记录转换状态的事务。不变性将计算状态的责任转移到运行时,从而让开发人员更容易推理事件驱动的应用程序。
不可变对象天然支持事务的异步与并发处理、多步操作和长期运行的工作流。它们为持久性实体提供了一个名称空间,这些持久实体可以存储参与服务的中间结果、充当流程状态的集合,并提供日志(事务跟踪或历史记录)以备调试和审核。
声明式模型和不可变对象共同为实时分布式应用程序的协调提供了基础支持,但是它们并不能解决异步环境中缺乏保证的问题。
解耦的应用程序会将网络插入所有解决方案元素之间,这会导致网络延迟和故障。连接服务的分布式应用程序必须适应后期的响应和非响应,以确保安全性和弹性。尽管许多 Web 和移动应用程序对一致性的要求可能较低,但企业级应用程序往往依赖“ 正确和当下 ”。为了确保正确性,开发人员必须替换掉丢掉的数据库保证(ACID)。
与分布式系统中的其他内容一样,类似事务的语义也被提升到了应用程序层。不变的持久性提供了持久的实体和权威的历史记录,但是不可靠的网络通信需要消息传递保证,以确保请求及其效果不会重复。接收者可以预期自己会“至少一次”收到消息。
已有的计算机科学原理“幂等”解决了这个问题,该原理允许请求操作重复,而不会重复其效果。一个最合适的例子是常见的电梯按钮,有人不耐烦地反复按下电梯键,并不会让电梯多次到达该楼层(或让其尽快到达)。具有幂等性的“至少一次”消息传递语义能够模拟出“恰好一次”的消息传递保证,以支持用于配置重试、超时和补偿的业务逻辑。
幂等将关注点分离开来;以前是数据库事务语义的内容,现在可以在应用程序层工作流中模仿一大部分。这就产生了一个图知识库,通过提供更高级别的控件和管理(低于 ACID 但高于 BASE)来原生部署为 NoSQL,以降低最终一致性的不确定性。基于图知识的系统可以是云原生的!
结合使用时,不变的持久性和可靠的幂等消息传递可以共同在固有的非确定性分布式系统上支持确定性的抽象,以确保图知识库是一个稳定且权威的计算环境。
通过扩展图知识库以建模分布式系统域,并对其运行时引擎进行工程改造以支持不变的持久性、异步和并发的方法,以及可靠的幂等消息传递,我们就能创建一种新型的信息系统,这种系统专为应对当今的 IT 挑战而生。
图知识系统的概念扩展涵盖了云原生的思想,可部署为云原生解决方案,并为努力交付智能、可连接的适应性企业应用程序的开发人员提供了他们急需的支持。这里的目的是为共享的企业模型和元数据提供直观的开发人员界面,以实现高效、高性能和可扩展的上下文即服务。
它提供了 “好高骛远的”API 网关 的一种替代方案,后者会演变为 膨胀且不透明的企业服务总线 ,或称“上帝”服务。基于图知识的系统具有天然的可检查性和开放性。声明式建模将模型与实现清晰地分离开来,并且类型化的对象支持事件驱动的无服务器函数的后期绑定,从而在动态管道(即数据流过程)中执行所需的任何中间件服务。同样,服务组合可以调用编排服务以跨一组服务进行协调,从而实现多步操作或端到端流程。这样以来,图知识库就可以在无需规定实现的情况下实现基于模型、事件驱动和策略控制的编排和自动化。相反,持久实体通过一个中央协调器的跟踪和管理来支持编排的灵活性。简而言之,图知识库的结构经过优化,可支持无状态和事件驱动的无服务器函数。
当然,要简化本质上很复杂的事情是很困难的。但是,只有解决了分布式应用程序的基本建模、处理和通信难题,业界才能让有状态云原生应用程序的设计、部署和管理变得切实可行。
随着 IT 环境变得愈加复杂,业界开始意识到了对更高级别抽象的需求。云原生应用程序必须从根本上简化。应用程序开发人员不想关心容器编排或网络连接微服务的方式,也不想了解分布式系统工程的所有变数。
本文所述的基于图知识的系统为下一代平台的设计提供了一种可能的方法。它们为整个企业用例提供了确定性和一致的开发人员抽象,以为复杂的分布式系统和应用程序带来秩序。
Dave Duggal是 Enterprise Web 的创始人兼首席执行官。Enterprise Web 是一家总部位于纽约的软件公司,提供混合集成和自动化应用程序平台。Duggal 是一位经验丰富的业务领导者,当行业专注于基础架构层时,他看到了应用程序层所面临的挑战和机遇,意识到应用层需要抽象日益分散、异构化和快速发展的 IT 资产中不断增长的复杂性。他创立了 Enterprise Web 来推动业务的数字化。Duggal 构思并设计了一个屡获殊荣的平台,该平台已获得 9 项美国专利。他撰写了许多学术论文、书籍章节和行业文章;他还偶尔会写博客。Duggal 是行业会议(例如 Layer 123、Structure、CloudExpo、SemTech、EDW、GoToCon、TM 论坛、BPMnext、IWPC 和电信理事会)的定期演讲者,并为许多标准组织(例如 ETSI、TMForum、工业互联网联盟)做出了贡献。他的 LinkedIn , Twitter 。
Graph Knowledge Base for Stateful Cloud-Native Applications