最近使用大数据时,碰到需要进行模型设计,map数量和reduce数量是一个比较重要的考量,现将实际做法与思考进行总结。
1、总体上因分区有1000的约束,同时需要支持未来5-8年的数据,因此对数据分区以5天/分区,可以满足年限要求。
map数量逻辑如下
map数量=split数量
split数量=文件大小/split size
splitszie=Math.max(minSize, Math.min(maxSize, blockSize))
如果不改,用默认值的话,split size就是128M,实际环境是split size128m,blockSize256M,map数不是越多越好,如果有很多小文件,每个小文件被当作一个块,而一个map任务启动和初始化的时间远远大于逻辑处理的时间,这就不合理了,属于资源浪费。
reduce数量
1 reduce的数量可以自定义,map是没有直接自定义这个设置的
hive> set mapred.reduce.tasks;
mapred.reduce.tasks=-1
2没有自定义的话会有默认值,主要依据下面这两个参数,reducer数量=min(hive.exec.reducers.max,总输入数据量/hive.exec.reducers.bytes.per.reducer)
hive> set hive.exec.reducers.bytes.per.reducer;
hive.exec.reducers.bytes.per.reducer=256000000
//每个任务的最大reducer数量
hive> set hive.exec.reducers.max ;
hive.exec.reducers.max=100
同map一样,启动reducer也要消耗资源和时间,另外,有多少reduce,就会有多少小文件生成,如果这些小文件作为下一个任务的输入,就会造成小文件过多. namenode的负担也会加重。有些情况设置了参数也没用,就是只有一个task
1,文件大小小于hive.exec.reducers.bytes.per.reducer,这个容易理解
2用了orderby,全局排序,只能一个reduce完成
3有笛卡尔乘积
4没有group by的汇总
map数量和reducer数量有关系么?
有一点关系,因为reducer的数量是由map输出的数据的大小决定的.map输出的数据量越大,reduce的数量相应的也就越多。
针对小文件过多如何优化?
map端开启小文件合并机制
减少map的数量,map输出的文件是要落地的
减少reduce的数量,因为reduce文件要落地的. 可以调大单个reduce处理的数据量。
分桶的基本原理是分桶列的hash_function%mod = bucketId。可以看到前提是,我们要指定mod,也即是分桶的个数,其实该值也是运行的最大reduce个数,生产的blockSize256M,因此分桶默认是11个桶,1个分桶两个块,可以支持1100W/天,另外由于分桶关联考虑,其余的以11的倍数设置分桶,如11,22,33,44,55等,另外分桶增加分区字段的ETL_DT,具体效果待后续观察。