spark的bulkload报错及解决
需求
将HDFS上的数据解析出来,然后通过hfile方式批量写入Hbase(需要多列写入)
写入数据的关键api:
rdd.saveAsNewAPIHadoopFile(
stagingFolder,
classOf[ImmutableBytesWritable],
classOf[KeyValue],
classOf[HFileOutputFormat2],
job.getConfiguration)
特殊地方:
1):
最初写hfile警告⚠️:
Does it contain files in subdirectories that correspond to column family names
这个原因大概3种:
A:代码问题
B:数据源问题
C:setMapOutputKeyClass 和 saveAsNewAPIHadoopFile中的Class不一致
(我的是数据源问题)
2):
正常些put操作的时候,服务端自动帮助排序,因此在使用put操作的时候没有涉及到这样的错误:
Added a key not lexically larger than previous
但是在写hfile的时候如果出现报错:
Added a key not lexically larger than previous
这样的错误,一般会认为rowkey没有做好排序,然后傻fufu的去验证了一下,rowkey的确做了排序
真正原因:
spark写hfile时候是按照rowkey+列族+列名进行排序的,因此在写入数据的时候,要做到整体有序
(事情还没完)
3):
因为需要多列写入,最好的方式:要么反射来动态获取列名称和列值 、 要么通过datafame去获取(df.columns)
反射方式:
val listData: RDD[(ImmutableBytesWritable, ListBuffer[KeyValue])] = rdd.map {
line =>
val rowkey = line.vintime
val clazz = Class.forName(XXXXXXXXXXXXXXXX)
val fields = clazz.getDeclaredFields
var list = new ListBuffer[String]()
var kvlist = new ListBuffer[KeyValue]()//
if (fields != null && fields.size > ) {
for (field <- fields) {
field.setAccessible(true)
val column = field.getName
list.append(column)
}
} val newList = list.sortWith(_ < _)
val ik = new ImmutableBytesWritable(Bytes.toBytes(rowkey))
for(column <- newList){
val declaredField: Field = line.getClass.getDeclaredField(column)
declaredField.setAccessible(true)
val value = declaredField.get(line).toString
val kv: KeyValue = new KeyValue(
Bytes.toBytes(rowkey),
Bytes.toBytes(columnFamily),
Bytes.toBytes(column),
Bytes.toBytes(value))
kvlist.append(kv)
}
(ik, kvlist)
}
datafame方式:
val tmpData: RDD[(ImmutableBytesWritable, util.LinkedList[KeyValue])] = df.rdd.map(
line =>{
val rowkey = line.getAs[String]("vintime")
val ik = new ImmutableBytesWritable(Bytes.toBytes(rowkey))
var linkedList = new util.LinkedList[KeyValue]()
for (column <- columns) {
val kv: KeyValue = new KeyValue(
Bytes.toBytes(rowkey),
Bytes.toBytes(columnFamily),
Bytes.toBytes(column),
Bytes.toBytes(line.getAs[String](column)))
linkedList.add(kv)
}
(ik, linkedList)
}) val result: RDD[(ImmutableBytesWritable, KeyValue)] = tmpData.flatMapValues(
s => {
val values: Iterator[KeyValue] = JavaConverters.asScalaIteratorConverter(s.iterator()).asScala
values
}
).sortBy(x =>x._1 , true)
仔细观察可以发现,其实两者都做了排序操作,但是即便经过(1)步骤后仍然报错:
Added a key not lexically larger than previous
那么在回想一下之前写hfile的要求:
rowkey+列族+列都要有序,那么如果出现数据的重复,也不算是有序的操作!
因为,做一下数据的去重:
val key: RDD[(String, TransferTime)] = data.reduceByKey((x, y) => y)
val unitData: RDD[TransferTime] = key.map(line => line._2)
果然,这样解决了:Added a key not lexically larger than previous这个异常
但是会报如下另一个异常:
Kryo serialization failed: Buffer overflow
这个是因为在对一些类做kryo序列化时候,数据量的缓存大小超过了默认值,做一下调整即可
sparkConf.set("spark.kryoserializer.buffer.max" , "256m")
sparkConf.set("spark.kryoserializer.buffer" , "64m")
完整代码:
/**
* Created by angel
*/
object WriteTransferTime extends WriteToHbase{
/**
* @param data 要插入的数据
* @param tableName 表名
**/
override def bulkLoadData(data: RDD[Any], tableName: String , columnFamily:String): Unit = { val bean: RDD[TransferTime] = data.map(line => line.asInstanceOf[TransferTime])
val map: RDD[(String, TransferTime)] = bean.map(line => (line.vintime , line))
val key: RDD[(String, TransferTime)] = map.reduceByKey((x, y) => y)
val map1: RDD[TransferTime] = key.map(line => line._2)
val by1: RDD[TransferTime] = map1.sortBy(f => f.vintime)
val listData: RDD[(ImmutableBytesWritable, ListBuffer[KeyValue])] = by1.map {
line =>
val rowkey = line.vintime
val clazz = Class.forName("com.dongfeng.code.Bean.message.TransferTime")
val fields = clazz.getDeclaredFields
var list = new ListBuffer[String]()
var kvlist = new ListBuffer[KeyValue]()//
if (fields != null && fields.size > 0) {
for (field <- fields) {
field.setAccessible(true)
val column = field.getName
list.append(column)
}
} val newList = list.sortWith(_ < _)
val ik = new ImmutableBytesWritable(Bytes.toBytes(rowkey))
for(column <- newList){
val declaredField: Field = line.getClass.getDeclaredField(column)
declaredField.setAccessible(true)
val value = declaredField.get(line).toString
val kv: KeyValue = new KeyValue(
Bytes.toBytes(rowkey),
Bytes.toBytes(columnFamily),
Bytes.toBytes(column),
Bytes.toBytes(value))
kvlist.append(kv)
}
(ik, kvlist)
}
val result: RDD[(ImmutableBytesWritable, KeyValue)] = listData.flatMapValues(
s => {
val values: Iterator[KeyValue] = s.iterator
values
}
)
val resultDD: RDD[(ImmutableBytesWritable, KeyValue)] = result.sortBy(x =>x._1 , true)
WriteToHbaseDB.hfile_load(result , TableName.valueOf(tableName) , columnFamily)
}
}
WriteTransferTime
def hfile_load(rdd:RDD[(ImmutableBytesWritable , KeyValue)] , tableName: TableName , columnFamily:String): Unit ={
//声明表的信息
var table: Table = null
try{
val startTime = System.currentTimeMillis()
println(s"开始时间:-------->${startTime}")
//生成的HFile的临时保存路径
val stagingFolder = "hdfs://cdh1:9000/hfile/"+tableName+new Date().getTime// table = connection.getTable(tableName)
//如果表不存在,则创建表
if(!admin.tableExists(tableName)){
createTable(tableName , columnFamily)
} //开始导入
val job = Job.getInstance(config)
job.setJobName("DumpFile")
job.setMapOutputKeyClass(classOf[ImmutableBytesWritable])
job.setMapOutputValueClass(classOf[KeyValue]) rdd.sortBy(x => x._1, true).saveAsNewAPIHadoopFile(
stagingFolder,
classOf[ImmutableBytesWritable],
classOf[KeyValue],
classOf[HFileOutputFormat2],
job.getConfiguration) val load = new LoadIncrementalHFiles(config)
val regionLocator = connection.getRegionLocator(tableName)
HFileOutputFormat2.configureIncrementalLoad(job, table, regionLocator)
load.doBulkLoad(new Path(stagingFolder), table.asInstanceOf[HTable])
// load.doBulkLoad(new Path(stagingFolder) , connection.getAdmin , table , regionLocator) val endTime = System.currentTimeMillis()
println(s"结束时间:-------->${endTime}")
println(s"花费的时间:----------------->${(endTime - startTime)}ms")
}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的bulkload报错及解决的更多相关文章
- Spark遇到的报错和坑
1. Java版本不一致,导致启动报错. # 解决方法: 在启动脚本最前边添加系统参数,指定Java版本 export JAVA_HOME=/usr/java/jdk1..0_181-amd64/jr ...
- Spark程序编译报错error: object apache is not a member of package org
Spark程序编译报错: [INFO] Compiling 2 source files to E:\Develop\IDEAWorkspace\spark\target\classes at 156 ...
- Springboot数据库连接池报错的解决办法
Springboot数据库连接池报错的解决办法 这个异常通常在Linux服务器上会发生,原因是Linux系统会主动断开一个长时间没有通信的连接 那么我们的问题就是:数据库连接池长时间处于间歇状态,导致 ...
- window7下安装第三方包报错及解决
window7 64位下安装第三方包,,比如安装yaml的exe执行文件,会 报错及解决:python version 2.7(3.4) required,which was not found in ...
- pom.xml里有红叉报错的解决办法
pom.xml里有红叉报错的解决办法一: 1.把鼠标点在报的错上发现pom.xml报如下错误: Multiple annotations found at this line: - Failure t ...
- eclipes的Spring注解SequenceGenerator(name="sequenceGenerator")报错的解决方式
eclipes的Spring注解SequenceGenerator(name="sequenceGenerator")报错的解决方式 右键项目打开Properties—>JA ...
- Can't bind to local 8700 for debugger报错和解决
[2016-02-15 22:37:17 - ddms] Can't bind to local 8700 for debugger报错和解决 1.打开studio monitor是出错: Can't ...
- Loadrunner参数化连接oracle、mysql数据源报错及解决办法
Loadrunner参数化连接oracle.mysql数据源报错及解决办法 (本人系统是Win7 64, 两位小伙伴因为是默认安装lr,安装在 最终参数化的时候,出现连接字符串无法自动加载出来: 最 ...
- ArcGIS API for Silverlight 调用WebService出现跨域访问报错的解决方法
原文:ArcGIS API for Silverlight 调用WebService出现跨域访问报错的解决方法 群里好几个朋友都提到过这样的问题,说他们在Silverlight中调用了WebServi ...
随机推荐
- CSS概念,引入,选择器
概念 层叠样式表,定义如何显示HTML元素. 使用方式 行内样式 不推荐使用此方式 结构 和 样式的 杂糅会影响后期的维护 <p style="color: red"> ...
- centos 下安装显卡驱动步骤
一. 先下载自己显卡对应的linux版本的驱动文件, 一般都是.run的一个文件. 二.如果是新安装的系统,先安装编译环境,gcc,kernel-devel,kernel-headers (联网) ...
- Vue(小案例_vue+axios仿手机app)_公共组件(路由组件传参)
一.前言 1.公共轮播图的实现 2.组件传参,公共组件的实现 二.主要内容 1.公共轮播图的实现 (1)分析:当渲染不同的轮 ...
- c/c++学习系列之memset()函数
[转载] memset 函数是内存赋值函数,用来给某一块内存空间进行赋值的: 包含在<string.h>头文件中,可以用它对一片内存空间逐字节进行初始化: 原型为 : void *mems ...
- <二>ELK-6.5.3学习笔记–使用rsyslog传输管理nginx日志
http://www.eryajf.net/2362.html 转载于 本文预计阅读时间 28 分钟 文章目录[隐藏] 1,nginx日志json化. 2,发送端配置. 3,接收端配置. 4,配置lo ...
- utf8mb4的大小写敏感性测试及其修改方法
utf8mb4的大小写敏感性测试及其修改方法 utf8mb4_ unicode_ ci 与 utf8mb4_ general_ ci 如何选择字符除了需要存储,还需要排序或比较大小,涉及到与编码字符集 ...
- 2017-12-19python全栈9期第四天第一节之昨日内容回顾与作业讲解之插入insert和extend
#!/user/bin/python# -*- coding:utf-8 -*-li = ['zs','ls','ww','zl']li.insert(4,'cc')print(li)li.exten ...
- Spring Boot集成MyBatis的2种方式
目录 写在前面 准备工作 配置数据库驱动 配置数据源 原生集成MyBatis 依赖配置 注册MyBatis核心组件 定义并使用映射器 通过MyBatis-Spring-Boot-Starter集成 默 ...
- [物理学与PDEs]第2章习题3 Laplace 方程的 Neumann 问题
设 $\Omega$ 为单连通区域, 在其边界 $\vGa$ 上给定向量场 ${\bf u}_B$, 则在 $\bar\Omega$ 中存在速度场 ${\bf u}$, 使其在 $\Omega$ 中成 ...
- v-charts 和 websocket实现数据展示动态推送
v-charts https://v-charts.js.org/#/ ELEMENT力作: 在使用 echarts 生成图表时,经常需要做繁琐的数据类型转化.修改复杂的配置项,v-charts 的出 ...