bulkload向hbase表中入数据
来源:互联网 发布:单片机开发板怎么做得 编辑:程序博客网 时间:2024/05/21 09:25
1、为何要 BulkLoad 导入?传统的 HTableOutputFormat 写 HBase 有什么问题?
我们先看下 Hbase 的写流程:
通常 MapReduce 在写HBase时使用的是 TableOutputFormat 方式,在reduce中直接生成put对象写入HBase,该方式在大数据量写入时效率低下(HBase会block写入,频繁进行flush,split,compact等大量IO操作),并对HBase节点的稳定性造成一定的影响(GC时间过长,响应变慢,导致节点超时退出,并引起一系列连锁反应),而HBase支持 bulk load 的入库方式,它是利用hbase的数据信息按照特定格式存储在hdfs内这一原理,直接在HDFS中生成持久化的HFile数据格式文件,然后上传至合适位置,即完成巨量数据快速入库的办法。配合mapreduce完成,高效便捷,而且不占用region资源,增添负载,在大数据量写入时能极大的提高写入效率,并降低对HBase节点的写入压力。
通过使用先生成HFile,然后再BulkLoad到Hbase的方式来替代之前直接调用HTableOutputFormat的方法有如下的好处:
(1)消除了对HBase集群的插入压力
(2)提高了Job的运行速度,降低了Job的执行时间
目前此种方式仅仅适用于只有一个列族的情况,在新版 HBase 中,单列族的限制会消除。
2、bulkload 流程与实践
bulkload 方式需要两个Job配合完成:(1)第一个Job还是运行原来业务处理逻辑,处理的结果不直接调用HTableOutputFormat写入到HBase,而是先写入到HDFS上的一个中间目录下(如 middata)
(2)第二个Job以第一个Job的输出(middata)做为输入,然后将其格式化HBase的底层存储文件HFile
(3)调用BulkLoad将第二个Job生成的HFile导入到对应的HBase表中。
了解了BULKLOAD基本过程后,开始进行我们的程序编写:
主函数流程:
1.首先加载集群配置文件
2.判断是否需要建表
3.执行builload任务
public static void main(String[] args) {Configuration conf = HadoopConfiguration.getConf();conf.set(XXT_CLICKLOG_COLUMN_FAMILY, familyName);conf.set("hbase.zookeeper.quorum", "cmaster1.hadoop.xxt.cn,cmaster0.hadoop.xxt.cn,cslave0.hadoop.xxt.cn");conf.set("zookeeper.znode.parent", "/hbase-unsecure");conf.set("hbase.fs.tmp.dir", "/tmp/hbase/bulkload/hbase-staging");Connection connection = null;Admin admin = null;try {connection = ConnectionFactory.createConnection(conf);admin = connection.getAdmin();TableName tn = TableName.valueOf(tableName);createTableIfNotExist(admin, tn);boolean isSuccess = runBulkLoadJob(connection, admin , tn, conf);System.exit(isSuccess?0:1);} catch (IOException e) {log.error("Clicklog bulkload job execute failed!", e);throw new RuntimeException("Clicklog bulkload job execute failed!", e);}finally {try {if (connection != null) {connection.close();}if (admin != null) {admin.close();}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
建表函数
如果表不存在建表,定义好列族及表名,并设置snappy压缩。
根据rowkey业务数据的分布特点进行预分区,尽量使落在每个region分区的数据均匀。
public static void createTableIfNotExist(Admin admin, TableName tableName) throws IOException {if (!admin.tableExists(tableName)) {HTableDescriptor tableDesc = new HTableDescriptor(tableName);HColumnDescriptor columnDesc = new HColumnDescriptor(Bytes.toBytes(familyName));columnDesc.setCompressionType(Algorithm.SNAPPY);tableDesc.addFamily(columnDesc);byte[][] splitKey = new byte[][]{Bytes.toBytes("000001000000"),Bytes.toBytes("000010000000"),Bytes.toBytes("000050000000"), Bytes.toBytes("000100000000")};admin.createTable(tableDesc, splitKey);log.info("create table success");}else {log.info("Table already exists!");}}最后开始执行bulkload任务了
public static boolean runBulkLoadJob(Connection connection, Admin admin, TableName tn, Configuration conf) {try {Job job = Job.getInstance(conf, "BulkLoad");/** * 利用分布式缓存加载依赖第三方jar包 */FileSystem fs = FileSystem.get(conf);FileStatus[] files = fs.listStatus(new Path(DISTRIBUTE_LIB_PATH));for(FileStatus file : files){log.info("file path:" + file.getPath().toString());job.addCacheFile(file.getPath().toUri());}job.setJarByClass(ClickLogBulkLoadJob.class);job.setMapperClass(ClickLogBulkLoadMap.class);job.setMapOutputKeyClass(ImmutableBytesWritable.class);job.setMapOutputValueClass(Put.class);job.setSpeculativeExecution(false);job.setReduceSpeculativeExecution(false);job.setInputFormatClass(TextInputFormat.class);job.setOutputFormatClass(HFileOutputFormat2.class);FileInputFormat.setInputPaths(job, inputPath);finalOutputPath = outputPath + System.currentTimeMillis();FileOutputFormat.setOutputPath(job, new Path(finalOutputPath));Table table = connection.getTable(tn);//HTable htable = new HTable(conf, tableName);RegionLocator regionLocator = connection.getRegionLocator(tn);HFileOutputFormat2.configureIncrementalLoad(job, table, regionLocator);//HFileOutputFormat2.configureIncrementalLoad(job, htable);if (job.waitForCompletion(true)) {log.info("Clicklog bulkload job execute success, load data to hbase...");doBulkLoadData(job, admin, table, regionLocator);processFinalFile(conf, true);//doBulkLoadData(job, htable);return true;}else {processFinalFile(conf, false);log.error("Clicklog bulkload job execute failed!");return false;}} catch (Exception e) {log.error("Clicklog bulkload job execute failed!", e);throw new RuntimeException("Clicklog bulkload job execute failed!", e);} }
map函数代码:
@Overrideprotected void map(LongWritable key, Text value, Context context)throws IOException, InterruptedException {/** * 输入数据格式: * xxtsessionId webId ip agentType * time url urlParam referUrl referUrlParam device os net browser remainTime */log.info("-----this data-----" + value.toString());String[] valueStrSplit = value.toString().split("#");String hkey = getRowKey(valueStrSplit[1],valueStrSplit[4]);String[] columnValue = new String[]{valueStrSplit[2],valueStrSplit[3],valueStrSplit[5],valueStrSplit[6],valueStrSplit[7],valueStrSplit[8],valueStrSplit[9],valueStrSplit[10],valueStrSplit[11],valueStrSplit[12],valueStrSplit[13]};final byte[] rowKey = Bytes.toBytes(hkey);final ImmutableBytesWritable hKey = new ImmutableBytesWritable(rowKey);Put put = new Put(rowKey);for(int i = 0; i < columnNames.length; i++) {log.info("column name:" + columnNames[i] + ",column value :" + columnValue[i]);put.add(Bytes.toBytes(family), Bytes.toBytes(columnNames[i]), Bytes.toBytes(columnValue[i]));}context.write(hKey, put);}
注意:我们只需要实现map函数即可,将我们的原始文本数据处理成ImmutableBytesWritable - put的键值对即可。然后利用HBase自带的HFileOutputFormat2.configureIncrementalLoad(job, table, regionLocator);生成HFile文件。
最终调用bulkload工具LoadIncrementalHFiles
将HFile文件move到对应的region分区下面。
private static void doBulkLoadData(Job job, Admin admin, Table table, RegionLocator regionLocator) {try {LoadIncrementalHFiles loader = new LoadIncrementalHFiles(job.getConfiguration());loader.doBulkLoad(new Path(finalOutputPath), admin, table, regionLocator);log.info("bulkload date success!");} catch (Exception e) {log.error("bulkload date failed!", e);throw new RuntimeException("bulkload date failed!" ,e);}
0 0
- bulkload向hbase表中入数据
- HBase快速导入数据--BulkLoad
- HBase快速导入数据--BulkLoad
- 【hbase】bulkload数据到hbase表中
- 【hbase】bulkload数据到hbase表中
- hbase bulkload
- hbase bulkload
- hbase bulkload
- hbase bulkload
- HBase bulkload
- 批量(bulkload)载入数据到hbase
- Hbase 批量数据BulkLoad 导入使用
- Hbase通过BulkLoad快速导入数据
- HBase数据快速导入之ImportTsv&Bulkload
- HBase数据快速导入之ImportTsv&Bulkload
- HBase 写优化之 BulkLoad 实现数据快速入库
- HBase 写优化之 BulkLoad 实现数据快速入库
- HBase 写优化之 BulkLoad 实现数据快速入库
- Chrome浏览器扩展开发系列之五:Page Action类型的Chrome浏览器扩展
- SAE基本使用
- ps命令的英文帮助文档
- Server Tomcat v7.0 Server at localhost was unable to start within 45 seconds问题解决
- VMWare虚拟机安装CentOS 7 Linux及Hadoop与Eclipse学习环境(3-Eclipse开发环境)
- bulkload向hbase表中入数据
- Chrome浏览器扩展开发系列之六:options 页面
- js 时间戳转为日期格式
- 微型投影仪第五篇——Metro UI
- Git远程操作详解
- Planar Homographies (平面单应矩阵)
- 原生js中创建ajax
- 有趣的KVC-几行代码打造一个万能容器对象
- C++ static对象 和析构函数的关系