@levinzhang
2020-05-25T23:41:49.000000Z
字数 7437
阅读 664
by Bilgin Ibryam
数据网关类似于API网关,但是它关注数据访问方面。数据网关提供了抽象、安全性、可扩展性、联邦以及契约驱动开发的特性。目前,有很多类型的数据网关,从传统的数据虚拟化技术,到轻量级的GraphQL转换器、云托管的服务、连接池以及全开源的替代方案。
应用架构的演化已经将前端和后端进行了分离,而且进一步将后端分解成了独立的微服务。
现代的分布式架构带来了对API网关的需求,并且帮助普及了API管理和服务网格技术。
如今,围绕12要素(12-factor)应用程序、微服务以及微服网格有很多令人兴奋的事情,但是在云原生数据方面,这样的事情却不太多。关于云原生数据访问的会议演讲、博客文章、最佳实践以及专门构建的工具都比较少。出现这种现象的一个主要原因在于,大多数数据访问技术都是在一个偏爱静态环境的栈中架构和创建的,而不是具有动态特性的云原生和Kubernetes环境。
在本文中,我们将会探索不同类型的数据网关,从更加单体化的方案到专门为云和Kubernetes设计的方案。我们将会看到微服务架构所引入的挑战是什么,数据网关如何补充完善API网关,从而解决这些Kubernetes时代所面临的挑战。
我们首先看一下,在过去的十多年间管理代码和数据的方式发生了什么变化。我依然记得我刚刚开始职业生涯的时候,我们使用Servlet、JSP和JSF创建前端。在后端,EJB、SOAP、服务器端会话管理是当时最先进的技术。但是随着REST的引入和Javascript的普及,事情发生了很大的变化。REST通过统一的接口和面向资源的请求帮助我们解耦前端和后端。它通过将所有客户端会话状态转移至客户端,普及了无状态服务并使响应缓存成为可能。这种新的架构为现代业务的大规模可伸缩性需求提供了解决方案。
通过微服务运动,后端服务也发生了类似的变化。将前端解耦出来还不够,单体后端必须解耦到限界上下文中,从而实现独立且快节奏的版本发布。这些都是架构、工具和技术在业务需求的压力下如何进行演化的例子,而如今的业务需求则是快速交付可以在全球范围扩展的应用程序。
这把我们带到了数据层。微服务存在的动机之一就是每个服务都有独立的数据源。如果你让服务都访问相同的数据的话,那么迟早会引入耦合并且会限制独立的可扩展性或版本发布。随着微服务的发展,数据层不仅是单独的数据库,而且还是异构的数据库,每个微服务都可以使用适合其需求的数据库类型。
应用架构的演化带来了新的挑战
尽管将前端和后端解耦以及将单体切分为微服务带来了预期的灵活性,但是它也带来了前所未有的挑战。在随后的几年中,服务发现和负载均衡、网络级的弹性以及可观察性成为了技术创新的主要领域。
与之类似,为每个微服务都创建一个数据库,所带来的自由以及不同数据存储的技术选择也成为了一个挑战。随着数据的爆炸性增长和数据访问需求(不仅服务要访问数据,其他的实时报告和AI/ML也要访问数据)的变化,这种情况越来越明显。
随着微服务采用的日益普及,运维这样的架构变得越来越困难。尽管让每个微服务独立听起来很不错,但是这需要我们以前所不需要和具备的工具及实践。这带来了更高级的版本发布策略,比如蓝/绿部署、金丝雀发布、灰度发布(dark launch)。随之而来的就是故障注入和自动恢复测试。最终,这产生了先进的网络遥测和跟踪技术。所有的这些形成了一个完整的层,位于前端和后端之间。这个层主要包括API管理、服务发现和服务网格技术,但是也会包括跟踪组件、应用负载均衡以及各种各样的流量管理和监控代理。甚至包括像Knative这样的项目,这些项目具有根据网络活动来驱动激活和扩展至零(scaling-to-zero)的特性。
随着时间的推移,很明显的一点在于,为了快节奏地创建微服务并运维大规模的微服务,我们需要一些以前用不到的工具。以前由单个负载均衡器完全处理的事情必须要由一个新的高级的管理层来替代。一个新的技术层、一组新的实践以及一个对其负责的新用户组应运而生。
微服务会在两个维度影响数据层。首先,它要求每个微服务都有一个独立的数据库。从实际实现的角度来看,这可以是独立的数据库实例,也可以是独立的模式和表的逻辑分组。这里的主要规则是,微服务只能访问自己的数据集。所有的数据都是通过拥有该数据的微服务的API或者事件来进行访问。微服务架构影响数据层的第二个方面在于数据存储的增殖扩散(proliferation)。与微服务可以使用不同的语言编写一样,这种架构也允许每个基于微服务的系统使用多样化(polyglot)的持久层。有了这种自由,某个微服务可以使用关系型数据库,而另一个微服务可以使用文档数据库,而第三个微服务完全可以使用基于内存的键-值存储。
虽然微服务给了我们这些自由,但是它同样是有代价的。事实证明,运维大量的数据存储是有代价的,现有的工具和实践并没有为此做好准备。在现代数字世界中,仅仅以可靠的形式存储数据是不够的。数据只有转化为真知灼见才是有用的,为了实现这一点,它必须能够以受控的方式被很多人来访问。AI/ML专家、数据科学家、业务分析师,他们都希望深入挖掘数据,但是面向应用的微服务以及它们的数据访问模式并不是为这些饥渴的数据需求而设计的。
API和数据网关在不同的层提供了类似的功能
这也就是数据网关能够发挥作用的地方了。数据网关与API网关类似,但是它理解并作用于物理数据层而不是网络层。如下是数据网关与API网关不同的几个领域。
API网关可以隐藏实现端点,并且有助于在不影响服务消费者的情况下升级和回滚服务。类似的,数据网关可以帮助抽象物理数据源及其细节,有助于在不影响数据消费者的情况下变更、迁移和废弃数据源。
API管理器基于HTTP方法保护资源端点。服务网格基于网络连接进行安全防护。但是,它们都无法理解和保护通过它们的数据及其形态。而数据网关能够理解不同的数据源及其数据模型,并对它们进行操作。它能够对每个数据行和列执行RBAC,并且在必要的时候过滤、混淆和无害化每个数据元素。相对于API网关所提供的网络或API级别的安全性,这是一个更加细粒度的安全模型。
API网关可以进行服务发现、负载均衡,并通过像Kubernetes这样的编排器来扩展服务。但是,它们无法扩展数据。数据只能通过副本和缓存进行扩展。有些数据存储可以在云原生环境中实现副本,但并非全部如此。专门构建的工具,如Debezium,可以通过数据存储的事务日志执行数据变更捕获,并能够实现数据复制以用于扩展和其他使用场景。
而数据网关则能够通过缓存数据和物化视图(materialized views)加速对各种数据源的访问。它能够理解查询,基于数据源的能力对查询进行优化并生成最高性能的执行计划。将物化视图和变更数据捕获的流特征结合起来,这将是最终的数据扩展技术,但是目前还有这方面的云原生实现。
在API管理中,响应组合是一种常见的技术,用来聚合来自多个不同系统的数据。在数据领域,同样的技术被称为异构数据联邦(heterogeneous data federation)。异构性指的是不同数据源之间的差异程度,如网络协议、查询语言、查询功能、数据模型、错误处理、事务语义等。数据网关可以作为无缝、透明的数据联邦层来处理这些差异。
API网关允许使用像OpenAPI这样的规范实现契约优先的服务和客户端开发。数据网关允许基于SQL标准的模式优先的数据消费。数据模型的SQL模式就等价于API的OpenAPI。
在本文中,我使用API和数据网关来泛指一组功能。API网关有很多类型,如API管理器、负载均衡器、服务网格、服务注册等。数据网关与之类似,涵盖了从希望完成所有事情的大型单体数据虚拟化平台,到数据联邦库,从专门构建的云服务到终端用户的查询工具。
我们来研究一下不同类型的数据网关,并看一下哪些符合“云原生数据网关”的定义。在谈到云原生数据网关时,我指的是容器化的一等Kubernetes公民。我的意思是开源的网关,使用开放标准;能够部署到混合/多云基础设施的组件,能够与不同的数据源、数据格式协作,适用于多种使用场景。
第一类数据网关就是传统的数据虚拟化平台,如Denodo和TIBCO/Composite。尽管这些是特性最丰富的数据平台,但是它们往往做得太多,想要做所有的事情,从API管理,到元数据管理、数据编目、环境管理、部署、配置管理等等。从架构的角度来看,它们非常类似于旧的ESB,只不过适用于数据层。我们可以设法将它们放到容器中,但是很难将它们放到云原生的类别之中。
另外一个新兴的趋势是数据库除了存储数据之外,它们也开始充当数据联邦网关,并允许访问外部的数据。
例如,PostgreSQL实现了ANSI SQL/MED规范,这是一个从SQL数据库访问远程对象的标准化方式。这意味着远程数据存储,如SQL、NoSQL、文件、LDAP、Web、大数据,都可以像同一个PostgreSQL数据库中的表那样进行访问。SQL/MED代表的意思是外部数据管理(Management of External Data),CONNECT引擎、DB2和后文介绍的Teiid项目以及其他的一些产品也实现了该规范。
从SQL Server 2019开始,我们可以在不移动或复制数据的情况下查询外部数据源。SQL Server实例的PolyBase引擎能够用来处理Transact-SQL查询,以便于访问SQL Server、Oracle、Teradata和MongoDB中的外部数据。
与传统的数据虚拟化相比,这是一种新的数据网关类型,主要关注基于Web的快速数据访问。Hasura、Prisma和SpaceUpTech的共同之处在于,它们通过在多个数据源上提供轻量级的抽象来聚焦GraphQL的数据访问。这是一个快速增长的类别,专门用来支撑基于Web的数据驱动应用的快速开发,而不是针对BI/AI/ML的使用场景。
Apache Drill是一个无模式的SQL查询引擎,适用于NoSQL数据库和文件系统。它在不支持JDBC和ODBC API的数据源之上,为业务用户、分析师和数据科学家提供了JDBC和ODBC访问的能力。同样,它的驱动力来自为不同的数据源提供统一的基于SQL的访问能力。尽管Drill具备高度可扩展的能力,但是它依赖于Hadoop或Apache Zookeeper这样的基础设施,这也在一定程度上暴露了它的年龄。
Teiid是Red Hat赞助的一个项目,也是我最熟悉的项目。它是一个成熟的数据联邦引擎,专门针对Kubernetes生态系统进行了重写。它使用SQL/MED规范来定义虚拟数据模型,并且依赖于Kubernetes Operator模型来构建、部署和管理其Openshift之上的运行时。一旦部署完成,运行时就可以像其他Kubernetes上的无状态云原生工作负载那样进行扩展了,并且能够与其他云原生项目进行集成。例如,它能够利用Keycloak实现单点登录和数据角色,利用Infinispan实现分布式缓存的需求,导出指标并注册到Prometheus上实现监控,利用Jaeger实现跟踪,甚至使用3scale实现API管理。但是,最终Teiid会以单个Spring Boot应用的形式来运行,作为一个数据代理并与Openshift上最棒的服务进行集成,而不是尝试从头发明所有的东西。
Teiid数据网关的架构概览
在客户端,Teiid在JDBC/ODBC和Odata API之上提供了标准SQL。业务用户、分析师和数据科学家可以使用标准的BI/分析工具(如Tableau、MicroStrategy、Spotfire)来与Teiid进行交互。开发人员可以利用REST API或JDBC实现自定义构建的微服务和serverless工作负载。不管是哪种情况,对于数据消费者来说,Teiid都像一个标准的PostgreSQL数据库那样,能够通过JDBC或ODBC协议来进行访问,但是提供了额外的抽象,并与物理数据源进行了解耦。
PrestoDB是由Facebook发起的另外一个流行的开源项目。它是一个面向大数据使用场景的分布式SQL查询引擎,借助其协调者-工作者(coordinator-worker)架构来实现。协调者负责解析语句、规划查询、管理工作者、从工作者获取结果并将最终结果返回给客户端。工作者负责执行任务并处理数据。最近,PrestoDB社区分裂了并创建了名为PrestoSQL的fork,该fork目前是Linux基金会的一部分。尽管对于很多开源项目来讲,fork都是一种常见且很自然的做法,但是很不幸的是,在该个案中,项目名称以及面向社区的制件的相似性产生了很多的困扰。尽管如此,这两个Presto分发版本都是在该领域最流行的开源项目。
随着向云基础设施的迁移,对数据网关的需求不但没有消失,反而增加了。下面列出了基于云的数据网关服务:
AWS Athena是一个基于ANSI SQL的交互式查询服务,用来分析与Amazon S3紧密集成的数据。它基于PrestoDB,并且支持额外的数据源和联邦功能。Amazon另外一个类似的服务是AWS Redshift Spectrum。它关注相同的功能,即使用SQL查询S3对象。主要的差异在于Redshift Spectrum需要一个Redshift集群,而Athena是一个serverless的方案,不需要任何服务器。Big Query是一个类似的方案,但是它来自谷歌。
这些工具几乎不需要设置,它们能够访问企业内建(on-premise)或云托管的数据,并能够处理大数据集。但是,它们会让你与某个云供应商耦合在一起,因为它们无法部署到多云或企业内建环境中。它们是交互查询的理想方案,但并不适合作为其他服务或工具的混合数据前端。
现在,云托管的数据网关面临着访问企业内建数据的需求。数据是非常重要的,并且可能会受到禁止转移到云端的法规约束。让最有价值的资产(也就是数据)避免与某个云耦合是明智的决定。所有这些情况都需要云访问企业内建的数据。云供应商让我们更容易地访问数据。Azure的On-premises Data Gateway就是这样一个代理,它允许通过Azure Service Bus访问企业内建的数据存储。
在与之相反的场景中,在企业内建的客户端中访问云托管的数据可能也很具挑战性。谷歌的Cloud SQL Proxy提供了安全访问Cloud SQL实例的功能,并且不需要白名单ID地址或配置SSL。
Red Hat赞助的开源项目Skupper采用了更通用的方式来解决这些挑战。Skupper通过一个第七层的虚拟网络来解决Kubernetes多集群通信所面临的挑战,该虚拟网络提供了高级路由和安全连接通信的功能。它不是将Skupper嵌入到业务服务运行时中,而是在每个Kubernetes命名空间中作为一个独立的实例来运行,充当一个共享的边车(sidecar),能够为数据访问或其他服务与服务间的通信提供安全的通道。它是一个通用的安全连接代理,适用于混合云领域的很多使用场景。
Serverless在微服务的基础上将软件分解又往前推进了一步。serverless基于函数模型,其中每个操作都是短期存活的,而且只执行一个操作,而不是按照限界上下文来切分服务。这些细粒度的软件结构非常具有扩展性和灵活性,但是所要付出的代价也是以前所没有遇到的。事实证明,对于面向连接的数据源来讲(如关系型数据库和消息代理),函数的快速扩张是一个挑战。因此,云提供商提供了透明的数据代理,将其作为一个服务来有效管理连接池。Amazon RDS Proxy就是一个这样的服务,它位于我们的应用和关系型数据库之间,以便于有效地管理数据库连接并提升可扩展性。
现代云原生架构结合微服务原则,能够创建出高度可扩展和独立的应用程序。我们面临着在数据存储引擎、云托管服务、协议以及数据格式方面的大量选择,它们为快速交付软件提供了极大的灵活性。但是,这一切的代价也越来越不容忽视,它们需要为具有不同需求的新兴用户组提供统一的实时数据访问。让微服务的数据仅仅满足微服务本身的需求带来了很多的挑战,在技术和架构方面还没有很好的答案。数据网关与云原生技术相结合提供了和API网关类似的特性,只不过它适用于数据层,能够帮助解决这些新的挑战。数据网关在规范化方面有很多差异,但是它们在提供统一的基于SQL的访问、增强数据角色的安全性、缓存和物理数据存储的抽象方面趋于一致。
数据是非常重要的,需要细粒度的访问控制,难以扩展并且难以迁移至或迁移出云原生基础设施,或者在这些设施之间迁移。数据网关组件是云原生工具库的一部分,它是混合的技术方案,可以在多个云提供商上运行,支持不同的使用场景,它正在变成一项必备的技术。
Bilgin Ibryam是Red Hat的产品主管、Apache 软件基金会(Apache Software Foundation)的提交者和成员。他热衷于推广开源、撰写博客,偶尔还参与技术演讲。他是《Kubernetes 模式(Kubernetes Patterns)》和《Camel 设计模式(Camel Design Patterns)》的作者。在日常工作中,Bilgin乐于指导、编码并领导开发人员成功地构建开源解决方案。目前,他专注于区块链、分布式系统、微服务、devops和云原生应用开发。