大规模数据工程需要高效地构建、转换和分析数据集。Medallion 架构是一种用于数据工作流的设计模式,通过分层转换来组织和提高数据质量,已成为管理复杂数据集的广泛采用的方法。传统上,这种工作流使用 Spark 和 Delta Lake 等工具实现,确保原始的“混乱”数据可以系统地提炼成干净、高质量的数据集,为最终用户分析和应用程序做好准备。
在这篇博文中,我们将探讨如何完全使用原生 ClickHouse 构造来实现 Medallion 架构,从而消除对任何外部框架或工具的需求。凭借其领先的查询性能、对各种数据格式的支持以及用于管理和转换数据的内置功能,ClickHouse 可用于有效地实现架构的每个阶段。
虽然这篇文章旨在展示 Medallion 架构的三个阶段如何在理论上使用 ClickHouse 构建,但后续文章将使用 Bluesky 数据集的实时馈送实际演示这一点。该数据集包含许多常见的数据挑战,包括格式错误的事件、高重复率和时间戳不一致,非常适合展示下面描述的过程。
什么是 Medallion 架构?
Medallion 架构是一种广泛使用的数据工作流,用于将数据组织成一个分层结构,其中数据质量随着数据在各个阶段的推进而逐步提高。虽然 Medallion 架构广泛应用于数据湖仓,但它也可以应用于实时数据仓库,作为实现高效数据管理和转换的一种手段。
该架构包括三个层(或阶段),每个层在数据管道中服务于不同的目的
- 青铜层 - 此层充当来自源系统的原始、未处理数据的着陆区:简而言之,就是一个“暂存区”。此数据以其原始结构存储,进行最少的转换和添加元数据。此层针对快速摄取进行了优化,并且可以提供源数据的历史存档,始终可用于重新处理或调试。
青铜层是否应存储所有数据是一个有争议的点,一些用户更喜欢过滤数据并应用转换,例如,展平 JSON、重命名字段或过滤掉格式错误的数据。我们在此处没有过多的意见,但建议优化存储,以便仅供银层使用 - 而不是其他消费者。
-
白银层 - 在这里,数据被清理、去重并符合统一的模式,来自先前青铜层的原始数据被丰富和转换,以提供更准确和一致的视图。此数据可以是一致且可用于企业范围的用例,例如机器学习和分析。数据模型应在此层中出现,重点是确保主键和外键一致,以简化未来的连接。虽然不常见,但应用程序和下游消费者可以从此层读取数据。这些通常是需要整个清理数据集的企业范围的应用程序,例如 ML 工作流。重要的是,数据质量在此阶段之后不会提高,只会提高查询效率的便利性。
-
黄金层 - 后者旨在拥有完全策划的、业务就绪的和项目特定的数据集,这些数据集使消费者更容易(且性能更高)访问数据。这些数据集通常是反规范化的或预聚合的,以实现最佳读取性能,并且可能由先前银层中的多个表组成。此处的重点是应用最终转换并确保最高的数据质量,以供最终用户或应用程序(例如报告和面向用户的仪表板)使用。
这种分层的数据管道方法旨在有效地解决数据质量、重复和模式不一致等挑战。通过逐步转换原始数据,Medallion 架构旨在确保清晰的沿袭和逐步细化的数据集,这些数据集已准备好用于分析或操作用途。
虽然我们发现 Medallion 架构的命名可能不够好,因为它没有直接传达各层的内容,但可以从每一层提取有用的过程,以及它有助于实施的纪律。
使用 ClickHouse 的 Medallion 架构
在本节中,我们建议如何使用 ClickHouse 实现 Medallion 架构的每一层,以及如何使用原生功能在它们之间移动数据。这代表了一种基于我们内部经验和用户见解的灵活且不断发展的方法,我们欢迎反馈以进一步完善这些实践。
使用 ClickHouse 的青铜层
青铜层充当原始、未处理数据的入口点,针对使用 ClickHouse 灵活且高性能的构造进行高吞吐量摄取进行了优化。它可能充当历史存档,可以保留原始数据以进行沿袭、调试或重新处理,而无需预先进行完整的清理或去重。这种对性能和灵活性的关注为后续阶段的下游细化和转换奠定了坚实的基础。
使用 ClickHouse 实现时,青铜层的关键功能包括
从源摄取
数据可以直接通过客户端、Fivetran 等 ELT 工具摄取到此层,或者使用 ClickPipes 或 ClickHouse Kafka 连接器从 Kafka 消费流。S3Queue 和 ClickPipes(在 ClickHouse Cloud 中)提供了额外的选项,用于从 S3 存储桶中以超过 70 种数据格式(可选压缩)增量读取数据,包括 Parquet 和湖格式(如 Iceberg)。当处理模式不太一致的较大半结构化数据时,使用 S3 作为暂存区的方法尤为常见。
针对快速插入的优化
我们的青铜层通常使用 MergeTree 实现,MergeTree 旨在高效处理快速插入。表的模式和排序键旨在支持高效的插入操作,同时在需要将数据重播(到白银层)或探索数据质量问题时也能够实现高性能读取。鉴于此层不会服务于消费者,我们建议优化排序键以实现高效的全数据扫描,即使用与读取顺序一致的排序键 - 通常是时间。
支持半结构化 JSON 数据
ClickHouse 中的新 JSON 类型 是处理青铜层中半结构化数据的关键功能。此类型允许摄取动态和不可预测的模式,而无需预先强制执行严格的模式,这使其对于具有不一致或不断发展的结构的数据集尤其有价值。通过支持高度动态的 JSON,青铜层成为原始数据的有效着陆区,适应模式一致性无法保证的场景。请注意,JSON 类型 允许应用过滤规则,以控制保留哪些对象路径。用户可能还希望在存储在此层之前过滤掉所有无效 JSON,并可能展平复杂的结构。
此类型的使用不限于青铜层,在其他层中也有有效的应用,例如,对于按设计包含动态模式的列,例如用户标签。
用于基本处理的物化列
物化列提供了一种强大的机制,用于在摄取期间提取和转换特定字段。虽然范围有限,但它们可以通过为常用查询属性创建派生列来有效处理 JSON 数据。在 JSON 数据包含不规则路径或结构的情况下,这种方法特别有用,允许进行基本预处理,而无需完全强制执行模式的开销。这些提取的列也常用于后续的条件过滤。
分区和数据保留
青铜层表可以进行分区以优化查询性能并实现高效的数据管理。TTL 规则建议用于过期不再需要的旧数据,从而确保合规性和高效的存储使用。
使用 ClickHouse 的白银层
白银层代表 Medallion 工作流的下一阶段,将来自青铜层的原始数据转换为更一致和结构良好的形式。此层解决数据质量问题,例如过滤掉无效行、标准化模式和执行转换。使用 ClickHouse,我们通常看到青铜表直接映射到白银等效表,但具有更干净、更丰富的数据集,作为黄金层中高级呈现的基础。
增量物化视图
白银层通常使用附加到青铜层的增量物化视图填充。这些视图对新插入到青铜层的数据块执行查询,这些查询在将结果写入白银层表以进行持久化之前,应用过滤、转换和模式规范化。这些视图实现了高效且持续的数据转换,通过附加多个视图,用户可以创建不同版本的数据,每个版本都针对特定的白银层表,以用于不同的下游用例。此外,无效或无法处理的行可以通过单独的物化视图重定向到死信队列,允许检查和潜在恢复,而不会污染主数据集。
处理去重和 CDC
对于需要去重或处理变更数据捕获 (CDC) 流的用例,可以使用 ReplacingMergeTree 表引擎。此引擎的排序键用于执行去重(具有唯一值集以标识行),更新被摊销为版本化插入 - 在 CDC 场景中特别有用。请注意,ReplacingMergeTree 执行合并时去重,因此仅最终一致,需要在查询时使用 FINAL 运算符以确保结果中零重复。通常,我们建议下游应用程序谨慎从此层读取数据,因为此子句可能会产生显着的查询时间开销。
分区和数据保留
与青铜层类似,白银层表也可以进行分区,以优化查询性能和数据管理,并使用 TTL。分区还可以提高性能,当从 ReplacingMergeTree 表中读取带有 FINAL
的表时。我们建议用户遵循最佳实践,例如优化合并操作以保持性能。由于此层不充当长期存档,并且可能不作为下游用例的来源使用,因此与青铜层和黄金层相比,数据可能在此层中保留较短的时间,分区可能在较短的时间段内进行。
使用 ClickHouse 的黄金层
黄金层代表 Medallion 架构的最终阶段,其中数据被策划成完全反规范化的、业务就绪的数据集,这些数据集针对最终用户应用程序和分析的消费进行了优化。黄金层从白银层使用可刷新物化视图填充,这些视图执行复杂的转换,包括连接和聚合。这确保数据处于最可用的形式,最大限度地减少了查询时连接甚至聚合的需求。黄金层表旨在提供高性能,以最小的延迟和最高的效率支持下游应用程序。
可刷新物化视图
与用于填充白银层的增量物化视图不同,黄金层使用可刷新物化视图填充。这些视图定期针对银层表执行,并实现高级转换,例如复杂的连接,这些连接在将数据写入黄金层表之前对数据进行反规范化。当从使用 ReplacingMergeTree 的银层表获取数据时,这些视图可以执行带有 FINAL 运算符 的查询,以确保将完全去重的数据插入到黄金层中。这种方法确保了最高的数据质量,同时保留了处理高级查询要求的灵活性。
下游应用程序的表设计
黄金层中的表通常使用标准 MergeTree 表实现,并使用 专门针对下游应用程序的访问模式优化的排序键。这些反规范化的数据集经过结构化,最大限度地减少了对额外连接的需求,使应用程序能够执行快速、高效的读取。通过根据最终用户查询的要求定制模式和键,这些表提供了与报告工具、仪表板和交互式用户体验的无缝集成。
用于预计算聚合的增量物化视图
除了存储反规范化的数据集外,黄金层通常还包括用于预计算聚合的增量物化视图。这些视图对新插入到黄金层表的 GROUP BY
查询执行,并使用 AggreatingMergeTree 引擎 将中间聚合结果写入目标表。将计算从查询时转移到插入时显着降低了查询延迟。反过来,下游查询只需要合并较小的中间状态,使其具有高性能,并适用于为具有丰富过滤和聚合功能的面向用户的应用程序提供支持。
我们的演示应用程序 ClickPy 大量利用物化视图来提供对万亿行 Python PYPI 数据集的可视化和过滤功能。有关更多详细信息,请参阅 clickPy GItHub 存储库。
完整的基于 ClickHouse 的 Medallion 架构
组合上述每个阶段,我们得到了完整的基于 ClickHouse 的 Medallion 架构
这种使用 ClickHouse 实现的 Medallion 架构提供了一种结构化的方法,可通过分层转换来管理数据管道。通过支持超过 70 种文件格式,原始数据可以使用 s3Queue 或 Clickpipe 功能(在 ClickHouse Cloud 中)直接摄取到青铜层,然后在白银层中逐步细化和丰富,最后在黄金层中策划,以供应用程序和分析最佳消费。利用 ClickHouse 的 MergeTree 表(增量/可刷新)物化视图和对各种文件格式的支持,此架构无需依赖外部工具即可实现数据摄取、转换和交付。
请注意,用户不必部署此架构的所有三个阶段,并且可以删除任何层。例如,如果数据交付时数据质量问题最少且没有重复项,则用户可能希望跳过白银阶段。
虽然此处的优势令人信服,并且有一套清晰的方法和工具可以向最终用户和应用程序交付干净、优化的数据,但此架构确实存在一些缺点。
黄金表本身以多种方式呈现相同的数据,每种方式都针对其消费应用程序进行了优化,从而导致需要复制数据。但是,相关的数据复制成本可以通过使用对象存储来实现缓解,用于存储带有存储和计算分离的 MergeTree 表。
此外,该架构需要管理多个层,从而增加了数据管道的复杂性。这需要监控,可以通过 ClickHouse 系统表 来实现,这些系统表提供了对 物化视图 和数据迁移过程状态的可见性,而 Grafana 等工具可以借助 ClickHouse 数据源 针对视图故障或数据差异等问题发出警报。
更难缓解的是此架构固有的数据可用性延迟,这是因为数据需要系统地通过每一层。因此,对于数据可用性至关重要的实时用例,此架构更难以优化。
结束语和结论
使用 ClickHouse 的 Medallion 架构演示了一种强大、自包含的方法来管理数据工作流,从而实现摄取、转换和消费。通过利用 ClickHouse 的原生功能,组织可以构建高效、可扩展的管道,从而为分析和应用程序交付干净、优化的数据集。
ClickHouse 实现的突出特点是其自包含方法。所有数据摄取、转换和消费都在 ClickHouse 本身内进行,而无需外部工具。
在我们的下一篇博客中,我们将展示为 Bluesky 数据构建 Medallion 架构的实际部署的步骤,该架构托管在 sql.clickhouse.com 上,您可以在其中直接探索和查询架构的每一层。敬请期待!