在Spark上通过BulkLoad快速将海量数据导入到Hbase
我们在《通过BulkLoad快速将海量数据导入到Hbase[Hadoop篇]》文中介绍了一种快速将海量数据导入Hbase的一种方法,而本文将介绍如何在Spark上使用Scala编写快速导入数据到Hbase中的方法。这里将介绍两种方式:第一种使用Put普通的方法来倒数;第二种使用Bulk Load API。关于为啥需要使用Bulk Load本文就不介绍,更多的请参见《通过BulkLoad快速将海量数据导入到Hbase[Hadoop篇]》。
文章目录
使用org.apache.hadoop.hbase.client.Put来写数据
使用 org.apache.hadoop.hbase.client.Put 将数据一条一条写入Hbase中,但是和Bulk加载相比效率低下,仅仅作为对比。
import org.apache.spark._import org.apache.spark.rdd.NewHadoopRDDimport org.apache.hadoop.hbase.{HBaseConfiguration, HTableDescriptor}import org.apache.hadoop.hbase.client.HBaseAdminimport org.apache.hadoop.hbase.mapreduce.TableInputFormatimport org.apache.hadoop.fs.Path;import org.apache.hadoop.hbase.HColumnDescriptorimport org.apache.hadoop.hbase.util.Bytesimport org.apache.hadoop.hbase.client.Put;import org.apache.hadoop.hbase.client.HTable; val conf = HBaseConfiguration.create()val tableName = "/iteblog"conf.set(TableInputFormat.INPUT_TABLE, tableName) val myTable = new HTable(conf, tableName);var p = new Put();p = new Put(new String("row999").getBytes());p.add("cf".getBytes(), "column_name".getBytes(), new String("value999").getBytes());myTable.put(p);myTable.flushCommits(); |
批量导数据到Hbase
批量导数据到Hbase又可以分为两种:(1)、生成Hfiles,然后批量导数据;
(2)、直接将数据批量导入到Hbase中。
批量将Hfiles导入Hbase
现在我们来介绍如何批量将数据写入到Hbase中,主要分为两步:
(1)、先生成Hfiles;
(2)、使用 org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles 将事先生成Hfiles导入到Hbase中。
实现的代码如下:
import org.apache.spark._import org.apache.spark.rdd.NewHadoopRDDimport org.apache.hadoop.hbase.{HBaseConfiguration, HTableDescriptor}import org.apache.hadoop.hbase.client.HBaseAdminimport org.apache.hadoop.hbase.mapreduce.TableInputFormatimport org.apache.hadoop.fs.Path;import org.apache.hadoop.hbase.HColumnDescriptorimport org.apache.hadoop.hbase.util.Bytesimport org.apache.hadoop.hbase.client.Put;import org.apache.hadoop.hbase.client.HTable;import org.apache.hadoop.hbase.mapred.TableOutputFormatimport org.apache.hadoop.mapred.JobConfimport org.apache.hadoop.hbase.io.ImmutableBytesWritableimport org.apache.hadoop.mapreduce.Jobimport org.apache.hadoop.mapreduce.lib.input.FileInputFormatimport org.apache.hadoop.mapreduce.lib.output.FileOutputFormatimport org.apache.hadoop.hbase.KeyValueimport org.apache.hadoop.hbase.mapreduce.HFileOutputFormatimport org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles val conf = HBaseConfiguration.create()val tableName = "iteblog"val table = new HTable(conf, tableName) conf.set(TableOutputFormat.OUTPUT_TABLE, tableName)val job = Job.getInstance(conf)job.setMapOutputKeyClass (classOf[ImmutableBytesWritable])job.setMapOutputValueClass (classOf[KeyValue])HFileOutputFormat.configureIncrementalLoad (job, table) // Generate 10 sample data:val num = sc.parallelize(1 to 10)val rdd = num.map(x=>{ val kv: KeyValue = new KeyValue(Bytes.toBytes(x), "cf".getBytes(), "c1".getBytes(), "value_xxx".getBytes() ) (new ImmutableBytesWritable(Bytes.toBytes(x)), kv)}) // Save Hfiles on HDFS rdd.saveAsNewAPIHadoopFile("/tmp/iteblog", classOf[ImmutableBytesWritable], classOf[KeyValue], classOf[HFileOutputFormat], conf) //Bulk load Hfiles to Hbaseval bulkLoader = new LoadIncrementalHFiles(conf)bulkLoader.doBulkLoad(new Path("/tmp/iteblog"), table) |
运行完上面的代码之后,我们可以看到Hbase中的iteblog表已经生成了10条数据,如下:
hbase(main):020:0> scan 'iteblog'ROW COLUMN+CELL \x00\x00\x00\x01 column=cf:c1, timestamp=1425128075586, value=value_xxx \x00\x00\x00\x02 column=cf:c1, timestamp=1425128075586, value=value_xxx \x00\x00\x00\x03 column=cf:c1, timestamp=1425128075586, value=value_xxx \x00\x00\x00\x04 column=cf:c1, timestamp=1425128075586, value=value_xxx \x00\x00\x00\x05 column=cf:c1, timestamp=1425128075586, value=value_xxx \x00\x00\x00\x06 column=cf:c1, timestamp=1425128075675, value=value_xxx \x00\x00\x00\x07 column=cf:c1, timestamp=1425128075675, value=value_xxx \x00\x00\x00\x08 column=cf:c1, timestamp=1425128075675, value=value_xxx \x00\x00\x00\x09 column=cf:c1, timestamp=1425128075675, value=value_xxx \x00\x00\x00\x0A column=cf:c1, timestamp=1425128075675, value=value_xxx |
直接Bulk Load数据到Hbase
这种方法不需要事先在HDFS上生成Hfiles,而是直接将数据批量导入到Hbase中。与上面的例子相比只有微小的差别,具体如下:
将
rdd.saveAsNewAPIHadoopFile("/tmp/iteblog", classOf[ImmutableBytesWritable], classOf[KeyValue], classOf[HFileOutputFormat], conf) |
修改成:
rdd.saveAsNewAPIHadoopFile("/tmp/iteblog", classOf[ImmutableBytesWritable], classOf[KeyValue], classOf[HFileOutputFormat], job.getConfiguration()) |
完整的实现如下:
import org.apache.spark._import org.apache.spark.rdd.NewHadoopRDDimport org.apache.hadoop.hbase.{HBaseConfiguration, HTableDescriptor}import org.apache.hadoop.hbase.client.HBaseAdminimport org.apache.hadoop.hbase.mapreduce.TableInputFormatimport org.apache.hadoop.fs.Path;import org.apache.hadoop.hbase.HColumnDescriptorimport org.apache.hadoop.hbase.util.Bytesimport org.apache.hadoop.hbase.client.Put;import org.apache.hadoop.hbase.client.HTable;import org.apache.hadoop.hbase.mapred.TableOutputFormatimport org.apache.hadoop.mapred.JobConfimport org.apache.hadoop.hbase.io.ImmutableBytesWritableimport org.apache.hadoop.mapreduce.Jobimport org.apache.hadoop.mapreduce.lib.input.FileInputFormatimport org.apache.hadoop.mapreduce.lib.output.FileOutputFormatimport org.apache.hadoop.hbase.KeyValueimport org.apache.hadoop.hbase.mapreduce.HFileOutputFormatimport org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles val conf = HBaseConfiguration.create()val tableName = "iteblog"val table = new HTable(conf, tableName) conf.set(TableOutputFormat.OUTPUT_TABLE, tableName)val job = Job.getInstance(conf)job.setMapOutputKeyClass (classOf[ImmutableBytesWritable])job.setMapOutputValueClass (classOf[KeyValue])HFileOutputFormat.configureIncrementalLoad (job, table) // Generate 10 sample data:val num = sc.parallelize(1 to 10)val rdd = num.map(x=>{ val kv: KeyValue = new KeyValue(Bytes.toBytes(x), "cf".getBytes(), "c1".getBytes(), "value_xxx".getBytes() ) (new ImmutableBytesWritable(Bytes.toBytes(x)), kv)}) // Directly bulk load to Hbase/MapRDB tables.rdd.saveAsNewAPIHadoopFile("/tmp/iteblog", classOf[ImmutableBytesWritable], classOf[KeyValue], classOf[HFileOutputFormat], job.getConfiguration()) |
其他
在上面的例子中我们使用了 saveAsNewAPIHadoopFile API来将数据写到HBase中;事实上,我们还可以通过使用 saveAsNewAPIHadoopDataset API来实现同样的目标,我们仅仅需要将下面代码
rdd.saveAsNewAPIHadoopFile("/tmp/iteblog", classOf[ImmutableBytesWritable], classOf[KeyValue], classOf[HFileOutputFormat], job.getConfiguration()) |
修改成
job.getConfiguration.set("mapred.output.dir", "/tmp/iteblog")rdd.saveAsNewAPIHadoopDataset(job.getConfiguration) |
剩下的和和之前完全一致。
在Spark上通过BulkLoad快速将海量数据导入到Hbase的更多相关文章
- 通过BulkLoad快速将海量数据导入到Hbase
在第一次建立Hbase表的时候,我们可能需要往里面一次性导入大量的初始化数据.我们很自然地想到将数据一条条插入到Hbase中,或者通过MR方式等. 但是这些方式不是慢就是在导入的过程的占用Region ...
- 通过BulkLoad快速将海量数据导入到Hbase(TDH,kerberos认证)
一.概念 使用BlukLoad方式利用Hbase的数据信息是 按照特点格式存储在HDFS里的特性,直接在HDFS中生成持久化的Hfile数据格式文件,然后完成巨量数据快速入库的操作,配合MapRedu ...
- spark上的一些常用命令(一)
1. 加速跑 spark-sql --name uername --num-executors --driver-memory 8G --executor-memory 8G 2. 上传数据 建表 ) ...
- Spark,一种快速数据分析替代方案
原文出处:http://www.ibm.com/developerworks/library/os-spark/ Spark 是一种与 Hadoop 相似的开源集群计算环境,但是两者之间还存在一些不同 ...
- Spark(火花)快速、通用的大数据处理引擎框架
一.什么是Spark(火花)? 是一种快速.通用处理大数据分析的框架引擎. 二.Spark的四大特性 1.快速:Spark内存上采用DAG(有向无环图)执行引擎非循环数据流和内存计算支持. 内存上比M ...
- Spark 安装部署与快速上手
Spark 介绍 核心概念 Spark 是 UC Berkeley AMP lab 开发的一个集群计算的框架,类似于 Hadoop,但有很多的区别. 最大的优化是让计算任务的中间结果可以存储在内存中, ...
- 协同过滤 CF & ALS 及在Spark上的实现
使用Spark进行ALS编程的例子可以看:http://www.cnblogs.com/charlesblc/p/6165201.html ALS:alternating least squares ...
- 如何在Win8.1和Win2012上运用PowerShell快速生成、安装、导出自签名证书 (Self-Signed Certificate)
自签名证书用途很广,测试,开发,本地或者云端网站(比如Microsoft Azure Web Site)都会使用到.本文会介绍一种在Win8.1和Win2012 R2上使用PowerShell快速生成 ...
- 在spark上构造随机森林模型过程的一点理解
这篇文章仅仅是为了帮助自己理解在分布式环境下是如何进行随机森林模型构建的,文章中记录的内容可能不太准确,仅仅是大致上的一个理解. 1.特征切分点统计 不管是连续取值型特征还是离散取值型特征,分裂树结点 ...
随机推荐
- English trip -- Review Unit6 Time 时间
It's at seven o'clock 整点 7点整 It's at half past seven or It's seven-thirty7点30 It's at seven fi ...
- 20170719xlVbaAbsorbProcedure
Sub AbsorbThisProcedure() If Application.VBE.MainWindow.Visible = False Then MsgBox "请先激活VBE编辑窗 ...
- 问题✅:render json的格式支持。to_json被改成as_json,功能一样
class StudentsController < ApplicationController def show @student = Student.find(params[:id]) re ...
- 2018焦作网络赛Mathematical Curse
题意:开始有个数k,有个数组和几个运算符.遍历数组的过程中花费一个运算符和数组当前元素运算.运算符必须按顺序花费,并且最后要花费完.问得到最大结果. 用maxv[x][y]记录到第x个元素,用完了第y ...
- Confluence 6 嵌套用户组的备注
潜在的性能影响.启用嵌套用户组可能会减慢用户查找的速度. 在 LDAP 中定义嵌套用户组.在 LDAP 中,一个嵌套用户组是 DN (Distinguished Name)的子用户组,这个字用户组将会 ...
- [poj 3090]Visible Lattice Point[欧拉函数]
找出N*N范围内可见格点的个数. 只考虑下半三角形区域,可以从可见格点的生成过程发现如下规律: 若横纵坐标c,r均从0开始标号,则 (c,r)为可见格点 <=>r与c互质 证明: 若r与c ...
- Liebig's Barrels CodeForces - 985C (贪心)
链接 大意:给定$nk$块木板, 要制作$n$个$k$块板的桶, 要求任意两桶容积差不超过$l$, 每个桶的容积为最短木板长, 输出$n$个桶的最大容积和 假设最短板长$m$, 显然最后桶的体积都在$ ...
- uva-11426-数论
https://vjudge.net/problem/UVA-11426#author=0 求 SUM{ gcd(i,j) | 1<=i<j<=n}, n<4000001. 令 ...
- 双机热备(准)-->RAC(夭折)-->DG(异地容灾)
以下有的地方为oracle专业术语,非懂勿喷.前段时间某项目负责人告知,他们应用需要一套oracle数据库环境运行模式为双机热备.简单了解下对于现在已经非常成熟的RAC再合适不过了.详细问了问当前服务 ...
- iframe刷新父页面
iframe页面是内嵌到父页面的,当点击iframe页面的服务器控件时,默认只刷新iframe页面,父页面是不会刷新的.若想刷新父页面,可以使用js来实现,如 1. parent.location.r ...
