Apache Iceberg数据时间旅行功能的潜在风险与应对策略

本文深入探讨Apache Iceberg时间旅行查询功能的隐藏成本与风险,包括存储开销、性能影响和合规挑战,并提供配置建议和最佳实践解决方案。

概述

Apache Iceberg是一个用于大型分析表的高性能开源表格式,支持表达性SQL、完整模式演进、隐藏分区、时间旅行和回滚、数据压缩以及通过Iceberg REST目录实现的互操作性。凭借其强大功能,Iceberg在数据湖和数据湖仓领域越来越受欢迎。

在本文中,我们将讨论最引人入胜的功能"时间旅行查询"的优缺点。我们还将讨论采用时间旅行功能时的注意事项。

什么是时间旅行查询?

我们可以检索表在给定时间点或给定版本的数据。简单来说,使用时间旅行,我们可以查询历史数据。公司使用时间旅行查询功能来跟踪数据和模式变更(变更数据捕获)、血缘关系或监管审计。意外数据恢复是时间旅行能力的主要用例。

Iceberg通过元数据文件支持时间旅行功能,这些文件有助于维护存储数据的不可变快照。让我们从高层次理解快照。每次通过插入、删除或更新操作更新Iceberg表时,Iceberg都会创建一个新快照。

每个快照都会导致创建以下文件:

  • 根元数据文件:包含整个表状态和模式的中央元数据文件
  • 清单列表:由根元数据文件引用的指向清单文件的文件
  • 清单文件:包含实际数据文件(如Parquet)路径的文件
  • 数据文件:包含以Parquet文件形式存储的实际表数据

利用上述文件基于时间的关系和层次结构,Iceberg实现了时间旅行能力。

快照的元数据文件层次结构:

潜在风险是什么?

时间旅行功能并非免费提供;它带来了一些额外的存储成本、操作/性能开销和合规风险。在决定时间/版本旅行的时间窗口之前,详细了解这些挑战非常重要。

  • 增加的存储成本:即使数据中的微小更改也可能导致创建新版本的数据和元数据文件。存储多个快照和数据文件版本会增加存储使用量。
  • 数据管理复杂性:需要定期识别、过期和清理更多的元数据和数据文件。还需要仔细配置以避免意外删除和过度保留。
  • 性能开销:时间旅行查询可能较慢,特别是如果查询指定范围内存在许多快照。此外,清理快照和旧数据文件会消耗计算资源,这可能进一步降低整体系统性能。
  • 安全和合规风险:这是一个不应忽视且必须妥善处理的严重领域。监管合规性,如FINRA、GDPR、CCPA和PCI DSS,有严格的数据保留、删除和归档规则。旧快照可能保留敏感或已删除的数据。此外,不合规数据只能从当前快照中删除,而不能从所有历史快照中删除。任何用户都可以执行时间旅行查询并访问已删除的数据。必须检测并删除所有包含已删除敏感数据的旧快照。大多数情况下,如果删除旧快照,未删除数据的历史记录将会丢失。因此,需要适当的分析和解决方案设计来处理这种情况。
  • 操作复杂性:如果您的系统需要备份和恢复策略,那么考虑多个版本将是一项复杂的任务。此外,在查询情况下,如果用户在查询中使用不同的快照,不同的用户可能会看到不同的结果。
  • 元数据性能下降:随着时间的推移,快照会累积,元数据文件会变得更大。元数据文件的内容变得复杂,因此增加了查询规划的内存需求。这使得任何表操作都非常缓慢。
  • 意外数据暴露:用户有时可能意外查询或恢复到过旧的快照,这将导致数据不一致。

选择时间旅行功能时考虑的步骤

理想情况下,这取决于用例,但这里我列出了一些在解决方案中需要考虑的通用要点。

  • 分析表上的写入和读取模式。某些用例可能需要使用时间旅行功能进行CDC(变更数据捕获),而某些数据分析可能使用时间旅行完成。可能需要回滚到特定快照。因此,根据快照生命周期的适当SLA(服务级别协议)设定期望。
  • 时间旅行不是SCD Type-2的替代品。宁愿正确设计缓慢变化维度模式类型2(SCD Type2),也不要依赖时间旅行来捕获数据变更。
  • 在Iceberg表创建期间,根据约定的SLA在表属性中定义快照的保留期。
  • 将快照过期作为表维护活动的一部分自动化。这可以按计划、按需或事件驱动进行。
  • 跟踪和监控谁访问了什么。使用经批准的框架和工具建立适当的审计跟踪。
  • 确保受监管合规约束的数据主体从所有当前和历史快照中删除。删除将创建另一个快照,因此请确保立即过期。
  • 通过一套适当的可观察性工具监控快照存储使用情况。
  • 如果需要,考虑时间旅行需求预算增加的存储。
  • 保持适当的血缘关系和跟踪,以记录模式和数据变更。
  • 建立清晰的文档和指南,以教育用户最佳实践、快照概念、复杂性以及优缺点。

参考示例代码

时间旅行查询:

1
SELECT * FROM iceberg_table FOR TIMESTAMP AS OF TIMESTAMP '2020-01-01 10:00:00 UTC'

版本旅行查询:

1
SELECT * FROM iceberg_table FOR VERSION AS OF 949530903748831860

将db.sample回滚到特定日期和时间:

1
CALL catalog_name.system.rollback_to_timestamp('db.sample', TIMESTAMP '2021-06-30 00:00:00.000');

将表db.sample回滚到快照ID 1:

1
CALL catalog_name.system.rollback_to_snapshot('db.sample', 1);

删除早于特定日期和时间的快照,但保留最后100个快照:

1
CALL hive_prod.system.expire_snapshots('db.sample', TIMESTAMP '2021-06-30 00:00:00.000', 100)

删除快照ID为123的快照:

1
CALL hive_prod.system.expire_snapshots(table => 'db.sample', snapshot_ids => ARRAY(123))

创建具有快照属性的表:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
CREATE TABLE my_catalog.my_db.sample_table
(
    id BIGINT,
    data STRING,
    event_ts TIMESTAMP
) USING iceberg
OPTIONS (
    'format-version'='2',
    'history.expire.max-snapshot-age-ms'='432000000',
    'history.expire.min-snapshots-to-keep' = 5
)

结论

Apache Iceberg的时间旅行能力对于执行历史数据分析和回滚来说是一个非常引人入胜的功能。然而,它需要适当的需求分析、周密的实施以及定期管理,以避免任何意外的成本和合规风险。组织在扩展历史数据分析和恢复的时间旅行窗口之前,应考虑监管合规要求以及操作复杂性。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计