「妙手数评」Picnic 的无湖数据仓库
Picnic数据建设系列一:揭示我们单一事实来源背后的技术和架构
在 Picnic,我们为拥有数据仓库 (DWH) 感到自豪,它涵盖了我们业务的所有方面并在组织中被广泛采用。我们通过不断兑现三个承诺来实现这一目标:
- 具有关键绩效指标 (KPI) 集中逻辑的单一事实来源。
- 数据质量高,结构直观,值得信赖的数据源。
- 针对任何业务问题在一个地方提供根本原因分析支持。
注意:这只是关于 Picnic 数据工程的五篇系列博文中的第一篇。它是关于技术和架构的当前状态。未来,我们还将探索诸如用数据解决的业务挑战、我们的技术堆栈演变以及高效数据团队背后的原则等主题。单击跟随按钮以保持循环。
设置场景上下文
Picnic 是欧洲发展最快的网上超市。我们是可持续的,我们努力减少食物浪费,我们深切关心我们的客户。我们的核心是一家数据驱动的科技公司,我们正在利用这种专业知识来解决在线杂货店购物的挑战。
作为数据工程团队,我们为基于数据的决策构建技术基础。从Picnic的第一天起,我们就一直在开发数据仓库——我们团队的主要产品。从本质上讲,这是一个包含我们所有数据和知识的庞大库,可帮助企业做出更明智、更明智的决策。
现在,当我们庆祝 Picnic 的五岁生日和每天数以千计的交付时,我很高兴在五篇博文中分享我的团队的旅程。这是一次狂野、冒险和动感十足的旅程!
数据仓库揭晓
我们的业务分析师和数据科学家不必担心数据来源、清理、解密和存储等技术问题。当数据存储中存在模式时,数据可发现性很容易。此外,表和列的良好文档可确保正确使用源。
我们严重依赖 Data Vault 和 Dimensional Kimball 建模来构建我们的数据仓库。为确保最高质量,我们在源系统中建立了消费者驱动的合同。对于每个新的 DWH 资源管理器,此技术设置与 SQL 中的入门程序相辅相成。同时,我们遵循数据治理和安全访问控制方面的最佳实践。
数据工程师从整个供应链的所有系统中获取数据,并使业务分析师和数据科学家能够专注于创建洞察力和机器学习算法的增值活动。
以下是一些数字,可以让我们了解当前的规模:
- DWH 有 120 个(微)服务源。
- 每天运行大约 1000 个 ETL/ELT 作业来捕获和聚合数据。
- 我们总部约 50% 的技术职位以外的员工拥有 SQL 技能。
- 业务分析师平均每天运行 300 个 SQL 查询。
- 我们的 DWH 包含 15,000 个表、247,000 个字段和 1210 亿行。
只有九名数据工程师支持所有这些!只有在我们的数据管道中实现显着的自动化以及对结构、模式和质量的不懈关注,才能以如此少的人管理这样的规模。
数据工程技术栈
我们有意保持数据工程技术堆栈的精简。作为一个快速发展的组织,我们需要掌握轻量级但功能强大的技术来跟上业务发展的步伐。这些工具必须足够通用,以适应不断变化的业务需求。
Picnic的数据工程技术栈:
- Python、Snowplow、Stitch、RMQ;
- Snowflake;
- SQL;
- Tableau、Slack;
- Kubernetes、Travis、Python、Argo、GitHub
Python:数据集成和 ETL/ELT 流程
Extract Transform Load (ETL),或者更现代的版本,Extract Load Transform (ELT),是负责捕获 DWH 中的历史数据并应用业务逻辑进行分析消费的作业。在 Picnic,ELT 是用 Python 实现的,它使用高度自动化在 DWH 中加载数据。除了自动化管道,我们还有用于识别结构和语义问题的异常检测工作。
在不同的流程中,我们使用公共和内部库来构建我们的工作。不到 0.5% 的运行以失败状态结束(触发 PagerDuty 警报),但我们会尽快处理每个警报并采取纠正措施。大多数情况下,警报的原因是从源系统部署了向后不兼容的功能。在这些情况下,我们会直接与各自的开发团队合作,以避免未来发生任何事件。
Snowflake:为云打造的数据仓库
在 Picnic,Snowflake 是首选的云数据仓库。 Snowflake 支持最常见的 SQL 标准化版本 ANSI,用于关系数据库查询。它还带有许多扩展,包括强大的 JSON 解析、自动摄取 Snowpipe 和其他内置函数。
Snowflake 的一项引人注目的功能是存储和计算资源的分离。这对我们很有好处,因为我们有大量数据需要存储在一个地方并以各种方式使用。我们的 DWH 构建在不同的数据库中——每个国家一个,多个模式——每个数据建模技术一个。我们欣赏的另一个功能是通过 Snowpipe(Snowflake 中的本机数据管道)从 S3 自动摄取数据,实现近实时数据摄取并减少 ETL/ELT 代码。
Picnic 的每位业务分析师(大约有 150 名!)都接受过 SQL 培训。在通过了一些挑战后,他们通过 SQL 获得了对 Snowflake 的读取权限。这种为广泛的 SQL 访问开放 DWH 的方式在 Picnic 上取得了巨大的成功。开始一年后,我们进行了一项调查以评估该计划。超过 95% 的分析师表示生产力有所提高。
Tableau:仪表板和数据可视化
Tableau 用作商业智能 (BI) 可视化和仪表板软件。它是我们五年前在 Picnic 运营之初采用的工具之一,时至今日,已被广泛使用。
DWH 报告层的大部分表都可以作为 Tableau 中的来源,我们将它们命名为与 Snowflake 中的事实表名称一致。我们使用托管服务 Tableau Online,每个市场都有单独的站点。这种多站点设置是企业架构的一部分,用于从性能和安全角度隔离国家。
使用超过 90% 的等效数据结构和工作簿维护多个站点带来了一些独特的挑战。我们使用 Tableau API 构建了一个自动化流程,以获取访问权限的概览,并能够自动操作数据源。自动化的另一个示例是创建所有 Tableau 对象备份的过程,从而能够恢复意外删除的任何数据源或工作簿。
由于所有分析师都获得了 SQL 访问权限,我们看到 Tableau 仅用于可视化的使用有所增加。这种模式明显偏离了之前使用的“混合”和“细节级别”计算。繁重的逻辑现在在 SQL 中完成,利用 Snowflake 以高效的方式进行复杂的计算。对 DWH 的直接 SQL 访问导致了性能更高的 Tableau 仪表板和Picnic组织中真正的快乐。
Argo on Kubernetes:编排和部署
我们所有的作业都部署在 Amazon AWS 上的 Kubernetes 中,在隔离的 Pod 中运行。这确保了作业不会相互阻塞,并且它们使用自定义数量的计算资源。因此,我们支持并行执行 Data Vault 数据捕获过程。这是一个安全的部署,因为所有的秘密都安全地保存在 Vault 中。
一些 ELT 作业每天运行几次,捕获增量更改。其他人每小时运行几次。这只能归功于作业的容器化。 Argo 允许我们使用环境变量和依赖项的配置来创建复杂的计划。
Snowplow:事件处理框架
对于近实时和批处理事件处理,我们使用 Snowplow 框架。 Snowplow 是一个事件数据收集平台,我们将其用于应用内和后端内部事件。要了解有关我们用例的更多信息,我推荐 D. Nedev 的博客文章“使用 Snowplow 的(一致的)应用分析”。
我们将事件的模式存储在 Iglu 存储库中。事件源自我们的后端系统并通过开源消息代理 RabbitMQ。除了将事件路由到 Snowplow 进行分析之外,我们还在 Picnic 中使用它进行服务之间的通信。
在 S3 上收集后,事件将通过 AWS Kinesis 进一步处理并加载到 Snowflake 中。所有内部后端事件都具有由生产者(所有者)系统验证的模式——显着降低了破坏更改的风险。
GitHub:版本控制和文档
我们不只是使用 Git 进行代码版本控制,以及管理我们的发布和拉取请求 (PR) 流程。对我们来说,GitHub 远不止这些。在这里,公司中的任何人都可以看到我们计算出的每个 KPI 背后的业务逻辑。
由于所有逻辑都在代码中——无论是 SQL 还是 Python——我们可以提供从源系统到聚合 KPI 的数据的透明度和完整沿袭。根据我们的经验,这是文档保持最新和完整的唯一地方。
应用的逻辑与 README 文件和注释位于同一空间,为决策提供上下文。它还可以轻松识别任何给定领域中知识最渊博的数据工程师。
用于组织数据仓库的数据建模框架
技术栈只是故事的一方面。另一个是我们如何使用这些工具。让我们深入了解数据仓库的架构。
就像一个功能强大的图书馆需要一个分类系统一样,一个可用且直观的数据仓库需要数据模型。事实上,数据建模是最关键但经常被忽视的数据工程技能之一。它使我们能够在混乱中创造和维持秩序。
图书馆的分类系统确保读者可以在一个合乎逻辑的地方找到他们想要的书,并且所有页面都完好无损。同样,数据模型为业务分析师和数据科学家提供了一张地图,因此他们可以准确地找到他们需要的东西——并确信它是正确的。
我们使用架构来构建我们的 DWH,以在不同的数据建模技术中描述数据,并且我们在后端和前端报告 DWH 层之间进行了严格分离。后端模式仅供数据工程师和数据科学家使用。同时,前端是一个 API,也可供业务分析师和开发人员使用,具体取决于他们的角色。 Data Vault 是后端 DWH 的主要建模技术,而 Dimensional Kimbal 是前端的主要建模技术。
我们的数据仓库由两层组成:前端和后端。此外,这些由多个模式实现,基于数据建模技术和功能进行拆分。
维度 Kimball 模型
我们向业务公开分析数据的首选方式是通过 Dimensional Kimball 模型。我们称其为我们的演示、报告或前端 DWH 层。我们交替使用这些术语。
DIMENSIONAL KIMBALL 模型非常适合围绕业务实体组织数据并强制执行一致的维度。因此,每当我们谈论产品、客户、履行中心、枢纽和电动汽车等实体时,我们总是在各自的维度中使用相同的主数据。我们的事实表涵盖从低级事务或事件数据到高度聚合的多维多维数据集。无论聚合级别如何,我们都会在一个地方维护 KPI 的逻辑,并允许进行根本原因分析。
我们还对维度模型进行了野餐风味的定制。除了基本数据类型,我们在事实和维度中公开了一些 JSON 字段。在非结构化数据时代,这是一个方便的扩展。它帮助我们在进行分析用例之前以受控方式公开非常详细的信息。
通常,此类字段是业务需求和快速原型设计的来源。例如,一个事实表包含一天内在给定履行中心发生的所有操作。这个事务性事实累积了数十万个事件。每个事件都可以是十几种类型中的一种,例如拣货、接收、库存移动、盘点或发货。
新类型的事件会定期发出,而不是阻止报告,我们通过在名为“event_raw”的 VARIANT 类型列中公开原始 JSON 有效负载将它们传递到事实表。仅对于最重要的实体,我们计算外键。在这种情况下,为所有可能涉及的实体创建密钥是多余的。它永远不会结束。因此,我们通过尽可能多地将源系统和 DWH 开发的新功能解耦来进行选择。
除了维度建模,在表示层,我们还有一个 SPECIALIZED MART 模式,其中包含业务可访问的表和视图。此模式包含有限数量的平面表,不适合 Kimball 维度建模。例如,在这里,我们有一些近乎实时的视图,它们可能没有可用的维度数据(还没有)和没有链接到其他任何东西的表格。
Data Vault
Data Vault (DV) 是一种用于捕获历史数据的现代数据建模技术。它的理念是“所有数据,所有时间”——与 Dimensional Kimball 模型形成对比,后者是“真相的单一版本”。如果部署得当,这两个是强大的二人组。我们仅将 DV 用作后端 DWH 层。
事实证明,结合两全其美对 Picnic 非常有价值。我们使用带有密钥散列的 DV v2.0,使我们能够轻松捕获卫星表中实体(集线器)和关系(链接)随时间的状态。
我们在 DATA VAULT 模式中有 1000 多个表,它非常适应业务方面的变化。例如,当关系基数发生变化时,我们可以在 DV 中轻松捕捉到这一点。
技术方面的变化也是如此。我们的后端系统从一个巨大的单体演变为一组微服务。借助 DV 建模,我们可以快速适应新的、更专业的来源——而且只需要衍生出新的卫星。
数据保险库的好处
DV 的主要优点是可追溯性功能、从并行增量加载中获得的性能以及丰富的时间序列数据。这对我们的数据科学团队很有用,使他们能够构建可靠的预测算法。它还使我们能够在 Dimensional Kimball 建模方面进行选择,并可以在需要时重建完整的表示层。
我们从 Picnic 开始就使用了 DV,我们在构建和维护它方面积累了很多经验。虽然开始可能是一个挑战,而且学习曲线很陡峭,但我们很高兴我们能够坚持完成早期阶段。
解决对 Data Vault 的一些常见批评
我们从其他数据团队那里听到了一些反对 DV 的论点,我们想简单地谈谈。
“DV 在数据建模方面过于冗长。”大量表是在捕获和使用数据进行历史分析时获得极大灵活性的代价。它还允许通过设计轻松分离敏感数据和完整的幂等变更数据捕获 (CDC)。在我看来,这是一个很小的代价。
由于方法非常简单,模型通常会在关于构建数据表的开放式讨论中节省大量时间。这些好处的大小可能不会立即显现出来,但经过多年收集的数据后会变得明显。在少数情况下,我们甚至使用 DV 作为来源来恢复数据以供操作使用。虽然我强烈推荐适当的备份和归档程序,但 DV 在极端情况下确实派上用场。
“DV 需要太多时间来运行新工作。”我认为这只是一个实现细节,而不是一个基本缺陷。如果没有自动化加载框架,维护数十个表就变成了一项挑战——更不用说数百个了。
在 Picnic,我们用 Python 构建了一个自主开发的解决方案,使我们能够在几小时而不是几天内实施新的 DV 域。该框架使用动态 SQL 实现了高度自动化,并且只需要四个要素进行配置:
- 提取的 Python 实现,因为它是自定义的。
- 带有目标 DV 结构配置的 YAML 文件。
- 用于硬业务逻辑转换的 SQL 脚本。
- 创建 DV 表时一次性执行 SQL 脚本。
我们的 DV 加载框架处理目标 DV 表的填充、CDC 哈希的计算以及事务的原子性。实施初始版本花费了一名数据工程师不少于四个月的全职开发时间。尽管如此,这为新管道带来了多年的稳定性和高速度。
使用临时表进行沙盒化和原型设计
Picnic 的另一个家庭发明的 DWH 架构元素是让用户控制对 DWH 的写访问。我们有一个名为 TEMP 的模式,我们每 24 小时清除一次。分析师有权创建表/视图并加载外部数据。
此功能使 DWH 成为分析的中心位置,数据来自 Excel 文件和 Google 表格——而不是相反。
即使对于完整的 DWH,也根本不可能包含业务所需的所有(新鲜)数据。因此,在架构中进行配置以允许可以与现有数据连接的导入是很有价值的。
我们每 24 小时清除一次此架构,以避免在没有所有者的情况下出现大量陈旧数据。如果分析师发现自己每天都在运行相同的 SQL 语句,那么下一步,数据工程师将在 SANDBOX 模式中更持久的区域中创建这些结构。然后,数据工程师有责任管理权限并确保在经过适当的同行评审开发过程后将其投入生产。
其他后端数据捕获模式
我们根据我们提供数据的机制定制后端 DWH。除了 DATA VAULT,我们还有专门用于 Snowplow 事件的 ATOMIC 模式。大多数数据在 JSON 对象中是非结构化的,在暴露之前,我们根据约定的事件模式对其进行解析。
类似地,操作数据存储 (ODS) 模式在数据从源系统到达时以第三范式保存数据。数据捕获通常没有变化,而是源的完整复制。 ODS 架构主要用于通过 Snowpipe 或第三方系统加载的业务映射和配置。 STITCH 是一个包含由第三方 ETL 解决方案提取的各种 ODS 导出的数据库。在可能的情况下,我们更喜欢使用它而不是编写我们自己的集成。
这里的一个例子是我们从公共 API 获取的天气数据。对于每个送货区域,我们查询天气预报和实际天气措施。这些数据有很多应用,例如了解雨天和黑暗中的下落持续时间或在温暖的日子里计划额外的冰袋。在 DV 中对此进行建模的努力超过了收益,因此我们决定按原样存储它。
我们的无数据湖方法
尽管我们以非结构化 JSON 格式捕获大量数据,但我们不称其为数据湖。我们坚信,即使数据是 JSON 格式,它仍然应该有一个严格的架构,并且这个架构是预先知道的。
在数据湖中如此常见的先捕获然后再考虑结构的过程不符合我们高度信任的 DWH 的愿景。根据我们的经验,数据湖通常在存在的最初几年内变成沼泽,更像是一个档案数据系统,而不是一个长期值得信赖的分析来源。
我们相信数据质量是每个数据项目的必备要求。没有它,任何机器学习工作都是无用的,业务决策充其量是有问题的。只有 3% 的公司符合基本数据质量标准,而在 Picnic,我们努力成为其中之一。
给您的建议
数据建模是保持高质量数据仓库的关键,企业信任该数据仓库并将其视为易于访问的库,以获得有意义的洞察力。结构化的数据和严格的数据治理保证了良好的质量。为了充分发挥其潜力,鼓励用户将其与 DWH 中专用区域中的自己的文件和映射结合起来。这种受控写入访问可确保敏感数据保持安全,同时鼓励组织内广泛采用 DWH。
除了数据建模在 DWH 架构中的重要性之外,维护一个非常精简的技术堆栈也是有益的。有很多好的工具,但要快速移动,我们需要保持轻量级。我们的多功能工具箱包括用于 ELT 的 Python、用于 DWH 的 Snowflake、用于可视化的 Tableau、用于编排作业的 Argo、用于部署的 Kubernetes、用于事件处理的 Snowplow 以及用于版本控制和代码文档的 GitHub。
我们对不受监管的数据湖采取强硬立场。相反,我们使用单一数据仓库为整个公司提供支持,并将数据工程团队视为数据驱动型组织中的加速器和推动者。我们渴望福尔摩斯雄辩的话语:“在拥有数据之前进行理论化是一个重大错误。人们不知不觉地开始扭曲事实以适应理论,而不是扭曲理论以适应事实。”在本系列的下一篇博文中,我将分享我们使用数据解决的一些谜团。