1:为什么大批量数据集写入Hbase中,需要使用bulkload

  • BulkLoad不会写WAL,也不会产生flush以及split。
  • 如果我们大量调用PUT接口插入数据,可能会导致大量的GC操作。除了影响性能之外,严重时甚至可能会对HBase节点的稳定性造成影响。但是采用BulkLoad就不会有这个顾虑。
  • 过程中没有大量的接口调用消耗性能
  • 可以利用spark 强大的计算能力

上面是一个总的执行流程图, 数据生成,HFile转换以及HFile加载, 下面是HFile 的格式, 就是个key value 存储结构,
key 是由行健column family 和限定符指定, 然后再加上key的索引

注意:

生成HFile要求Key有序。开始是以为只要行键有序,即map之后,sortByKey就ok,后来HFileOutputFormat一直报后值比前值小(即未排序)。翻了很多鬼佬网站,才发现,这里的行键有序,是要求rowKey+列族+列名整体有序!!!

package hbaseLoad.CommonLoad

import java.io.IOException
import java.sql.Date
import java.util
import java.util.concurrent.{Executors, ScheduledExecutorService, TimeUnit} import org.apache.hadoop.fs.Path
import org.apache.hadoop.hbase.client._
import org.apache.hadoop.hbase.io.ImmutableBytesWritable
import org.apache.hadoop.hbase.mapreduce.{HFileOutputFormat2, LoadIncrementalHFiles}
import org.apache.hadoop.hbase.{HBaseConfiguration, HColumnDescriptor, HTableDescriptor, KeyValue, TableName}
import org.apache.hadoop.hbase.util.Bytes
import org.apache.hadoop.mapreduce.Job
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext} /**
* Created by angel;
*/
object Hfile {
val zkCluster = "hadoop01,hadoop02,hadoop03"
val hbasePort = "2181"
val tableName = TableName.valueOf("hfile")
val columnFamily = Bytes.toBytes("info")
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setAppName("Hfile").setMaster("local[*]")
conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer");
conf.registerKryoClasses(Array(classOf[D_class]))
val sc = new SparkContext(conf)
val fileData: RDD[String] = sc.textFile("data")
val rdd = fileData.map{
line =>
val dataArray = line.split("@")
val rowkey = dataArray(0)+dataArray(1)
val ik = new ImmutableBytesWritable(Bytes.toBytes(rowkey))
val kv = new KeyValue(Bytes.toBytes(rowkey) , columnFamily , Bytes.toBytes("info") , Bytes.toBytes(dataArray(2)+":"+dataArray(3)+":"+dataArray(4)+":"+dataArray(5)))
(ik , kv)
}
// val scheduledThreadPool = Executors.newScheduledThreadPool(4);
// scheduledThreadPool.scheduleWithFixedDelay(new Runnable() {
// override def run(): Unit = {
// println("=====================================")
// }
//
// }, 1, 3, TimeUnit.SECONDS);
hfile_load(rdd)
}
def hfile_load(rdd:RDD[Tuple2[ImmutableBytesWritable , KeyValue]]): Unit ={
val hconf = HBaseConfiguration.create()
hconf.set("hbase.zookeeper.quorum", zkCluster);
hconf.set("hbase.master", "hadoop01:60000");
hconf.set("hbase.zookeeper.property.clientPort", hbasePort);
hconf.setInt("hbase.rpc.timeout", 20000);
hconf.setInt("hbase.client.operation.timeout", 30000);
hconf.setInt("hbase.client.scanner.timeout.period", 200000);
//声明表的信息
var table: Table = null
var connection: Connection = null
try{
val startTime = System.currentTimeMillis()
println(s"开始时间:-------->${startTime}")
//生成的HFile的临时保存路径
val stagingFolder = "hdfs://hadoop01:9000/hfile"
//将日志保存到指定目录
rdd.saveAsNewAPIHadoopFile(stagingFolder,
classOf[ImmutableBytesWritable],
classOf[KeyValue],
classOf[HFileOutputFormat2],
hconf)
//开始即那个HFile导入到Hbase,此处都是hbase的api操作
val load = new LoadIncrementalHFiles(hconf) //创建hbase的链接,利用默认的配置文件,实际上读取的hbase的master地址
connection = ConnectionFactory.createConnection(hconf)
//根据表名获取表
table = connection.getTable(tableName)
val admin = connection.getAdmin
//构造表描述器
val hTableDescriptor = new HTableDescriptor(tableName)
//构造列族描述器
val hColumnDescriptor = new HColumnDescriptor(columnFamily)
hTableDescriptor.addFamily(hColumnDescriptor)
//如果表不存在,则创建表
if(!admin.tableExists(tableName)){
admin.createTable(hTableDescriptor)
}
//获取hbase表的region分布
val regionLocator = connection.getRegionLocator(tableName)
//创建一个hadoop的mapreduce的job
val job = Job.getInstance(hconf)
//设置job名称
job.setJobName("DumpFile")
//此处最重要,需要设置文件输出的key,因为我们要生成HFile,所以outkey要用ImmutableBytesWritable
job.setMapOutputKeyClass(classOf[ImmutableBytesWritable])
//输出文件的内容KeyValue
job.setMapOutputValueClass(classOf[KeyValue])
//配置HFileOutputFormat2的信息
HFileOutputFormat2.configureIncrementalLoad(job, table, regionLocator)
//开始导入
load.doBulkLoad(new Path(stagingFolder), table.asInstanceOf[HTable])
val endTime = System.currentTimeMillis()
println(s"结束时间:-------->${endTime}")
println(s"花费的时间:----------------->${(endTime - startTime)}")
}catch{
case e:IOException =>
e.printStackTrace()
}finally {
if (table != null) {
try {
// 关闭HTable对象 table.close();
} catch {
case e: IOException =>
e.printStackTrace();
}
}
if (connection != null) {
try { //关闭hbase连接. connection.close();
} catch {
case e: IOException =>
e.printStackTrace();
}
}
} } }

spark批量写写数据到Hbase中(bulkload方式)的更多相关文章

  1. java实现服务端守护进程来监听客户端通过上传json文件写数据到hbase中

    1.项目介绍: 由于大数据部门涉及到其他部门将数据传到数据中心,大部分公司采用的方式是用json文件的方式传输,因此就需要编写服务端和客户端的小程序了.而我主要实现服务端的代码,也有相应的客户端的测试 ...

  2. 简单通过java的socket&serversocket以及多线程技术实现多客户端的数据的传输,并将数据写入hbase中

    业务需求说明,由于公司数据中心处于刚开始部署的阶段,这需要涉及其它部分将数据全部汇总到数据中心,这实现的方式是同上传json文件,通过采用socket&serversocket实现传输. 其中 ...

  3. 【转载】C#批量插入数据到Sqlserver中的三种方式

    引用:https://m.jb51.net/show/99543 这篇文章主要为大家详细介绍了C#批量插入数据到Sqlserver中的三种方式,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 本篇, ...

  4. 大数据学习day20-----spark03-----RDD编程实战案例(1 计算订单分类成交金额,2 将订单信息关联分类信息,并将这些数据存入Hbase中,3 使用Spark读取日志文件,根据Ip地址,查询地址对应的位置信息

    1 RDD编程实战案例一 数据样例 字段说明: 其中cid中1代表手机,2代表家具,3代表服装 1.1 计算订单分类成交金额 需求:在给定的订单数据,根据订单的分类ID进行聚合,然后管理订单分类名称, ...

  5. 批量导入数据到HBase

    hbase一般用于大数据的批量分析,所以在很多情况下需要将大量数据从外部导入到hbase中,hbase提供了一种导入数据的方式,主要用于批量导入大量数据,即importtsv工具,用法如下:   Us ...

  6. C#批量插入数据到Sqlserver中的四种方式

    我的新书ASP.NET MVC企业级实战预计明年2月份出版,感谢大家关注! 本篇,我将来讲解一下在Sqlserver中批量插入数据. 先创建一个用来测试的数据库和表,为了让插入数据更快,表中主键采用的 ...

  7. C#批量插入数据到Sqlserver中的三种方式

    本篇,我将来讲解一下在Sqlserver中批量插入数据. 先创建一个用来测试的数据库和表,为了让插入数据更快,表中主键采用的是GUID,表中没有创建任何索引.GUID必然是比自增长要快的,因为你生 成 ...

  8. C#_批量插入数据到Sqlserver中的四种方式

    先创建一个用来测试的数据库和表,为了让插入数据更快,表中主键采用的是GUID,表中没有创建任何索引.GUID必然是比自增长要快的,因为你生成一个GUID算法所花的时间肯定比你从数据表中重新查询上一条记 ...

  9. java批量插入数据进数据库中

    方式1: for循环,每一次进行一次插入数据. 方式2: jdbc的preparedStatement的batch操作 PreparedStatement.addBatch(); ...... Pre ...

随机推荐

  1. 029_mount bind挂载

    一. 由于公司的配置标准并不统一,交付的磁盘挂载的路径不是想要的路径,但是 1./home目录下有很重要的堡垒机登录的相关文件,还不能卸载 2.我通过pts/0登录的,这个文件描述符也是在/home目 ...

  2. python操作三大主流数据库(10)python操作mongodb数据库④mongodb新闻项目实战

    python操作mongodb数据库④mongodb新闻项目实战 参考文档:http://flask-mongoengine.readthedocs.io/en/latest/ 目录: [root@n ...

  3. centos如何安装Python3

    Linux下默认系统自带python2.6的版本,这个版本被系统很多程序所依赖,所以不建议删除,如果使用最新的Python3那么我们知道编译安装源码包和系统默认包之间是没有任何影响的,所以可以安装py ...

  4. page_cleaner: 1000ms intended loop took 4724ms. The settings might not be optimal. (flushed=1037, during the time.)

    2018-07-09T14:28:56.853600Z 0 [Note] InnoDB: page_cleaner: 1000ms intended loop took 4724ms. The set ...

  5. Hive学习01-基础常见问题

      理论: 什么是hive: 1. Hive旨在实现轻松的数据汇总,即时查询和分析大量数据. 2. 它提供了SQL,使用户可以轻松地进行临时查询,汇总和数据分析. 3. Hive可以使用用户定义函数( ...

  6. 弃 Java 而使用 Kotlin 的你后悔了吗?| kotlin将会是最好的开发语言

    自从 2011 年发布以来,Kotlin 凭借强大的功能在开发者中的欢迎程度与日俱增.且在一年前,Google 宣布 Kotlin 正式成为 Android 官方开发语言,由此引发了从 Java 迁移 ...

  7. 【Java】「深入理解Java虚拟机」学习笔记(4)- 类文件结构

    我为什么喜欢Java,另一个重要原因就是跨平台,WORA. 程序员是爽了,但肯定有人要为你遮风挡雨,解决WORA的基石就是字节码+虚拟机. ♣Tip 其实这里存在两种无关性,一是平台无关性.另一个是语 ...

  8. day 28 面向对象 三种特性之一 多态 鸭子类型 反射(反省)

    多态是OOP的三大特征之一 字面意思:多种形态 多种状态 官方描述:不同的对象可以响应(调用)同一个方法 产生不同的结果(例如水的三相特征) 多态不是什么新技术 我们编写面向对象的程序时 其实就有多态 ...

  9. SpringBoot图片上传(一)

    简单描述:点击上传文件的图标,上传文件,上传成功后,图标编程上传的图片. 吐槽:文件上传下载这种东西,总是感觉莫名的虚-_-||  也不知道是造了什么孽,(其实就是IO File这一块的知识了解的不太 ...

  10. bzoj1123 割点性质应用

    删掉无向图上任意一点,请求出将会增加的不连通的点对数 将无向图联通性的问题转化到搜索树方向上考虑 如果一个点不是割点,那么删掉该点的答案很简单,就是2*(n-1) 如果点u是割点,同时u在搜索树上有t ...