2.2 数据工程生命周期中的主要底层设计
数据工程正在迅速成熟。以前的数据工程周期只关注技术层,而工具和实践的持续抽象和简化已经改变了这一重点。数据工程现在包含的不仅仅是工具和技术。该领域现在正在向价值链上游移动,将数据管理和成本优化等传统企业实践与DataOps等新实践相结合。
我们将这些实践称为底层设计——安全、数据管理、DataOps、数据架构、编排和软件工程——它们支持数据工程生命周期的各个方面(如图2-7所示)。在本节中,我们将概述这些底层设计及其主要组成部分,你将在本书中看到更详细的内容。
图2-7:数据工程的主要底层设计
2.2.1 安全
安全必须是数据工程师的首要考虑因素,忽视安全的人将会面临危险。这就是安全是第一个底层设计的原因。数据工程师必须了解数据和访问安全,运用最小特权原则。最小特权原则(https://oreil.ly/6RGAq)意味着只允许用户或系统访问基本数据和资源以执行预期的功能。我们在缺少安全经验的数据工程师身上看到的一个常见反模式是向所有用户授予管理员访问权限。这是一场即将发生的灾难!
只为用户提供他们今天完成工作所需的访问权限,仅此而已。当你只是在寻找具有标准用户访问权限的可见文件时,请不要从root shell进行操作。查询具有较小角色的表时,不要使用数据库中的超级用户角色。将最小特权原则强加给我们自己可以防止意外损坏,并使你保持安全第一的心态。
人和组织结构始终是任何公司中最大的安全漏洞。当我们在媒体上听到重大安全漏洞时,往往会发现公司中有人忽视了基本的预防措施,成为网络钓鱼攻击的受害者,或者采取了其他不负责任的行为。数据安全的第一道防线是创建一种贯穿整个组织的安全文化。所有有权访问数据的个人都必须了解他们在保护公司敏感数据及其客户方面的责任。
数据安全还与时间有关——为需要访问数据的人和系统提供数据访问权限,并且仅在执行工作所需的时间内提供数据访问权限。应通过使用加密、令牌化、数据屏蔽、混淆和简单、强大的访问控制来保护数据,使数据无论是在运行中还是在静止状态都不可见。
数据工程师必须是称职的安全管理员,因为安全属于他们的领域。数据工程师应该了解云和本地部署的安全最佳实践。了解用户和身份访问管理(Identity Access Management,IAM)角色、策略、组、网络安全、密码策略和加密是很好的起点。
在整本书中,我们强调了在数据工程生命周期中安全应该是首要考虑因素的领域。你还可以在第10章中更详细地了解安全。
2.2.2 数据管理
你可能认为数据管理听起来很公司化。“老派”数据管理实践进入数据和ML工程。旧的又成了新的。数据管理已经存在了几十年,但直到最近才在数据工程中得到很大的关注。数据工具变得越来越简单,数据工程师要管理的复杂性也越来越低。结果,数据工程师沿着价值链向上移动到下一级最佳实践。曾经为大公司保留的数据最佳实践——数据治理、主数据管理、数据质量管理、元数据管理——现在正在渗透到各种规模和成熟度级别的公司。正如我们喜欢说的,数据工程正在变得“企业化”。这最终是一件了不起的事情!
国际数据管理协会(the Data Management Association International,DAMA)的《数据管理知识体系》(Data Management Body of Knowledge,DMBOK),我们认为是企业数据管理的权威书籍,提供了以下定义:
数据管理是计划、政策、程序和实践的开发、执行和监督,这些计划、政策、程序和实践在数据和信息资产的整个生命周期中交付、控制、保护和提高数据价值。
这有点冗长,所以让我们看看它与数据工程师的关系。数据工程师管理数据生命周期,而数据管理包含数据工程师将用于在技术和战略上完成此任务的一组最佳实践。如果没有管理数据的框架,数据工程师只是在真空中操作的技术人员。数据工程师需要更广泛地了解数据在整个组织中的效用,从源系统到最高管理层,以及两者之间的所有地方。
为什么数据管理很重要?数据管理表明数据对日常运营至关重要,就像企业将财务资源、成品或房地产视为资产一样。数据管理实践形成了一个每个人都可以采用的有凝聚力的框架,以确保组织从数据中获取价值并适当地处理它。
数据管理有很多方面,包括以下内容:
• 数据治理,包括可发现性和问责制
• 数据建模和设计
• 数据血缘
• 存储和操作
• 数据集成和互操作性
• 数据生命周期管理
• 用于高级分析和机器学习的数据系统
• 道德与隐私
虽然本书绝不是关于数据管理的详尽资源,但我们将简要介绍每个领域与数据工程相关的一些突出要点。
数据治理
根据Data Governance:The Definitive Guide,“数据治理首先是一种数据管理功能,可确保组织收集的数据的质量、完整性、安全性和可用性”。[1]1
我们可以对该定义进行扩展,并说数据治理涉及人员、流程和技术,以最大限度地提高整个组织的数据价值,同时通过适当的安全控制保护数据。有效的数据治理是有目的的开发并得到组织的支持。当数据治理是偶然的和随意的时候,副作用的范围可能从不受信任的数据到安全漏洞以及介于两者之间的一切。有意识地进行数据治理将使组织的数据能力和数据产生的价值最大化。它还(有希望地)让公司远离可疑或完全鲁莽的数据实践的头条新闻。
想想数据治理做得不好的典型例子。业务分析师收到报告请求,但不知道使用什么数据来回答问题。他们可能会花费数小时挖掘事务数据库中的数十个表,疯狂地猜测哪些字段可能有用。分析师编制了一份“方向正确”的报告,但并不完全确定该报告的基础数据是否准确或合理。报告的接收者也质疑数据的有效性。分析师以及公司系统中所有数据的完整性受到质疑。公司对其业绩感到困惑,使得业务规划无法进行。
数据治理是数据驱动业务实践的基础,也是数据工程生命周期的一个关键任务部分。当数据治理得到很好的实践时,人、流程和技术就会协调一致,将数据视为关键的业务驱动力,如果数据问题出现,则会及时得到处理。
数据治理的核心类别是可发现性、安全性和可问责性[2]。在这些核心类别中还有子类别,例如数据质量、元数据和隐私。让我们依次看看每个核心类别。
可发现性。在数据驱动型公司中,数据必须可用且可发现。终端用户应该能够快速可靠地访问他们完成工作所需的数据。他们应该知道数据的来源、数据与其他数据的关系,以及数据的含义。
数据可发现性的一些关键领域包括元数据管理和主数据管理。让我们简要描述一下这些领域。
元数据。元数据是“关于数据的数据”,它支撑着数据工程生命周期的每个部分。元数据正是使数据可发现和可治理所需的数据。
我们将元数据分为两大类:自动生成的和人工生成的。现代数据工程围绕自动化展开,但元数据收集通常是手动的且容易出错。
技术可以协助这个过程,消除手动收集元数据的许多容易出错的工作。我们看到数据目录、数据血缘跟踪系统和元数据管理工具的激增。工具可以爬数据库以查找关系并监控数据管道以跟踪数据的来源和去向。低保真手动方法使用内部主导的努力,其中各种利益相关者在组织内众包元数据收集。这些数据管理工具在整本书中都有深入的介绍,因为它们削弱了数据工程生命周期的大部分内容。
元数据成为数据和数据处理的副产品。然而,主要挑战依然存在,特别是,仍然缺乏互操作性和标准。元数据工具的好坏取决于它们与数据系统的连接器及其共享元数据的能力。此外,自动化元数据工具不应将人完全排除在外。
数据具有社会元素。每个组织都在积累社会资本和关于流程、数据集与管道的知识。以人为本的元数据系统关注元数据的社会方面。这是Airbnb在其有关数据工具的各种博客文章中所强调的内容,尤其是其最初的Dataportal概念[3]。此类工具应提供一个公开数据所有者、数据消费者和领域专家的场所。文档和内部wiki工具为元数据管理提供了重要基础,但这些工具还应该与自动数据编目相集成。例如,数据扫描工具可以生成带有相关数据对象链接的wiki页面。
一旦元数据系统和流程存在,数据工程师就可以以有用的方式使用元数据。元数据成为在整个生命周期中设计管道和管理数据的基础。
DMBOK确定了对数据工程师有用的四大类元数据:
• 业务元数据
• 技术元数据
• 操作元数据
• 参考元数据
让我们简要介绍一下每一类元数据。
业务元数据与数据在业务中的使用方式相关,包括业务和数据定义、数据规则和逻辑、数据的使用方式和位置,以及数据所有者。
数据工程师使用业务元数据来回答关于谁、什么、在哪里以及怎么样的非技术问题。例如,数据工程师的任务可能是为客户销售分析创建一个数据管道。但什么是客户?是在过去90天内购买过的人吗?或者是在公司开业的任何时间购买的人吗?数据工程师会使用正确的数据来参考业务元数据(数据字典或数据目录)来查找“客户”是如何定义的。业务元数据为数据工程师提供正确的上下文和定义以正确使用数据。
技术元数据描述了系统在整个数据工程生命周期中创建和使用的数据。它包括数据模型和架构、数据血缘、字段映射和管道工作流。数据工程师使用技术元数据在数据工程生命周期中创建、连接和监控各种系统。
以下是数据工程师将使用的一些常见技术元数据类型:
• 管道元数据(通常在编排系统中产生)
• 数据血缘元数据
• 模式元数据
• 操作元数据
• 参考元数据
编排是协调跨各种系统的工作流的中央枢纽。在编排系统中捕获的管道元数据提供了工作流计划、系统和数据依赖性、配置、连接细节等的详细信息。
数据血缘元数据跟踪数据随着时间的推移的起源和变化,以及它的依赖性。随着数据流经数据工程生命周期,它会通过转换和与其他数据的组合而不断发展。数据血缘提供了数据在各种系统和工作流中移动时演变的审计线索。
模式元数据描述了存储在数据库、数据仓库、数据湖或文件系统等系统中的数据结构。它是不同存储系统的关键区别之一。例如,对象存储不管理模式元数据;相反,模式元数据必须在元数据存储中进行管理。另外,云数据仓库在内部管理模式元数据。
这些只是数据工程师应该了解的技术元数据的几个例子。这不是一个完整的列表,我们在本书中涵盖了技术元数据的其他方面。
操作元数据描述了各种系统的运行结果,包括进程统计、作业ID、应用程序运行日志、进程中使用的数据和错误日志。数据工程师使用操作元数据来确定流程是成功还是失败,以及流程中涉及的数据。
编排系统可以提供操作元数据的有限情况,但后者仍然倾向于分散在许多系统中。对更高质量的操作元数据和更好的元数据管理的需求是下一代编排和元数据管理系统的主要动机。
参考元数据是用于对其他数据进行分类的数据,也称为查找数据。参考数据的标准示例是内部代码、地理代码、测量单位和内部日历标准。请注意,大部分参考数据完全在内部管理,但地理代码等项目可能来自标准外部参考。参考数据本质上是解释其他数据的标准,因此如果它发生变化,则这种变化会随着时间慢慢发生。
数据问责制。数据问责制意味着分配一个人来管理一部分数据。然后,负责人协调其他利益相关者的治理活动。如果没有人对相关数据负责,那么管理数据质量就会很困难。
请注意,负责数据的人不一定是数据工程师。负责人可能由软件工程师、产品经理或其他角色担任。此外,负责人通常不具备维护数据质量所需的所有资源。相反,他们与所有接触数据的人协调,包括数据工程师。
数据问责制可以发生在各个层面。问责制可以发生在表或日志流的级别,但也可以是与出现在多个表中的单个字段实体一样的细粒度级别。个人可能负责跨多个系统管理客户ID。对于企业数据管理,数据域是给定字段类型出现的所有可能值的集合,例如在这个ID示例中。这可能看起来过于官僚和细致,但它会显著影响数据质量。
数据质量
我可以相信这些数据吗?
——业务中的每个人
数据质量是数据向理想状态的优化,围绕着“与预期相比,你得到了什么?”这个问题展开。数据应符合业务元数据中的期望。数据是否符合企业约定的定义?
数据工程师确保整个数据工程生命周期中的数据质量。这涉及执行数据质量测试,并确保数据符合模式预期、数据完整性和精度。
根据Data Governance:The Definitive Guide,数据质量由三个主要特征定义[4]:
准确性
收集到的数据是否真实?是否有重复值?数值准确吗?
完整性
记录是否完整?所有必填字段都包含有效值吗?
及时性
记录是否及时可用?
这些特征中的每一个都非常微妙。例如,在处理网络事件数据时,我们如何看待机器人和网络爬虫?如果我们打算分析客户旅程,那么我们必须有一个流程可以让我们将人类与机器生成的流量区分开。任何机器人生成的事件都被错误分类为人类存在的数据准确性问题,反之亦然。
关于完整性和及时性,会出现各种有趣的问题。在介绍Dataflow模型的Google论文中,作者给出了一个显示广告的离线视频平台的示例[5]。该平台在有连接时下载视频和广告,允许用户在离线时观看这些内容,一旦连接再次存在,就会上传广告浏览数据。这些数据可能在广告被观看完之后才能收集到。平台如何处理广告的计费?
从根本上说,这个问题是无法通过纯粹的技术手段解决的。相反,工程师将需要确定他们对迟到数据的标准并统一执行这些标准,这可能需要借助各种技术工具。
主数据管理
主数据是有关业务实体的数据,例如员工、客户、产品和位置。随着组织通过有机增长和收购,并与其他企业合作变得越来越大、越来越复杂,保持实体和身份的一致形象变得越来越具有挑战性。
主数据管理(Master Data Management,MDM)是构建一致的实体定义(称为黄金记录)的实践。黄金记录协调整个组织及其合作伙伴的实体数据。MDM是一种通过构建和部署技术工具来促进的业务运营流程。例如,MDM团队可能会确定地址的标准格式,然后与数据工程师合作构建一个API以返回一致的地址,以及一个使用地址数据来匹配公司各部门客户记录的系统。
MDM跨越整个数据周期进入操作数据库。它可能直接属于数据工程的范围,但通常是跨组织工作的专门团队的指定职责。即使他们不拥有MDM,数据工程师也必须始终意识到这一点,因为他们可能会在MDM计划上进行协作。
数据质量跨越了人类和技术问题的边界。数据工程师需要强大的流程来收集有关数据质量的可操作的人工反馈,并使用技术工具在下游用户看到之前先检测出质量问题。我们在本书的相应章节中介绍了这些收集过程。
数据建模与设计
为了通过业务分析和数据科学从数据中获得业务洞察力,数据必须采用可用的形式。将数据转换为可用形式的过程称为数据建模和设计。虽然我们传统上认为数据建模是数据库管理员(Database Administrator,DBA)和ETL开发人员的问题,但数据建模几乎可以发生在组织中的任何地方。固件工程师为IoT设备开发记录的数据格式,或者Web应用程序开发人员设计对API调用或MySQL表模式的JSON响应——这些都是数据建模和设计的实例。
由于新数据源和用例的多样性,数据建模变得更具挑战性。例如,严格规范化不适用于事件数据。幸运的是,新一代数据工具增加了数据模型的灵活性,同时保留了度量、维度、属性和层次结构的逻辑分离。云数据仓库支持摄取大量非规范化和半结构化数据,同时仍支持常见的数据建模模式,例如Kimball、Inmon和Data Vault。如Spark之类的数据处理框架可以获取整个范围的数据,从平面结构化关系记录到原始非结构化文本。我们将在第8章中更详细地讨论这些数据建模和转换模式。
由于工程师必须处理各种各样的数据,因此很容易让我们举手投降并放弃数据建模。这是一个可怕的想法,会带来令人痛苦的后果,当人们抱怨一次写入,永不读取(Write Once,Read Never,WORN)访问模式或引用数据沼泽时,这一点就很明显了。数据工程师需要了解建模最佳实践,并开发灵活性以将适当级别和类型的建模应用到数据源和用例中。
数据血缘
随着数据在其生命周期中移动,你如何知道影响数据的系统或数据在传递和转换时由什么组成?数据血缘描述了数据在其生命周期中的审计跟踪记录,跟踪处理数据的系统和它所依赖的上游数据。
数据血缘有助于数据和处理数据的系统进行错误跟踪、问责和调试。它具有为数据生命周期提供审计跟踪的明显好处,并有助于合规性。例如,如果用户希望从你的系统中删除他们的数据,则拥有该数据的血缘可以让你知道该数据的存储位置及其依赖关系。
数据血缘在具有严格合规标准的大公司中已经存在了很长时间。然而,随着数据管理成为主流,它现在在较小的公司中得到更广泛的采用。我们还注意到,Andy Petrella的数据可观测性驱动开发(Data,Observability Driven Development,DODD)(https://oreil.ly/3f4WS)概念与数据血缘密切相关。DODD一直观测其血缘的数据。在开发、测试和最终生产过程中应用此过程,以提供符合预期的质量和一致性。
数据集成和互操作性
数据集成和互操作性是跨工具和流程的集成数据的过程。随着我们从单一栈分析方法转向异构云环境,该环境中的各种工具按需处理数据,集成和互操作性占据了数据工程师工作的越来越大的比重。
集成越来越多地通过通用API而不是自定义数据库连接进行。例如,数据管道可能从Salesforce API中获取数据,将其存储到Amazon S3,调用Snowflake API将其加载到表中,再次调用API运行查询,然后将结果导出到S3,Spark可以消费它们。
所有这些活动都可以通过与人的数据系统对话的相对简单的Python代码来管理,而不是直接处理数据。虽然与数据系统交互的复杂性降低了,但系统的数量和管道的复杂性却急剧增加。白手起家的工程师很快就超越了定制脚本的能力,并偶然发现了对编排的需求。编排是我们的底层设计之一,我们将在2.25节中详细讨论它。
数据生命周期管理
数据湖的出现鼓励组织忽视数据归档和销毁。当你可以无限地添加更多存储空间时,为什么要丢弃数据?两个变化促使工程师更加关注数据工程生命周期结束时发生的事情。
首先,数据越来越多地存储在云端。这意味着我们有即付即得的存储成本,而不是本地数据湖的大量前期资本支出。当每个字节都显示在AWS月度报表上时,CFO就会看到节省开支的机会。云环境使数据归档成为一个相对简单的过程。主要的云供应商提供特定于归档的对象存储类,允许以极低的成本长期保留数据,假设访问频率非常低(应该注意的是,数据检索并不那么便宜,但这是另一个话题)。这些存储类别还支持额外的策略控制,以防止意外或关键档案的故意删除。
其次,GDPR和CCPA等隐私和数据保留法律要求数据工程师积极管理数据销毁,以尊重用户的“被遗忘权”。数据工程师必须知道他们保留了哪些消费者数据,并且必须具有销毁数据的程序以响应请求和合规性要求。
数据销毁在云数据仓库中很简单。SQL语义允许删除符合where子句的行。数据销毁在数据湖中更具挑战性,其中一次写入、多次读取是默认的存储模式。Hive ACID和Delta Lake等工具可以允许大规模删除事务的轻松管理。新一代元数据管理、数据血缘和编目工具也将简化数据工程生命周期的结束。
道德与隐私
过去几年的数据泄露、错误信息和数据处理不当清楚地表明了一件事:数据会影响人。过去生活在狂野西部的数据,像棒球卡一样自由收集和交易。那些日子已经一去不回。尽管数据的伦理和隐私影响曾经被认为是很好的,就像安全一样,但它们现在是一般数据生命周期的核心。数据工程师需要在没人注视的时候做正确的事,因为总有一天每个人都会关注[6]。我们希望更多的组织鼓励良好的数据道德和隐私文化。
道德和隐私如何影响数据工程生命周期?数据工程师需要确保数据集掩盖个人身份信息(Personally Identifiable Information,PII)和其他敏感信息,可以在转换数据集时识别和跟踪偏见。监管要求和合规处罚只会越来越多。确保你的数据资产符合越来越多的数据法规,如GDPR和CCPA。请认真对待这件事。我们在整本书中提供了技巧,以确保你将道德和隐私纳入数据工程生命周期。
2.2.3 DataOps
DataOps将敏捷方法、DevOps和统计过程控制(Statistical Process Control,SPC)的最佳实践映射到数据。DevOps旨在提高软件产品的发布和质量,而DataOps则针对数据产品也是做同样的事情。
数据产品与软件产品的区别在于数据的使用方式。软件产品为终端用户提供特定的功能和技术特性。相比之下,数据产品是围绕合理的业务逻辑和指标建立的,其用户可以做出决策或构建执行自动化操作的模型。数据工程师必须了解构建软件产品的技术方面以及将创建优秀数据产品的业务逻辑、质量和指标。
与DevOps一样,DataOps大量借鉴了精益生产和供应链管理,混合人员、流程和技术以缩短实现价值的时间。正如Data Kitchen(DataOps专家)所描述的那样[7]:
DataOps是技术实践、工作流、文化规范和架构模式的集合,能够实现:
• 快速创新和实验,以更快的速度为客户提供新的见解
• 极高的数据质量和极低的错误率
• 跨复杂的人员、技术和环境阵列进行协作
• 结果的清晰测量、监控和透明度
精益实践(如缩短交货时间和最大限度地减少缺陷)以及由此带来的质量和生产力改进是我们很高兴看到的在软件和数据运维方面的发展势头。
首先,DataOps是一套文化习惯。数据工程团队需要采用与业务沟通和协作、打破孤岛、不断从成功和错误中学习以及快速迭代的循环。只有这些文化习惯养成后,团队才能从技术和工具中获得最好的结果。
根据公司的数据成熟度,数据工程师可以选择将DataOps纳入整个数据工程生命周期的结构。如果公司没有预先存在的数据基础设施或实践,那么DataOps是一个非常新的机会,可以从第一天开始就融入其中。对于缺少DataOps的现有项目或基础设施,数据工程师可以开始将DataOps添加到工作流中。我们建议首先从可观测性和监控开始,了解系统性能,然后添加自动化和事件响应。数据工程师可以与现有的DataOps团队一起工作,以改善数据成熟公司的数据工程生命周期。在所有情况下,数据工程师都必须了解DataOps的理念和技术方面。
DataOps具有三个核心技术要素:自动化、可观测性和监控以及事件响应(如图2-8所示)。让我们看看这些部分以及它们与数据工程生命周期的关系。
图2-8:DataOps的三大支柱
自动化
自动化可确保DataOps流程的可靠性和一致性,并允许数据工程师快速部署新产品功能和对现有工作流程进行改进。DataOps自动化具有与DevOps类似的框架和工作流,包括变更管理(环境、代码和数据版本控制)、持续集成/持续部署(CI/CD)和配置即代码。与DevOps一样,DataOps实践监控和维护技术与系统(数据管道、编排等)的可靠性,并增加了检查数据质量、数据/模型漂移、元数据完整性等的维度。
让我们简要讨论一下在一个假想组织中DataOps自动化的演变。DataOps成熟度较低的组织通常会尝试使用cron作业来安排数据转换过程的多个阶段。这在一段时间内效果很好。随着数据管道变得越来越复杂,可能会发生几件事情。如果cron作业托管在云实例上,则该实例可能存在操作问题,导致作业意外停止运行。随着作业之间的间隔越来越小,一个作业最终会运行很长时间,导致后续作业失败或产生陈旧数据。在从分析师那里得知报告已过时之前,工程师可能不会意识到作业失败。
随着组织数据成熟度的增长,数据工程师通常会采用编排框架,可能是Airflow或Dagster。数据工程师意识到Airflow会带来操作负担,但编排的好处最终会超过其复杂性。工程师们会逐渐将他们的cron作业迁移到Airflow作业。现在,我们在作业运行之前检查依赖关系。可以在给定时间内打包更多转换作业,因为每个作业都可以在上游数据准备就绪后立即开始,而不是在固定的、预先确定的时间开始。
数据工程团队仍有改进操作的空间。一位数据科学家最终部署了一个已损坏的DAG,导致Airflow网络服务器瘫痪,并使数据团队无法操作。经过足够多的此类麻烦之后,数据工程团队成员意识到他们需要停止允许手动DAG部署的行为。在下一阶段的运营成熟度中,他们采用自动化DAG部署。DAG在部署前需经过测试,监控过程确保新的DAG开始正常运行。此外,数据工程师会阻止新Python依赖项的部署,直到安装得到验证。在采用自动化后,数据团队会更快乐,遇到的麻烦也会少得多。
DataOps宣言(https://oreil.ly/2LGwL)的宗旨之一是“拥抱变化”。这并不意味着为了改变而改变,而是以目标为导向的改变。在我们自动化之旅的每个阶段,都存在改进运营的机会。即使达到我们在此描述的高度成熟度,仍存在进一步改进的空间。工程师可能会采用下一代编排框架,并在其中建立更好的元数据功能。或者他们可能会尝试开发一个框架,根据数据血缘规范自动构建DAG。要点是工程师不断寻求实施自动化改进,以减少他们的工作量并增加他们为业务提供的价值。
可观测性和监控
正如我们告诉客户的那样,“数据是一个无声的杀手”。我们已经看到不良数据在报告中持续数月或数年的无数个例子。管理人员可能会根据这些不良数据做出关键决策,但直到很久以后才发现错误。结果通常很糟糕,有时对企业来说是灾难性的。倡议被破坏和摧毁,多年的工作被浪费了。在某些最坏的情况下,不良数据可能导致公司陷入经济崩溃。
另一个可怕的故事是为报告创建数据的系统随机停止工作,导致报告延迟数天。数据团队在利益相关者询问为什么报告延迟或产生陈旧信息之前并不知情。最终,各个利益相关者对核心数据团队的能力失去了信任,开始了自己的分裂团队。其结果是许多不同的不稳定系统、不一致的报告和孤岛。
如果你不观测和监控你的数据和生成数据的系统,你将不可避免地经历自己的数据恐怖故事。可观测性、监控、日志记录、警报和跟踪对于在数据工程生命周期中提前解决任何问题都是至关重要的。我们建议你合并SPC以了解正在监控的事件是否异常以及哪些事件值得响应。
本章前面提到的Petrella的DODD方法为思考数据可观测性提供了一个很好的框架。DODD很像软件工程中的测试驱动开发(Test-Driven Development,TDD)[8]:
DODD的目的是让数据链中的每个人都能看到数据和数据应用程序,以便数据价值链中的每个人都能够从获取到转换再到分析的每个步骤中识别数据或数据应用程序的变化,以帮助解决或防止数据问题。DODD专注于使数据可观测性成为数据工程生命周期中的首要考虑因素。
我们将在后面的章节中介绍整个数据工程生命周期中监控和可观测性的许多方面。
事件响应
使用DataOps的高效数据团队将能够快速交付新的数据产品。但错误会不可避免地发生。一个系统可能会停机,一个新的数据模型可能会破坏下游报告,一个ML模型可能会变得陈旧并提供错误的预测——无数的问题都会中断数据工程的生命周期。事件响应关于使用前面提到的自动化和可观测性功能来快速识别事件的根本原因并尽可能可靠和快速地解决它。
事件响应不仅仅与技术和工具有关——尽管这些都是有益的,还涉及数据工程团队和整个组织的开放和无责的沟通。正如Amazon Web Services的首席技术官Werner Vogels所说的那样,“所有的东西都会坏掉”。数据工程师必须为灾难做好准备,以尽可能迅速且有效地做出响应。
数据工程师应该在业务报告问题之前主动发现问题。失败发生了,当利益相关者或终端用户看到问题时,他们会提出问题。他们会不高兴这样做。当他们向团队提出这些问题并看到他们已经在积极努力解决时,感觉是不同的。作为终端用户,你更信任哪个团队的状态?信任需要很长时间才能建立,也可能在几分钟内失去。事件响应既是对事件的追溯响应,也是在事件发生之前主动解决事件。
数据运维总结
在这一点上,DataOps仍是正在进行的一项工作。实践者在将DevOps原则应用于数据领域并通过DataOps宣言和其他资源制定初步愿景方面做得很好。数据工程师最好将DataOps实践作为他们所有工作的高度优先事项。前期的努力通过更快的产品交付、更高的可靠性和数据准确性以及更高的业务整体价值,将获得显著的长期回报。
与软件工程相比,数据工程的运营状态还很不成熟。许多数据工程工具,尤其是传统的单机,并不是自动化优先的。最近出现了在整个数据工程生命周期中采用自动化最佳实践的进展。Airflow等工具为新一代自动化和数据管理工具铺平了道路。我们为DataOps描述的一般实践是有抱负的,我们建议公司鉴于当今可用的工具和知识,尝试尽可能充分地采用它们。
2.2.4 数据架构
数据架构反映了支持组织长期数据需求和战略的数据系统的当前和未来状态。由于组织的数据需求可能会快速变化,而且新工具和实践几乎每天都会出现,因此数据工程师必须了解良好的数据架构。第3章将深入介绍数据架构,但我们想在这里强调数据架构是数据工程生命周期的一个底层设计。
数据工程师应该首先了解业务需求并收集新用例的需求。接下来,数据工程师需要将这些需求转化为设计新方法去捕获和提供数据,并在成本和操作简单性之间取得平衡。这意味着了解设计模式、技术和源系统、获取、存储、转换和服务数据的工具之间的权衡。
这并不意味着数据工程师就是数据架构师,因为两者通常是两个独立的角色。如果数据工程师与数据架构师一起工作,则数据工程师应该能够交付数据架构师的设计并提供架构反馈。
2.2.5 编排
我们认为编排很重要,因为我们认为它确实是数据平台和数据生命周期的重心,涉及数据的软件开发生命周期。
——Nick Schrock,Elementl创始人[9]
编排不仅是DataOps的核心流程,也是数据作业工程和部署流程的关键部分。那么,什么是编排?
编排是协调许多作业以尽可能快速且高效地按照预定节奏运行的过程。例如,人们经常将Apache Airflow等编排工具称为调度器。这不太准确。一个纯粹的调度程序,比如cron,只知道时间;编排引擎在作业依赖性元数据中构建,通常是有向无环图(Directed Acyclic Graph,DAG)的形式。DAG可以运行一次,也可以按固定时间间隔运行,如每天、每周、每小时、每5分钟等。
当我们在整本书中讨论编排时,我们假设编排系统以高可用性保持在线。这允许编排系统在没有人为干预的情况下持续感知和监控,并随时运行在部署的新作业。编排系统监视它所管理的作业,并在内部DAG依赖关系完成时启动新任务。它还可以监控外部系统和工具,以观察数据是否到达以及是否满足标准。当某些条件超出界限时,系统还会设置错误条件并通过电子邮件或其他渠道发送警报。你可以将每日通宵数据管道的预期完成时间设置为上午10点。如果此时还没有完成作业,则会向数据工程师和消费者发出警报。
编排系统还构建作业历史记录功能、可视化和警报。高级编排引擎可以在新的DAG或到DAG添加单个任务时回填。它们还支持一个时间范围内的依赖关系。例如,月度报告作业可能会在开始前检查ETL作业是否已完成整月的工作。
长期以来,编排一直是数据处理的关键功能,但除了大公司以外,通常不是最重要的,也不是任何人都可以使用的。企业使用各种工具来管理作业流程,但这些工具价格昂贵,小型初创公司无法企及,而且通常没有可扩展性。Apache Oozie在21世纪10年代非常流行,但它是为在Hadoop集群中工作而设计的,很难在更加异构的环境中使用。Facebook在21世纪00年代后期开发了供内部使用的Dataswarm。这激发了Airflow等流行工具的灵感,Airbnb于2014年推出了该工具。
Airflow从一开始就是开源的,并被广泛采用。它是用Python编写的,因此可以高度扩展到几乎任何可以想象的用例。虽然存在许多其他有趣的开源编排项目,例如Luigi和Conductor,但Airflow可以说是目前的市场领导者。Airflow的到来恰逢数据处理变得更加抽象和易于访问,工程师们对协调跨多个处理器和存储系统的复杂流程越来越感兴趣,尤其是在云环境中。
在撰写本书时,几个新兴的开源项目旨在模仿Airflow核心设计的最佳元素,同时在关键领域对其进行改进。一些最有趣的例子是Prefect和Dagster,它们旨在提高DAG的可移植性和可测试性,使工程师能够更轻松地从本地开发转移到生产。Argo是一个围绕Kubernetes基元构建的编排引擎;Metaflow是Netflix的一个开源项目,旨在改进数据科学编排。
我们必须指出,编排严格来讲是一个批处理的概念。编排任务DAG的流式替代方案是流式DAG。流式DAG的构建和维护仍然具有挑战性,但Pulsar等下一代流式平台旨在显著减轻工程和运营负担。我们将在第8章详细讨论这些发展。
2.2.6 软件工程
软件工程一直是数据工程师的一项核心技能。在当代数据工程的早期(2000~2010年),数据工程师在低级框架上工作,并用C、C++和Java编写MapReduce作业。在大数据时代的顶峰时期(21世纪10年代中期),工程师们开始使用抽象出这些底层细节的框架。
这种抽象一直延续到今天。云数据仓库支持使用SQL语义的强大转换,像Spark这样的工具变得更加用户友好,从低级编码细节过渡到易于使用的数据框架。尽管有这种抽象,软件工程对数据工程仍然至关重要。我们简要讨论一下适用于数据工程生命周期的软件工程的几个常见领域。
核心数据处理代码
虽然变得更加抽象和易于管理,但核心数据处理代码仍然需要编写,并且贯穿于整个数据工程生命周期。无论是在获取、转换还是数据服务方面,数据工程师都需要精通和高效地使用Spark、SQL或Beam等框架和语言。我们反对SQL不是代码的观点。
数据工程师还必须了解正确的代码测试方法,如单元、回归、集成、端到端和冒烟。
开发开源框架
许多数据工程师积极参与开发开源框架。他们采用这些框架来解决数据工程生命周期中的特定问题,然后继续开发框架代码以改进其用例的工具并回馈社区。
在大数据时代,我们看到了Hadoop生态系统内数据处理框架出现了寒武纪大爆发。这些工具主要侧重于转换和服务数据工程生命周期的各个部分。数据工程工具的形成并没有停止或放缓,但重点已经从直接的数据处理转移到抽象的阶梯上。这种新一代开源工具可帮助工程师管理、增强、连接、优化和监控数据。
例如,从2015年至21世纪20年代初期,Airflow主导了编排领域。现在,一批新的开源竞争者(包括Prefect、Dagster和Metaflow)如雨后春笋般涌现,以修复Airflow的局限性,提供更好的元数据处理、可移植性和依赖性管理。编排的未来走向何方,谁也说不准。
数据工程师在开始设计新的内部工具之前,最好调查一下公开可用工具的概况,要密切关注与实施工具相关的总拥有成本(Total Cost of Ownership,TCO)和机会成本。很有可能已经存在一个开源项目来解决数据工程师想要解决的问题,这样他们会更好地合作而不是重新发明轮子。
流
流数据处理本质上比批处理更复杂,而且工具和范式可以说还没有那么成熟。随着流数据在数据工程生命周期的每个阶段变得越来越普遍,数据工程师面临着有趣的软件工程问题。
例如,join这种数据处理任务使用实时数据处理比批处理更加复杂,需要更复杂的软件工程。数据工程师还必须编写代码来应用各种窗口化方法。窗口化允许实时系统计算有价值的指标,如尾随统计数据。数据工程师有许多框架可供选择,包括用于处理单个事件的各种函数平台(OpenFaaS、AWS Lambda、Google Cloud Functions)或用于分析流以支持报告和实时处理的专用流处理器(Spark、Beam、Flink或Pulsar)。
基础设施即代码
基础设施即代码(Infrastructure as Code,IaC)将软件工程实践应用于基础设施的配置和管理。随着公司迁移到托管大数据系统[例如Databricks和Amazon Elastic MapReduce(EMR)]和云数据仓库,大数据时代的基础设施管理负担已经减轻。当数据工程师必须在云环境中管理他们的基础设施时,他们越来越多地通过IaC框架来完成,而不是手动启动实例和安装软件。几个通用和特定于云平台的框架允许基于一组规范的自动化基础设施部署。其中许多框架可以管理云服务和基础设施。还有一个使用容器和Kubernetes的IaC概念,使用像Helm这样的工具。
这些实践是DevOps的重要组成部分,允许版本控制和部署的可重复性。当然,这些功能在整个数据工程生命周期中都至关重要,尤其是在我们采用DataOps实践时。
流水线即代码
流水线即代码是当今编排系统的核心概念,它涉及数据工程生命周期的每个阶段。数据工程师使用代码(通常是Python)来声明数据任务和它们之间的依赖关系。编排引擎解释这些指令以使用可用资源运行步骤。
通用问题解决
在实践中,无论数据工程师采用哪种高级工具,他们都会在整个数据工程生命周期中遇到极端情况,这些情况要求他们解决所选工具范围之外的问题并编写自定义代码。在使用Fivetran、Airbyte或Matillion等框架时,数据工程师会遇到没有现有连接器的数据源,需要编写一些自定义的东西。他们应该精通软件工程以理解API、提取和转换数据、处理异常等。