Hadoop 小文件优化方法
1 Hadoop小文件弊端
HDFS上每个文件都要在NameNode中都有对应的元数据,这个元数据的大小约为150byte,这样当小文件比较多的时候,一方面会大量占用NameNode的内存空间,另一方面就是元数据过多的情况查找速度变慢。
小文件过多,在进行MR计算时,会导致生成过多的切片. 需要启动过多的MapTask。
2 Hadoop小文件解决方案
小文件优化的方向:
(1)在数据采集的时候,就将小文件或小批数据合成大文件再上传HDFS。
(2)在业务处理之前,在HDFS上使用MapReduce程序对小文件进行合并。
(3)在MapReduce处理时,可采用CombineTextInputFormat提高效率。
(4)开启uber模式,实现jvm重用
Hadoop Archive
是一个高效的将小文件放入HDFS块中的文件存档工具,能够将多个小文件打包成一个HAR文件,从而达到减少NameNode的内存使用
小文件存档
hive的小文件如何处理
小文件如何产生的?
(1)动态分区插入数据(如果动态分区的字段设置不合理,有的时候你会 发现明知道不合理,但是你必须这样设置),分区数太多,产生大量的小文件,导致map数量剧增;
(2)reduce数量越多,小文件也越多(reduce的个数和输出文件是对应的);
(3)数据源本身就包含大量的小文件。
小文件解决方案
(1)在Map执行前合并小文件,减少Map数:CombineHiveInputFormat具有对小文件进行合并的功能(系统默认的格式)。HiveInputFormat没有对小文件合并功能。
(2)merge
输出合并小文件
(3)开启JVM重用
JVM重用是Hadoop调优参数的内容,其对Hive的性能具有非常大的影响,特别是对于很难避免小文件的场景或task特别多的场景,这类场景大多数执行时间都很短。
Hadoop的默认配置通常是使用派生JVM来执行map和Reduce任务的。这时JVM的启动过程可能会造成相当大的开销,尤其是执行的job包含有成百上千task任务的情况。JVM重用可以使得JVM实例在同一个job中重新使用N次。N的值可以在Hadoop的mapred-site.xml文件中进行配置。通常在10-20之间,具体多少需要根据具体业务场景测试得出。默认值是1
这个功能的缺点是,开启JVM重用将一直占用使用到的task插槽,以便进行重用,直到任务完成后才能释放。如果某个“不平衡的”job中有某几个reduce task执行的时间要比其他Reduce task消耗的时间多的多的话,那么保留的插槽就会一直空闲着却无法被其他的job使用,直到所有的task都结束了才会释放。
spark如何处理小文件
可以采用上述的思路,除了上述的思路之外,还有一些方法,处理小文件;
SparkRDD
coalesce与repartition 解决小文件问题
repartition(numPartitions: Int)
Ø 返回numPartitions分区个数的新RDD(或DataFrame)。
Ø 可以增加或减少此RDD中的并行性级别,内部使用shuffle来重新分配数据。
Ø 如果要减少partition数量,可考虑使用`coalesce`,这可以避免执行shuffle。
p coalesce(numPartitions: Int, shuffle: Boolean = false)
Ø 1)返回一个新的RDD,该RDD被缩减为`numPartitions`分区。
Ø 2)这导致窄依赖,例如, 如果从1000个分区转到100个分区,则不会有shuffle,而是100个新分区中的每一个都将声明当前分区的10个分区。
Ø 3)如果您正在进行剧烈的合并,例如将numPartitions从1000减少为1,这将会导致计算发生在非
常少的节点上(例如numPartitions = 1的情况下为一个节点)。
4)为了避免这种情况,可以传递shuffle = true,或者直接使用repartition。
这将添加一个shuffle步骤,意味着当前的上游分区将并行执行(无论当前的分区是什么)。
5)注意:随着shuffle = true,实际上可以合并到更大数量的分区。 如果你有少量的分区,比如
100,那么这很有用,可能有几个分区异常大。 调用coalesce(1000,shuffle = true)将导致
使用hash partitioner分发数据到1000个分区。