【问题标题】:Spark Streaming to Hive, too many small files per partitionSpark Streaming to Hive,每个分区的小文件太多
【发布时间】:2018-08-28 18:20:32
【问题描述】:

我有一个批处理间隔为 2 分钟(可配置)的 spark 流式传输作业。
该作业从 Kafka 主题中读取数据并创建数据集并在其上应用架构并将这些记录插入 Hive 表中。

Spark 作业在 Hive 分区中每个批次间隔创建一个文件,如下所示:

dataset.coalesce(1).write().mode(SaveMode.Append).insertInto(targetEntityName);

现在传入的数据并没有那么大,如果我将批处理持续时间增加到大约 10 分钟左右,那么即使我最终也可能只获得 2-3mb 的数据,这比块大小要小得多。

这是 Spark Streaming 中的预期行为。
我正在寻找有效的方法来进行后处理以合并所有这些小文件并创建一个大文件。
如果有人以前做过,请分享您的想法。

【问题讨论】:

标签: apache-spark hadoop hive apache-kafka spark-streaming


【解决方案1】:

我建议您不要使用 Spark 将数据从 Kafka 流式传输到 HDFS。

Kafka Connect HDFS Confluent 的插件(或 LinkedIn 的 Apache Gobblin)就是为了这个目的而存在的。两者都提供 Hive 集成。

this Github issue中查找我关于压缩小文件的cmets

如果您需要编写 Spark 代码来将 Kafka 数据处理为模式,那么您仍然可以这样做,并以(最好)Avro 格式写入另一个主题,Hive 无需预定义的表模式即可轻松读取该主题

我个人编写了一个“压缩”过程,它实际上从 Hive 表中抓取了一堆每小时 Avro 数据分区,然后转换为每日 Parquet 分区表进行分析。到目前为止,它运行良好。

如果您想在记录到达 HDFS 之前对其进行批处理,那么 Kafka Connect 或 Apache Nifi(在链接中提到)可以提供帮助,因为您有足够的内存来存储记录,然后再将它们刷新到 HDFS

【讨论】:

    【解决方案2】:

    我的情况和你一模一样。我通过以下方式解决了它:

    假设您的新数据存储在数据集中:dataset1

    1- 使用良好的分区键对表进行分区,就我而言,我发现我可以使用组合键进行分区,每个分区大约有 100MB。

    2- 使用 spark core 不使用 spark sql 保存:

    a- 当你想保存时,将整个分区加载到你的内存中(在数据集内:dataset2)

    b- 然后应用数据集联合函数:dataset3 = dataset1.union(dataset2)

    c- 确保结果数据集按照您的意愿进行分区,例如:dataset3.repartition(1)

    d - 以“OverWrite”模式保存生成的数据集以替换现有文件

    如果您需要有关任何步骤的更多详细信息,请与我们联系。

    【讨论】:

      猜你喜欢
      • 2017-04-30
      • 2018-09-10
      • 1970-01-01
      • 1970-01-01
      • 2018-09-26
      • 2019-04-03
      • 1970-01-01
      • 2019-02-28
      • 2016-01-04
      相关资源
      最近更新 更多