我有一个火花流工作,批处理间隔为2分钟(可配置) 此作业从Kafka主题读取并创建数据集并在其上应用模式并将这些记录插入到Hive表中。
Spark作业在Hive分区中每个批处理间隔创建一个文件,如下所示:
dataset.coalesce(1).WRITE()模式(SaveMode.Append).insertInto(targetEntityName);
现在进来的数据并不是那么大,如果我将批处理持续时间增加到大约10分钟左右,那么即使我最终也只能获得2-3mb的数据,这比块大小要小。
这是Spark Streaming中的预期行为 我正在寻找有效的方法来进行后处理以合并所有这些小文件并创建一个大文件 如果有人以前做过,请分享您的想法。
答案 0 :(得分:4)
我建议您不要使用Spark将数据从Kafka传输到HDFS。
Kafka Connect HDFS Confluent(或Apache Gobblin by LinkedIn)的插件就是出于此目的而存在的。两者都提供Hive集成。
中查找有关压缩小文件的评论如果您需要编写Spark代码来将Kafka数据处理成模式,那么您仍然可以这样做,并以(最好)Avro格式写入另一个主题,Hive可以在没有预定义的表模式的情况下轻松读取
我个人写过"压缩"实际上从Hive表中获取一堆每小时Avro数据分区的进程,然后转换为每日Parquet分区表以进行分析。到目前为止,它一直很好用。
如果您希望在记录到达HDFS之前对其进行批处理,那么Kafka Connect或Apache Nifi(链接中提到的)可以提供帮助,因为您有足够的内存来存储记录,然后才能刷新到HDFS
答案 1 :(得分:0)
我和你的处境完全一样。我是通过以下方式解决的:
让我们假设您即将收到的新数据存储在数据集中:dataset1
1-使用良好的分区键对表进行分区,就我而言,我发现我可以使用组合键进行分区,以使每个分区大约100MB。
2-使用spark核心而不使用spark sql保存:
a-要保存时将整个分区加载到内存中(在数据集内:dataset2)
b-然后应用数据集联合函数:dataset3 = dataset1.union(dataset2)
c-确保根据需要对结果数据集进行分区,例如:dataset3.repartition(1)
d-以“ OverWrite”模式保存结果数据集以替换现有文件
如果您需要有关任何步骤的更多详细信息,请与我们联系。