delta—在hadoop hdfs中高效地存储每日转储

cbjzeqam  于 2021-06-02  发布在  Hadoop
关注(0)|答案(1)|浏览(712)

我认为hadoop的一种常见使用模式是通过从操作系统加载定期(例如每天)的数据快照来构建“数据湖”。对于许多系统,每天的更改率通常小于行的5%(即使更新了行,也只有少数字段可能更改)。
问:如何在hdfs上构建这样的历史数据,这样既节省空间,又能高效访问。
当然,答案将取决于通常如何访问数据。在我们的hadoop集群上:
大多数作业只读取和处理最新版本的数据
一些工作处理一段时间的历史数据(例如1-3个月)
一些作业处理所有可用的历史数据
这意味着,虽然保留历史数据很重要,但不应以严重放缓那些只想知道昨天收盘时数据是什么样子的工作岗位为代价。
我知道有几个选择,但似乎都不太令人满意:
将每个完整转储单独存储为一个新的子目录。这是最明显的设计,简单,并且与mapreduce范式非常兼容。我相信有些人会使用这种方法,但我想知道他们是如何证明存储成本的?假设每天加载1tb的数据,则每年会向集群中添加365tb的大部分重复数据。我知道现在磁盘很便宜,但大多数预算制定者习惯于基础设施按业务增长比例扩张,而不是随时间线性增长。
仅存储与前一天的差异(增量)。当源系统喜欢以delta的形式发送更新时,这是一个自然的选择(这种思维方式似乎可以追溯到数据以cd-rom的形式在系统之间传递的时候)。它更节省空间,但更难做到正确(例如,如何表示删除?),更糟糕的是,它意味着消费者需要扫描整个历史,“事件源”式,以获得系统的当前状态。
将行的每个版本存储一次,包括开始和结束日期。这种模式被称为“时变数据”,在数据仓库中非常常见,在关系数据库设计中,当需要存储历史值时,通常会出现这种模式。行更改时,更新以前的版本以设置“结束日期”,然后插入以今天为“开始日期”的新版本。不幸的是,这并不能很好地转化为hadoop范例,在hadoop范例中,只附加数据集是受欢迎的,并且没有更新行的本地概念(尽管这种效果可以通过覆盖现有的数据文件来实现)。这种方法需要相当复杂的逻辑来加载数据,但不可否认,使用这种结构使用数据是非常方便的。
(值得注意的是,每天只需改变一个特别不稳定的字段,就可以使后一个选项降低到与选项1相同的空间效率)。
那么…有没有另一种结合空间效率和易用性的选择呢?

brccelvz

brccelvz1#

我建议使用选项3的一个变体,它尊重hdfs的纯附加特性。
我们不使用一个数据集,而是使用不同类型的信息分别保存两个数据集:
过期行的历史记录,很可能是按结束日期(可能是每月)划分的。只有在知道行的结束日期时,才会添加行。
特定日期(至少包括最近一天)的快照集合,很可能按快照日期进行分区。每天都可以添加新快照,几天后可以删除旧快照,因为可以从当前快照和过期记录的历史记录中重建旧快照。
与选项3的区别在于,我们认为未过期的行与过期的行是不同的信息类型。
赞成:与hdfs的纯附加特性一致。
优点:使用当前快照的查询可以在添加新的一天时安全运行,只要我们将快照保留几天(比运行最长查询所需的时间长)。
赞成:使用历史记录的查询同样可以安全地运行,只要它们显式地在最新的“结束日期”上给出一个边界,该边界在运行时排除任何随后添加的过期行。
缺点:这不仅仅是每天简单的“更新”或“覆盖”。在hdfs中,这通常需要通过复制和过滤来实现,所以这并不是一个真正的缺点。
缺点:许多查询需要合并这两个数据集。为了简化这一点,我们可以创建视图或类似的视图,将这两个视图适当地结合起来,以生成与选项3完全相同的内容。
缺点:找到最新的快照需要找到正确的分区。这可以通过在每次有新快照可用时“滚动”到最新快照的视图来缓解。

相关问题