您的位置:首页 > 其它

通过Bulk Load导入HBase海量数据

2015-07-16 19:27 453 查看
如果我们一次性入库hbase巨量数据,处理速度慢不说,还特别占用Region资源,一个比较高效便捷的方法就是使用“Bulk Load”方法,即HBase提供的HFileOutputFormat类。

它是利用hbase的数据信息按照特定格式存储在hdfs内这一原理,直接生成这种格式文件,然后上传至合适位置,即完成巨量数据快速入库。配合mapreduce完成,高效便捷,而且不占用region资源。

使用bulk load功能最简单的方式就是使用importtsv工具。importtsv是从TSV文件直接导入数据至HBase的一个内置工具。

importtsv工具不仅支持将数据直接加载进HBase的表中,还支持直接生成HBase自有格式文件(HFile),所以你可以用HBase的bulk load工具将生成好的文件直接加载进运行中的HBase集群。

步骤

首先将tsv格式的数据文件上传到HDFS上。然后运行

hbase org.apache.hadoop.hbase.mapreduce.ImportTsv
-Dimporttsv.columns=HBASE_ROW_KEY,columnfamily:qualifier table_name input_file


Importtsv工具默认使用了HBase的Put API来将数据插入HBase表中,在map阶段使用的是TableOutputFormat 。但是当-Dimporttsv.bulk.output输入选项被指定时,会使用HFileOutputFormat来代替TableOutputFormat,输出HFile文件。而后我们能够使用LoadIncrementalHFiles来加载生成的文件到一个运行的集群中。

加上-Dimporttsv.bulk.output=output选项,则输出bulk,如不用此选项,目标表需在HBase已存在。

HBASE_ROW_KEY指定rowkey,必选。

HBASE_TS_KEY指定时间戳,可选,最多指定一列时间戳,带无效时间戳的record将是bad record。如果使用这个选项,importtsv.timestamp选项将被忽略。

其他选项

-Dimporttsv.skip.bad.lines=false - fail if encountering an invalid line

‘-Dimporttsv.separator=|’ - eg separate on pipes instead of tabs

-Dimporttsv.timestamp=currentTimeAsLong - use the specified timestamp for the import

-Dimporttsv.mapper.class=my.Mapper - A user-defined Mapper to use instead of org.apache.hadoop.hbase.mapreduce.TsvImporterMapper

-Dmapred.job.name=jobName - use the specified mapreduce job name for the import

-Dcreate.table=no - can be used to avoid creation of table by this tool

Note: if you set this to ‘no’, then the target table must already exist in HBase

For performance consider the following options:

-Dmapred.map.tasks.speculative.execution=false

-Dmapred.reduce.tasks.speculative.execution=false

如果输出是HFile文件,还需要用下面的命令导入HBase:

hbase org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles  bulk_path table_name


运行该命令的本质是一个hdfs的mv操作,并不会启动MapReduce。读取生成的文件,判断它们归属的区域,然后访问适当的区域服务器。区域服务器会将HFile文件转移进自身存储目录中,并且为客户端建立在线数据。

参考文献

《HBase Administration Cookbook》

HBase数据迁移

http://www.importnew.com/3912.html

LoadIncrementalHFiles是copy而不是move的疑惑

http://www.thinksaas.cn/group/topic/233674/

初次导入的时候还存在这种情况(《Hadoop权威指南》P427):

如果一个表是新的,并且一开始只有一个区域。此时所有的更新都会到这个区域,知道区域出现分裂为止。即使数据行的键是随机分布的,我们也无法避免这种情况。这种启动现象意味着上传数据在开始时比较慢,知道有足够的区域被分布到各个节点,集群的成员都能参与上传为止。

可以通过预先建立多个区域,来实现随机分布,较少分裂。

另一种解决办法是直接生成HFile文件。

执行

hbase org.apache.hadoop.hbase.util.RegionSplitter -c 10 -f info new UniformSplit


可新建一个表new,拥有列族info,10个区域。不带参数可查看其用法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: