我们在《通过BulkLoad快速将海量数据导入到Hbase[Hadoop篇]》文中介绍了一种快速将海量数据导入Hbase的一种方法,而本文将介绍如何在Spark上使用Scala编写快速导入数据到Hbase中的方法。这里将介绍两种方式:第一种使用Put普通的方法来倒数;第二种使用Bulk Load API。关于为啥需要使用Bulk Load本文就不介绍,更多的请参见《通过BulkLoad快速将海量数据导入到Hbase[Hadoop篇]》


如果想及时了解Spark、Hadoop或者Hbase相关的文章,欢迎关注微信公共帐号:iteblog_hadoop

使用org.apache.hadoop.hbase.client.Put来写数据

使用 org.apache.hadoop.hbase.client.Put 将数据一条一条写入Hbase中,但是和Bulk加载相比效率低下,仅仅作为对比。

import org.apache.spark._
import org.apache.spark.rdd.NewHadoopRDD
import org.apache.hadoop.hbase.{HBaseConfiguration, HTableDescriptor}
import org.apache.hadoop.hbase.client.HBaseAdmin
import org.apache.hadoop.hbase.mapreduce.TableInputFormat
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.HColumnDescriptor
import org.apache.hadoop.hbase.util.Bytes
import 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.NewHadoopRDD
import org.apache.hadoop.hbase.{HBaseConfiguration, HTableDescriptor}
import org.apache.hadoop.hbase.client.HBaseAdmin
import org.apache.hadoop.hbase.mapreduce.TableInputFormat
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.HColumnDescriptor
import org.apache.hadoop.hbase.util.Bytes
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.mapred.TableOutputFormat
import org.apache.hadoop.mapred.JobConf
import org.apache.hadoop.hbase.io.ImmutableBytesWritable
import org.apache.hadoop.mapreduce.Job
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat
import org.apache.hadoop.hbase.KeyValue
import org.apache.hadoop.hbase.mapreduce.HFileOutputFormat
import 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 Hbase
val 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.NewHadoopRDD
import org.apache.hadoop.hbase.{HBaseConfiguration, HTableDescriptor}
import org.apache.hadoop.hbase.client.HBaseAdmin
import org.apache.hadoop.hbase.mapreduce.TableInputFormat
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.HColumnDescriptor
import org.apache.hadoop.hbase.util.Bytes
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.mapred.TableOutputFormat
import org.apache.hadoop.mapred.JobConf
import org.apache.hadoop.hbase.io.ImmutableBytesWritable
import org.apache.hadoop.mapreduce.Job
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat
import org.apache.hadoop.hbase.KeyValue
import org.apache.hadoop.hbase.mapreduce.HFileOutputFormat
import 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的更多相关文章

  1. 通过BulkLoad快速将海量数据导入到Hbase

    在第一次建立Hbase表的时候,我们可能需要往里面一次性导入大量的初始化数据.我们很自然地想到将数据一条条插入到Hbase中,或者通过MR方式等. 但是这些方式不是慢就是在导入的过程的占用Region ...

  2. 通过BulkLoad快速将海量数据导入到Hbase(TDH,kerberos认证)

    一.概念 使用BlukLoad方式利用Hbase的数据信息是 按照特点格式存储在HDFS里的特性,直接在HDFS中生成持久化的Hfile数据格式文件,然后完成巨量数据快速入库的操作,配合MapRedu ...

  3. spark上的一些常用命令(一)

    1. 加速跑 spark-sql --name uername --num-executors --driver-memory 8G --executor-memory 8G 2. 上传数据 建表 ) ...

  4. Spark,一种快速数据分析替代方案

    原文出处:http://www.ibm.com/developerworks/library/os-spark/ Spark 是一种与 Hadoop 相似的开源集群计算环境,但是两者之间还存在一些不同 ...

  5. Spark(火花)快速、通用的大数据处理引擎框架

    一.什么是Spark(火花)? 是一种快速.通用处理大数据分析的框架引擎. 二.Spark的四大特性 1.快速:Spark内存上采用DAG(有向无环图)执行引擎非循环数据流和内存计算支持. 内存上比M ...

  6. Spark 安装部署与快速上手

    Spark 介绍 核心概念 Spark 是 UC Berkeley AMP lab 开发的一个集群计算的框架,类似于 Hadoop,但有很多的区别. 最大的优化是让计算任务的中间结果可以存储在内存中, ...

  7. 协同过滤 CF & ALS 及在Spark上的实现

    使用Spark进行ALS编程的例子可以看:http://www.cnblogs.com/charlesblc/p/6165201.html ALS:alternating least squares ...

  8. 如何在Win8.1和Win2012上运用PowerShell快速生成、安装、导出自签名证书 (Self-Signed Certificate)

    自签名证书用途很广,测试,开发,本地或者云端网站(比如Microsoft Azure Web Site)都会使用到.本文会介绍一种在Win8.1和Win2012 R2上使用PowerShell快速生成 ...

  9. 在spark上构造随机森林模型过程的一点理解

    这篇文章仅仅是为了帮助自己理解在分布式环境下是如何进行随机森林模型构建的,文章中记录的内容可能不太准确,仅仅是大致上的一个理解. 1.特征切分点统计 不管是连续取值型特征还是离散取值型特征,分裂树结点 ...

随机推荐

  1. 用MVVM模式开发中遇到的零散问题总结(1)

    https://www.cnblogs.com/tong-tong/archive/2011/11/28/2250948.html

  2. JAVA计算文件的crc32校验码

    import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java ...

  3. fabric 学习笔记

    fabric安装 目前,从PyPI可以搜索到主要的fabric库为“ Fabric 2.1.3 ”.“ fabric2 2.1.3 ”和“ Fabric3 1.14.post1 ”. Fabric:官 ...

  4. java.net.SocketException: Broken pipe

    java.net.SocketException: Broken pipe 生产上遇到一个问题,socket发生Broken pipe错误,如下 这个问题跟踪了好几个月,始终没有模拟出为什么会发生Br ...

  5. xrat CC特征

    ["6", 11818669.0, 8326.0, 599.75, 19705.992496873696, 13.882451021258857, 0.07203338938265 ...

  6. PHP:第一章——PHP中的goto语句和

    goto语句: <?php header("Content-Type:text/html;charset=utf-8"); /*goto语句:可以代替break*/ //例1 ...

  7. PHP:第一章——PHP中逻辑运算符的使用方法

    //逻辑运算符 $a=;$b=;$c=;$d=; //逻辑与(and 和 &&)他们两个的逻辑是一样的,如果两个值都为true,结果才为true,否则是false. //var_dum ...

  8. Maven 入门篇 ( 上 )

    写这个 maven 的入门篇是因为之前在一个开发者会的动手实验中发现挺多人对于 maven 不是那么了解,所以就有了这个想法.这个入门篇分上下两篇.本文着重动手,用 maven 来构建运行 hello ...

  9. vue + element-ui Table的数据多选,多页选择数据回显,分页记录保存选中的数据。

    业务的需要:我要对与会人员勾选,记录所选的与会人员,并且点击到别的页面上时也要记录所勾选的.第一次尝试,每次点击下一页数据都会清空.然后我就去element ui官网查看了api.实现如下: 在tab ...

  10. docker(二)不管怎么样,先跑起来。运行一个samba,运行一个hello world。

    ---恢复内容开始--- 继续上一篇文章 访问https://hub.docker.com/r/jackadam/samba/ 这是我写的一个docker镜像. 下面有 无脑测试用: docker r ...