hive减少小文件、合并小文件namenode的内存使用很高时可能是小文件占比高如果内存是正常上下波动的说明内存没问题可以减少小文件会降低元数据占用的内存以下参数可用于hive版本为2.x以及3.x一、历史的小文件合并1、执行 ALTER TABLE tablename PARTITION (dtxxxx-xx-xx) CONCATENATE;如果集群有上千万张表可以想办法把这些小文件的分区导出然后让ai根据表分区批量生成合并sql2、重写表的方式:针对已存在的hive表数据的小文件合并可以通过 INSERT OVERWRITE 重写整张表/分区 来实现小文件合并前置设置真正决定文件数的参数 需要在执行前设置控制 Reduce 数SET hive.exec.reducers.bytes.per.reducer256000000; -- 每个reducer处理约256MBSET hive.exec.reducers.max100; -- reducer上限-- 或直接指定SET mapreduce.job.reduces10; -- 期望生成约10个文件1针对非分区表插入语句INSERT OVERWRITE TABLE db_name.tab_nameSELECT *FROM db_name.tab_nameSORT BY 1;SORT BY 是分区内排序每个 Reduce 内部有序不保证全局有序开销小1 表示按 SELECT 列表中的第 1 列排序这里加排序的真正目的不是排序本身而是强制触发 Reduce 阶段。如果纯 SELECT * 没有聚合/排序Hive 可能走 INSERT ... SELECT 的 map-only 作业无 Reduce那样会一个 Map 一个文件反而不会合并甚至文件数不变或更多。加上 SORT BY 后必然有 Reduce文件数 Reduce 数。若表有分区列非分区表用 * 没问题但如果误用于分区表分区列会被当成普通列写出导致数据错位2针对分区表INSERT OVERWRITE TABLE db_name.tab_namePARTITION (part_col part_value)SELECT col1, col2, ..., colnFROM db_name.tab_nameWHERE part_col part_valueSORT BY 1;PARTITION 子句指定写回的目标分区动态/静态分区WHERE 子句限定只读取该分区的数据二者配合做到只重写单个分区不影响其他分区SELECT col1, col2, ..., coln 不含分区列分区表的分区列是元数据不写在 SELECT 列列表里若写成 SELECT * 会把分区列也当普通列读出来再和 PARTITION 指定的分区值冲突/重复导致数据错误所以分区表必须显式列出非分区列。触发 ReduceSORT BY 1多分区需循环该写法一次只处理一个分区值若有多个分区需对每个 part_value 重复执行脚本循环或动态分区INSERT OVERWRITE TABLE db_name.tab_namePARTITION (part_col)SELECT col1, col2, ..., coln, part_col -- 动态分区需把分区列放最后FROM db_name.tab_nameDISTRIBUTE BY part_colSORT BY part_col, 1;二、针对运行的hive作业输出的新小文件合并设置输出文件合并可以减少文件个数也能达到减少map个数的目的。1、不同程序开启的参数不同1如果hive on mr的程序只有maptask将MapTask产生的所有小文件进行合并默认trueset hive.merge.mapfilestrue;2 如果hive on mr的程序有Map和Reduce Task将ReduceTask产生的所有小文件进行合并默认falseset hive.merge.mapredfilestrue;4每一个合并的文件的大小默认256000000单位byteset hive.merge.size.per.task256000000;5当输出文件的平均大小小于该值时启动一个独立的map-reduce任务进行文件merge默认16000000单位byteSET hive.merge.smallfiles.avgsize 16000000;6map端优化set hive.input.formatorg.apache.hadoop.hive.ql.io.CombineHiveInputFormat;The default input format. Set this to HiveInputFormat if you encounter problems with CombineHiveInputFormat.3如果是hive on spark的程序将spark 输出端产生的所以小文件进行合并默认falseset hive.merge.sparkfilestrue;8hive on tez的程序将tez输出文件合并默认falseset hive.merge.tezfilestrue;以上参数的介绍查看hive官网https://hive.apache.org/docs/latest/user/configuration-properties/TezConfiguration 类配置参考https://tez.apache.org/releases/0.10.5/tez-api-javadocs/configs/TezConfiguration.htmlflink侧减少小文件数量auto-compaction true自动合并小文件开关默认是 false显式打开compaction.file-size 128mb合并目标文件大小sink.rolling-policy.file-size 128MB单文件滚动阈值sink.rolling-policy.rollover-interval 30 min文件最长写入时间参考下官网配置参数https://nightlies.apache.org/flink/flink-docs-stable/docs/connectors/table/filesystem/