认为系统中的数据比组成它的实际应用程序更有价值,这有点老生常谈。这些应用程序被更新、修改、停用和替换,但数据仍然存在。对于许多企业来说,这些数据是他们最重要的资产。它过去很简单。您拥有该组织的数据库。只有一个地方存储了组织所做的一切和所知道的一切,这就是您满足所有需求的地方。一个数据库,用于管理、监视、优化、备份等,以管理整个组织的数据需求。
随着组织的发展,数据库中的数据越来越多,因此增加了更多的需求。在某种程度上,你达到了你所能做的绝对极限。您不能再使用单个数据库;您必须将系统和数据库拆分为独立的组件。在本文中,我将讨论如何管理数据范围和大小的增长。
共享数据库的死亡:为什么我们不能拥有更大的机器
虽然并不常见,但目前使用TB级数据库处理数十亿条记录的情况并不少见。那么问题是什么?这个问题与特定数据库引擎的技术限制无关。这是将所有东西(包括至少两个厨房水槽和一个生日蛋糕)放入单个数据库的组织权重。例如,在我工作的一家公司,数据库中有30000多个表。视图和存储过程的数量要高得多。我们不会谈论触发器的数量。
用于处理数据库的工具中,没有一个可以处理这么多表。通过任何GUI工具连接到数据库通常会导致工具每次冻结几分钟,而读取模式描述的时间很短。当然,实际上没有人知道数据库中发生了什么,但数据和围绕它的过程对组织的成功至关重要。唯一的选择是要么停滞不前,要么开始将数据库拆分为可管理的块。
那是多年前的事了,行业格局已经发生了变化。如今,在考虑数据时,我们还有很多需要考虑的问题,例如:
-
属于欧洲公民的个人数据,这意味着与之相关的任何数据也必须实际存在于欧盟,并受GDPR规则的约束。
-
医疗信息(直接或间接),有一套全新的规则需要遵循(例如HIPAA、HITECH或ENISA规则)。
数据隐私和来源等问题更为重要,比如能够审核和分析谁访问了特定数据项,以及为什么在许多领域这是一项艰巨的要求。一个存储组织中所有信息的存储桶的概念已不再可行。
另一个重要的重大变化是常见的架构模式。我们现在不再使用单一的单一系统来管理组织中的一切,而是将系统拆分为更小的组件。这些组件有不同的需求和要求,按不同的时间表发布,并使用不同的技术。当您需要进行更改时,尝试在所有这些团队之间进行协调的开销是您希望在系统中进行更改时的一大障碍。跨如此多的团队和组件进行协调的成本实在太高了。
通常使用独立应用程序数据库的概念,而不是使用单个共享数据库。这是一个更大的建筑概念的重要组成部分。通常,您会在微服务和面向服务的体系结构这两个术语下遇到这种情况。
作为实施决策的应用程序数据库
从单个共享数据库移动到一组应用程序数据库之间最重要的区别之一是,我们没有拆分共享数据库。数据库级别的适当分离是关键。一组共享数据库将有完全相同的协调问题,因为厨房里有太多厨师。应用程序数据库如果适当分离,将使我们能够为每个任务选择最佳的数据库引擎,本地化更改,并减少更改通信的开销,从而使我们受益。这种方法的缺点是,我们将在生产中支持更多的系统。
让我们更深入地讨论共享数据库和应用程序数据库之间的区别。很容易犯错误,如图1所示,例如:
图1:从单个共享数据库到多个(仍然共享)数据库的错误迁移路径
虽然共享数据库是您可以实现的,因为没有其他选项,但应用程序数据库是一种内部选择,除了应用程序之外,任何人都不能访问它。从同样的意义上说,我们在面向对象编程中进行封装,使用隐藏状态的私有变量,应用程序数据库是应用程序之外任何人都不会关心的。我对这件事很感兴趣。
在编写代码时,您知道直接处理其他对象的私有状态是错误的。您可能违反了不变量;您将使未来的维护和开发变得复杂。这一点受到了太多的打击,以至于大多数开发人员几乎本能地不愿这么做。当您直接接触另一个应用程序的数据库时,也会发生同样的情况,但这种情况非常常见。
在某些情况下,我会对数据库中的所有表和列的名称进行加密,以表明您不应该查看我的数据库。应用程序数据库是应用程序的内部关注点,而不是其他人。这个想法很简单。如果应用程序之外的任何实体需要一些数据,他们需要向应用程序请求这些数据。它们不能直接进入应用程序的数据库来解决问题。这是问“你在和谁说话”和查看他们所有的通话记录和信息之间的区别。从理论上讲,这是一种很好的方法,但您需要考虑您的应用程序很少是系统的应用程序。你必须与生态系统的其他部分整合。问题是你如何做到这一点。
如果这里描述的系统听起来很熟悉,那是因为您以前可能听说过它。它最初是DCOM/COBRA系统的一部分,后来被称为面向服务的体系结构,现在被称为微服务。
让我们假设在我们的系统中处理发货的应用程序需要访问一些客户的数据来完成其任务。如何获取这些数据?使用共享数据库时,直接查询客户的表。当拥有客户应用程序的团队需要添加列或重构数据时,您的系统将崩溃。它们之间没有封装或分隔。对另一个团队的实现细节的直接依赖导致了毁灭、停滞和不断增加的复杂性。
使用全局数据
或者,发货应用程序可以(通过发布的服务接口)要求拥有客户的数据的应用程序获取所需的详细信息。这通常是通过从一个应用程序到另一应用程序的RCP调用来完成的。这里的问题是,这在两个应用程序之间建立了强大的联系。如果客户的应用程序因维护而停机,则发货应用程序将无法工作。再加上几十个这样的应用程序以及它们之间的相互依赖性,就会出现僵局。我们需要考虑一种更好的方法来处理这种情况。
我的建议是从另一个方向开始整个过程。我们将反向处理,而不是发送应用程序查询客户的应用程序以获取相关数据。作为客户应用程序服务界面的一部分,我们可以决定要向组织的其他成员公开什么样的信息。
需要注意的是,我们发布的数据绝对是服务合同的一部分。我们不提供对数据库的直接访问。应用程序应将其数据发布给外部世界。这可以是每天上传到FTP站点或GraphQL端点的CSV文件,以选择两种截然不同的技术和语义。
我在FTP中加入了CSV,特别是为了指出这种数据共享方式并不相关。重要的是,有一种既定的方法可以从应用程序中发布数据,因为这种体系结构风格的一个关键方面是,我们在需要数据时不会查询数据。相反,我们将其摄入我们自己的系统。我希望很清楚为什么发货应用程序不只是打开一个FTP连接到客户的每日CSV转储文件来查找一些详细信息。同样,它不应该将查询GraphQL端点作为其正常例程的一部分。
相反,我们有一个既定的机制来发布客户的数据(客户的应用程序已向组织的其他成员公开)。这被系统中的其他应用程序接收,当他们需要查询客户的详细信息时,他们可以从自己的系统中进行查询。您可以在图2中看到它的样子。
图2:客户的应用程序发布数据以供发货应用程序使用
在每个应用程序中,数据可以以不同的方式存储和表示。在每种情况下,这都是最适合他们的方案。
发布应用程序还可以以任何方式处理数据。数据库和数据发布方式之间的服务边界允许自由修改内部细节,而无需与外部系统协调。
另一种选择是有一个两阶段的过程,如图3所示。客户的应用程序不会将其更新发送到发货应用程序,而是将其发送到组织数据湖。通过这种方式,每个应用程序都将希望公开的数据发送到中心位置。其他应用程序可以将所需数据从数据湖复制到自己的数据库。
图3:从每个应用程序发布到数据湖,并将数据拉到每个应用程序
最终结果是一个数据共享的系统,但应用程序和服务之间没有时间依赖性。它还确保了不同团队和系统之间的边界。只要发布的接口保持不变,就不需要协调或复杂性。
在现实世界中应用这种架构风格
让我们深入探讨一些关于如何应用这种架构方法的具体建议。您可以通过在服务总线上发出事件或发布每日文件来全局发布数据。您可以发布特定场景的数据,例如从客户的数据库到发货数据库的ETL流程。确切的方式并不重要,只要我们有适当的边界,我们可以改变我们的方式,而不会产生全球协调成本。
只有当我们需要参考数据或对与一致性无关的数据做出决策时,这种操作风格才有效。如果我们需要对数据进行更改或协调更改,则此方法不适用。在一致性无关紧要的场景中,一个很好的例子是从客户的ID中查找客户的姓名。如果我们有旧名称,这不是一个主要问题。它很快就会自行修复,我们不会根据客户的名字做出决定。同时,我们可以运行所有计算,并在应用程序范围内完全在本地工作,这是一个很大的优势。
当我们需要做出决策或修改数据时,一致性很重要。例如,在运输场景中,如果我们需要收取超重运输费用,我们需要确保客户的账户中有足够的资金(并且我们需要扣除运输金额)。在这种情况下,我们无法对自己的数据进行操作。毕竟,我们没有账户中的资金。我们也无法直接改变它。在这种情况下,我们需要去客户的申请处,要求扣除这些资金,如果资金不足,我们会报错。请注意,如果客户无法付款,我们希望发货过程失败。
我们的应用程序不再部署到单个服务器甚至单个数据中心。如今,在边缘系统上运行应用程序(如移动应用程序或物联网设备)是很常见的。将所有这些数据推送到我们自己的系统可能会导致我们存储大量数据。这种数据封装和只发布我们想向其他方公开的细节的架构风格在这个场景中发挥了很好的作用。
无需将所有信息复制到中心位置,我们可以将数据存储在边缘,并从边缘设备接收足够的数据,以便能够做出决策并操作系统的全局状态。在其他优点中,这种方法可以让用户控制所有数据,我认为这是一个主要优点。
结束语
在体系结构中使用应用程序数据库和显式发布数据有几个原因。首先,这意味着这些行动是在当地资源和最低限度的协调下进行的。这反过来意味着操作将更快、更可靠。其次,它减少了全面的协调开销,这意味着我们可以根据需要独立部署和更改每个应用程序。
最后,这意味着我们可以为每个场景单独选择最佳选项。我们可以为每个选项选择最好的品种,而不是迎合最低的公分母。例如,我们可以使用文档数据库存储装运清单,但将历史数据放入数据池。
每个应用程序都是独立的,相互独立的,我们可以为每个场景做出最佳的技术选择,而无需考虑任何全局约束。结果是一个更容易更改的系统,由更小的组件组成(因此更容易理解),并且更加灵活。
原文标题:Data Management in Complex Systems
原文作者:Oren Eini
原文链接:https://dzone.com/articles/data-management-in-complex-systems