今天群里有个有经验的大神提了一个问题(@尘事随缘),记录下来。
A君搭建一个小型的集群,7台DataNode,一台主节点。需求是这样:通过MR程序去读取Hbase表里面的数据,程序运行后发现速度比较慢,通过查询任务详细发现,累计需要1542个Map完成,目前有14个MAP在执行。客户对此速度表示不满意,请问如何优化?
首先通过Job看,有1542个Map需要执行,说明Hbase,有1542个分区(每个分区对应一个Map),这是一个知识点。
数据不存在热点,Hbase处理性能没有问题
有1542个Map需要执行,但是并行的只有14个,说明Map的数据量不够。
经过询问,他没有做配置,默认每台机器只有2个Map,所以并行度是7*2=14,也就是同时运行14个Map
所以提示他去配置文件重新配置,每台机器配置的Map数据量是CPU个,因为8个CPU,所以配置8个MAP。那么并行处理能力是7*8=56(同时56个Map)。
运行速度提升4倍。
参数修改:
conf/mapred-site.xml
1.0 版本是这个参数 mapred.tasktracker.map.tasks.maximum 配置Map
mapred.tasktracker.reduce.tasks.maximum 配置Reduce
https://hadoop.apache.org/docs/r1.0.4/mapred-default.html
2.0 版本是这个参数mapreduce.tasktracker.map.tasks.maximum 配置Map
mapreduce.tasktracker.reduce.tasks.maximum 配置Reduce
查询缓存
Scan的caching属性默认值是1,意味着扫描器每次从region服务器抓取1条记录进行匹配。我们可以设置caching为比1大得多的值。例如,设置为500,则一次可以抓取500条,需要注意的是该值设得越大服务器的内存开销会越多。
HTableInterface hTable=getHTable(tableName);
Scan scan=newScan();
/*设置缓存*/
scan.setCaching(StaticConfig.getIControl_hbase_cache());
ResultScanner scanner= hTable.getScanner(scan);
多线程配置
Hbase.regionser.handler.count
RegionServer中RPC监听器实例的数量。对于master来说,这个属性是master受理的处理线程(handler)数量。默认值是10。
根据调控层的业务场景,1条运价的匹配查询就会产生4条hbase并发查询。如果有20条,就可能有80条并发,这个并发量是相当的。除了将该参数适当调大可以增加并发处理能力外,还跟集群的数量和服务器的配置有直接的关系,预计集群数量越多,服务器CPU核数越高,并发处理能力越强。
预分区
HRegion是Hbase中分布式存储和负载均衡的最小单元。最小单元就表示不同的Hregion可以分布在不同的HRegion server上。但一个Hregion是不会拆分到多个server上的。
Hbase.hregion.max.filesize
HstoreFile的最大值。Region中任何一个列族的存储文件如果超过了这个上限,就会被拆分成两个region。默认:268435456(256x1024x1024),即256M。
我们的调控文件比较小,要达到分区最大上限256M需要较多的调控文件。为了提高并发量,我们需要在没有达到分区上限的情况下,产生多个hregion来保存和处理数据,这里就用hbase的预分区功能。
示例:
Configuration conf = HBaseConfiguration.create()
HBaseAdmin admin = new HBaseAdmin(conf);
HTableDescriptor desc =newHTableDescriptor(
Bytes.toBytes(tablename));
HColumnDescriptor coldef =newHColumnDescriptor(
Bytes.toBytes(colfamily));
admin.createTable(desc, Bytes.toBytes(1L),Bytes.toBytes(10L), 10);
//以第一位字符不同划分区
desc.setValue(HTableDescriptor.SPLIT_POLICY,
KeyPrefixRegionSplitPolicy.class.getName());
desc.setValue("prefix_split_key_policy.prefix_length","1");
反思:Hadoop集群搭建好了,必须要做优化(优化需要根据你不同的业务场景来做优化)
一个Region对应一个Map,那么反过来,批量导入数据到Hbase,怎么优化呢?