2

我相信 Hadoop 的一个常见使用模式是通过加载来自操作系统的数据的常规(例如每日)快照来构建一个“数据湖”。对于许多系统,每天的变化率通常小于 5% 的行(即使更新了一行,也只有少数字段可能发生变化)。

Q:这样的历史数据如何在HDFS上结构化,既节省空间,又高效访问。

当然,答案将取决于通常如何访问数据。在我们的 Hadoop 集群上:

  • 大多数作业只读取和处理最新版本的数据
  • 少数作业处理一段时间的历史数据(例如 1 - 3 个月)
  • 一些作业处理所有可用的历史数据

这意味着,尽管保留历史数据很重要,但不应该以严重减缓那些只想知道昨天收盘时数据的情况的工作为代价。

我知道一些选项,但似乎都不太令人满意:

  1. 将每个完整转储独立存储为新的子目录。这是最明显的设计,简单,并且与 MapReduce 范式非常兼容。我确信有些人使用这种方法,但我想知道他们如何证明存储成本是合理的?假设每天加载 1Tb,那么每年向集群添加 365Tb,其中大部分是重复数据。我知道现在磁盘很便宜,但大多数预算制定者习惯于基础设施与业务增长成比例地扩展,而不是随着时间的推移线性增长。

  2. 仅存储与前一天的差异(增量)。当源系统更喜欢以增量形式发送更新时,这是一个自然的选择(这种思维方式似乎可以追溯到数据以 CD-ROM 形式在系统之间传递的时间)。它更节省空间,但更难正确处理(例如,你如何表示删除?),更糟糕的是,它意味着消费者需要扫描整个历史,“事件溯源”式,才能到达在系统的当前状态。

  3. 将行的每个版本存储一次,并带有开始和结束日期。这种模式被称为“时变数据”等术语,在数据仓库中非常频繁地出现,并且在需要存储历史值时更普遍地出现在关系数据库设计中。当一行发生变化时,更新以前的版本以设置“结束日期”,然后插入以今天为“开始日期”的新版本。不幸的是,这并不能很好地转化为 Hadoop 范式,在这种范式中,只支持追加数据集,并且没有更新行的原生概念(尽管可以通过覆盖现有数据文件来实现该效果)。这种方法需要相当复杂的逻辑来加载数据,但不可否认的是,使用这种结构来消费数据非常方便。

(值得注意的是,每天都在变化一个特别不稳定的字段,以使后一个选项降级到与选项 1 相同的空间效率)。

那么......是否还有另一种将空间效率与易用性相结合的选择?

4

1 回答 1

2

我会建议选项 3 的变体,它尊重 HDFS 的仅附加性质。

我们保留两个不同类型的信息,而不是一个数据集,分别存储:

  1. 过期行的历史记录,很可能按结束日期(可能每月)划分。只有当它们的结束日期已知时才会添加行。
  2. 特定日期的快照集合,至少包括最近一天,最有可能按快照日期进行分区。可以每天添加新快照,并且可以在几天后删除旧快照,因为它们可以从当前快照和过期记录的历史中重建。

与选项 3 的区别只是我们认为未过期的行是与过期行不同的信息。

优点:与 HDFS 的仅附加性质一致。

优点:使用当前快照的查询可以在添加新的一天时安全运行,只要我们将快照保留几天(比运行最长查询所需的时间长)。

优点:使用历史记录的查询同样可以安全地运行,只要它们明确地对最新的“结束日期”进行限制,在运行时排除任何后续添加的过期行。

缺点:这不仅仅是每天简单的“更新”或“覆盖”。在 HDFS 的实践中,这通常需要通过复制和过滤来实现,所以这并不是一个真正的骗局。

缺点:许多查询需要结合两个数据集。为了缓解这种情况,我们可以创建视图或类似的视图,将两者适当地结合起来,以产生看起来与选项 3 完全相同的东西。

缺点:查找最新快照需要找到正确的分区。这可以通过在每次有新快照可用时“滚动”到最新快照的视图来缓解。

于 2017-09-13T03:54:11.453 回答