分享

谈谈Data Mesh架构中的数据域设计

 数据治理精英馆 2023-04-15 发布于浙江

域驱动设计

让我们从理论部分开始:域驱动设计 (DDD) 是一种支持软件开发的方法,有助于为大型组织描述复杂系统,最初由 Eric Evans 描述。DDD 之所以流行,是因为它的许多高级实践对现代软件和应用程序开发方法(例如微服务)产生了影响。

DDD 包括有界上下文、域和子域。域是我们试图解决的问题。它们是知识、行为、管理和活动聚集在一起的组。它们是我们看到语义耦合的范畴:组件或服务之间的行为依赖性。通常将域分解为子域以更好地管理复杂性。一个常见的例子是以每个子域对应于特定业务问题的方式分解域。

并非所有子域都相同。例如,可以将域分类为核心域、通用域或支持域。核心子域是最重要的。它们是使企业独有的业务能力。通用子域是非特定的,通常很容易用现成的产品解决。支持子域不提供竞争优势,但对于保持组织运行是必要的。通常,它们并不那么复杂。

有界上下文是逻辑(上下文)边界。他们专注于解决方案空间:系统和应用程序的设计。这是一个将焦点对准解决方案空间的区域。在 DDD 中,这可以是代码、数据库设计等。在域和有界上下文之间,可以对齐,但将它们绑定在一起并不是硬性规定。有界上下文本质上是一般技术性的,可以跨越多个域和子域。

DDD 用于数据管理的困难在于,DDD 的原始用例是在软件开发环境中对复杂系统进行建模。最初,它从来不是为企业数据建模而创造的,这使得数据管理从业者的方法非常抽象和技术化。所以让我打个比方。将域视为共同兴趣的领域。以房子和街道为例。街道是一个域,每个房屋代表一个子域。每栋房子都站在自己的财产上并有围栏,这也意味着房子不会填满整个财产。栅栏表示有界上下文(责任模型)。房主负责维护他们的房屋,并且可以在他们的围栏内为所欲为。然而,跨越边界(栅栏)时,需要遵守某些规则。例如,进出房屋时始终使用公共车道。

如果我们将数据网格作为数据民主化的概念,并实施面向域的数据所有权原则以获得更大的灵活性,那么这在实践中将如何运作?从企业数据建模到域驱动设计建模的转变会是什么样子?我们可以从 DDD 中学到什么用于数据管理?

对问题范围进行功能性业务分解

在团队端到端地操作他们的数据之前,第一个建议是查看范围并了解试图解决的问题范围。在进入技术实现的细节之前,先做这个练习很重要。正如 DDD 所提倡的那样,它有助于在这些问题范围之间设置逻辑边界,因为职责更加明确并且将得到更好的管理。

为了对问题范围进行分组,最好查看组织的业务架构。在业务架构中,有业务能力:业务可能拥有或交换以实现特定目的或结果的功能或能力。这种抽象将特定上下文中的数据、流程、组织和技术打包在一起,与组织的战略业务目标和目标保持一致。业务能力视图显示哪些功能区域被认为是实现使命和愿景所必需的。

上面,创建了一个虚构的航空公司的能力架构图:Oceanic Airlines,它需要掌握业务能力图中列出的所有功能区域才能取得成功。例如,Oceanic Airlines 必须能够将机票作为在线或离线机票管理系统的一部分进行销售,或者通过飞行员管理计划让飞行员可以驾驶飞机。公司可以外包一些活动,同时将其他活动作为其业务的核心。

在实践中可以看到,大部分员工都是围绕这些能力组织起来的。从事相同业务能力工作的人们共享相同的词汇。这同样适用于应用程序和流程;根据他们需要支持的活动的凝聚力,它们通常很好地对齐并紧密相连。因此,业务能力映射是一个很好的起点,但故事并没有就此结束。

将业务能力映射到应用程序和数据

为了更好地管理企业架构,业务能力、有界上下文和应用程序都应该保持一致。这样做时,遵循一些基本规则很重要。业务能力保持在业务级别并保持抽象是至关重要的。它们代表组织所做的事情并针对特定问题范围。实现业务功能时,会创建特定上下文的实现(功能实例)。在解决方案的这些边界内,多个应用程序和组件协同工作以提供特定的业务价值。

与特定业务能力一致的应用程序和组件与与其他业务能力一致的应用程序保持分离。这提供了更大的灵活性,并且也是域和有界上下文发挥作用的地方,就像边界围栏和我们的房子一样。我们可以设定明确的原则:有界上下文派生自业务功能并专门映射到业务功能。它们代表业务能力实现的边界,并且表现得像一个域。如果业务能力发生变化,则有界上下文也会发生变化。最好域和相应的有界上下文之间完全对齐,但现实情况可能有所不同。

如果我们将功能映射投影到 Oceanic Airlines,有界上下文边界和域实现可能如下所示。

在上面的“域之间的数据分布”示例中,客户管理建立在主题专业知识的基础上,因此有权确定将哪些数据提供给其他域。客户管理的内部架构是解耦的,因此这些边界内的所有应用程序组件都可以使用特定于应用程序的接口和数据模型直接进行通信,使用数据产品和明确的互操作性标准将数据分发到其他领域。这是进出房屋的公共车道!在这种方法中,所有数据产品也与域保持一致并继承所有的通信标准:一种构造的、形式化的语言,由同一域的利益相关者和设计者商定,以满足该领域的需求。

多种能力的实现导致其他的域

使用业务能力图时重要的是要了解某些业务能力可以实例化多次。例如,到目前为止,我们一直在使用的示例 Oceanic Airlines 可以具有“行李处理和丢失物品”的多个本地化实现或实例。例如,一项业务仅在亚洲运营。在这种情况下,“行李处理和遗失物品”是亚洲相关飞机的一项能力。不同的业务线可能针对欧洲市场,因此在这种情况下使用另一种“行李处理和丢失物品”功能。这种多个实例的场景可能会导致使用不同技术服务的多个本地化实施以及运营这些服务的团队。

共享能力和共享数据

更重要的是应该如何处理共享的业务能力。这种能力通常作为服务模型集中实施,并提供给不同的业务线。例如,“客户管理”可能就是这样一种能力。在 Oceanic Airlines 的背景下,亚洲和欧洲业务线对其客户使用相同的管理。问题是:如何将域数据所有权投射到共享功能上?多个业务代表很可能对位于同一共享管理中的客户负责。总而言之,有一个应用域和一个数据域!来自数据产品观点,域和有界上下文并不完全一致。相反,您可能会说,从业务能力的角度来看,仍然存在单一数据问题。

数据产品:数据产品是数据架构的一个单元或组件,它封装了使读取优化的数据集可供其他域使用的功能。

对于共享功能,例如复杂的供应商包、SaaS 解决方案和遗留系统,我建议域数据所有权方法上保持一致。一种技术可能是通过数据产品分离数据所有权,这也可能需要改进应用程序。在“客户管理”的示例中,来自应用程序域的不同管道可以生成多种数据产品:一种数据产品适用于所有亚洲相关客户,一种数据产品适用于所有欧洲相关客户。这意味着多个数据域源自同一个应用程序域。

处理共享数据的另一种技术是要求应用程序域设计一个封装元数据的单一数据产品,以区分数据产品内的数据所有权。例如,可以为所有权使用保留的列名,将每一行映射到一个特定的数据域。下面是一个如何使用域列的示例。

共享功能的复杂性在于数据域与应用程序域重叠。理想情况下,拥有业务能力的团队与应用程序领域保持一致,因此软件所有权和数据所有权也保持一致。如果无法拆分域,则需要区分应用程序所有权和数据所有权。因此,在“客户管理”的示例中,将有一个应用程序所有者负责底层技术服务、管道和应用程序组件。接下来,将有多个数据所有者负责不同的数据集,包括元数据注册、隐私、安全等。

关注服务于多种业务功能的复杂应用程序

另一个关注点是满足多种业务能力的应用程序,这在大型和传统企业中很常见。例如,大洋航空使用一个软件包来促进“成本管理”和“资产与融资”。此类共享应用程序通常庞大而复杂:提供尽可能多的功能的供应商业务套件或遗留单体。这种情况下的应用领域预计会更大。这同样适用于共享所有权,这意味着多个数据域驻留在一个应用程序域中。

源对齐、重新交付和消费者对齐域的设计模式

在映射域时,将了解基于数据的创建、使用或重新交付的不同模式。我建议基于它们所具有的特征设计架构蓝图以支持域。

源对齐域与数据来源的源系统对齐。这些通常是交易或操作系统。目标必须是直接从这些黄金源系统中捕获数据。来自提供域的数据产品应该针对密集的数据消费进行读取优化,因此使用标准化服务来促进域进行数据转换和共享。这些服务,包括预配置的容器结构,使面向源的域团队能够更轻松地发布数据;这是以最小的中断和成本的好处做正确的事情的阻力最小的途径。例如,如果设计正确,体系结构将类似于以下模型:

消费者对齐域与源对齐域相反,因为它们与需要来自其他域的数据的特定最终用户用例对齐。他们使用和转换数据以适应他们的业务用例。为了满足这些消费需求,应该考虑为数据转换和消费提供共享数据服务,例如,与域无关的数据基础设施功能来处理数据管道、存储基础设施、流服务、分析处理等。

重新交付域:一个不同且更困难的场景是数据的可重用性。例如,多个下游消费者可能对来自不同域的数据组合感兴趣。

对于架构,建议松散地耦合数据产品的创建和分析用例。在下面的模型中,域同时拥有聚合数据可重用数据和分析用例的所有权。然而,这两个问题是分离的。通过这种方法,数据消费者可以安全地使用新的数据产品,而不会与同一域的分析用例紧密相关。这种情况下的聚合数据是分析用例的输入。

另一种选择可能是新生成的数据成为其他域数据消费的候选者。在这种情况下,数据消费者成为数据提供者,并遵循相同的数据分发路径。这种情况下的架构如下所示:

解决复杂集成挑战的标准化模式

当将企业环境分解为更细粒度的域结构时,将遇到复杂的集成挑战。如果我们以大洋航空公司为例,其他不同领域可能需要来自“客户管理”的数据。或者“飞行计划和概览管理”必须在计划飞行之前知道飞行员是否仍然存在于“飞行员管理”的管理中。你会如何解决这个问题?

最佳实践是对跨域边界集成的通用泳道模式进行标准化。例如,在进行大量数据处理时,可以应用 CQRS 来构建面向域的读取数据存储。这允许域从其他域集中读取数据,而不需要不断地复制数据。例如,对于强一致性读取和命令,建议使用API模式。以下设计模式可以帮助组织完成过渡:

如果泳道模式设计正确,它们还会与数据管理功能相集成。这使组织可以捕获元数据以实现安全性、可观察性、可发现性、沿袭和链接、质量监控、编排、通知等方面的透明度和洞察力。

解耦的粒度级别

现在我们知道如何识别和建立数据域,我们进入下一个要点:设计正确的域粒度级别和解耦规则。分解架构时,有两个重要的维度需要考虑:

首先,功能域有粒度设置有界上下文:符合工作方式,确保数据对所有域可用并利用共享服务,遵守元数据标准等。我对数据分发的建议是尽可能细粒度地设置边界,因为成为数据驱动就是让数据可用于集中(重新)使用数据。如果将域边界定义得过于粗粒度,将在许多应用程序之间强制进行不需要的耦合,并且数据可重用性会丢失。因此,每次数据跨越业务能力边界时,都力求解耦。这意味着在一个域内,紧耦合是允许的。然而,当跨越边界时,域必须保持解耦并分发读取优化的数据产品以共享数据到其他域。

其次,技术域和基础设施利用具有粒度。想一想使用不同分散区域的现代分布式数据平台,以实现在其中服务数据集成和数据产品的敏捷性。这样一个区域,下面有共享的基础设施和服务,将如何向不同的域团队提供它?我的经验是,许多不同的方面触发了哪些功能域将在逻辑上组合在一起并成为共享平台基础设施的候选。这里有一些例子:

  • 工作和共享数据方式的凝聚力和效率。这与数据引力密切相关:在域之间不断共享大型数据集的趋势。

  • 域边界可能导致实施相同的业务能力和蓝图。

  • 所有权、安全或法律边界可能会迫使域被隔离。例如,某些数据不允许其他域看到。

  • 灵活性和变化速度是重要的驱动因素。多个域内可能存在创新速度,而其他域则非常看重稳定性。

  • 功能边界可能分离团队,例如面向来源/消费者。也许域团队中有一半重视特定服务而不是其他服务集。

  • 如果希望潜在地出售或分离功能,与其他域的共享服务紧密集成并不是明智之举。

  • 团队规模、技能和成熟度可能是一个因素。高技能和成熟的团队希望运营自己的服务和基础设施。

  • 政治边界也可能是一种驱动力。当业务能力与组织结构不正确地对齐时,我尤其会看到这一点。

业务能力建模的好处是它可以帮助更好地识别和组织数据网格架构中的域。它提供了数据和应用程序如何为业务创造价值的整体视图。同时,优先考虑并专注于数据战略和实际业务需求。除了仅需要数据之外,还可以使用此模型。例如,如果可扩展性是一个问题,可以确定最关键的核心能力并为这些能力制定战略。

将所有域和基础设施区域拼接在一起时,数据网格架构在概念上应该像这样:

在上面的模型中,域在逻辑上组织起来并有效地共享基础设施,同时使用通用的泳道模式集成和分发数据。每个数据产品团队作为一个子域,对他们生产和服务的数据负责。跨越域边界时,团队利用基础设施蓝图提供的共享数据服务进行数据转换和消费。

有些人可能会担心,通过预先规划所有内容来构建这样一个目标状态架构是一项巨大的工作。建议的替代方案是有机地识别域,同时将它们纳入架构。因此,无需自上而下定义目标状态,而是自下而上:探索、试验并将当前状态转变为目标状态。这种方法可能会更快,但会暴露出在出现问题时进行复杂移动或改造操作的风险。一种更微妙的方法可能是双向工作,并随着时间的推移在中间对其。

最后,大规模设计分布式架构还需要进行系统化的思考。业务能力建模和映射关键战略将简化域的分解。

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多