我使用Spark插入HBase,但速度很慢。对于60,000条记录,需要2-3分钟。我有大约1000万条记录要保存。
package com.ggl.testing;
import java.awt.Color;
import java.awt.Shape;
public class MyShape {
private int brushSize;
private Color interiorColor;
private Shape shape;
public MyShape() {
this.brushSize = 1;
this.interiorColor = Color.blue;
}
public MyShape(int brushSize, Color interiorColor, Shape shape) {
this.brushSize = brushSize;
this.interiorColor = interiorColor;
this.shape = shape;
}
public int getBrushSize() {
return brushSize;
}
public void setBrushSize(int brushSize) {
this.brushSize = brushSize;
}
public Color getInteriorColor() {
return interiorColor;
}
public void setInteriorColor(Color interiorColor) {
this.interiorColor = interiorColor;
}
public Shape getShape() {
return shape;
}
public void setShape(Shape shape) {
this.shape = shape;
}
}
我在spark-submit中使用它:
object WriteToHbase extends Serializable {
def main(args: Array[String]) {
val csvRows: RDD[Array[String] = ...
val dateFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")
val usersRDD = csvRows.map(row => {
new UserTable(row(0), row(1), row(2), row(9), row(10), row(11))
})
processUsers(sc: SparkContext, usersRDD, dateFormatter)
})
}
def processUsers(sc: SparkContext, usersRDD: RDD[UserTable], dateFormatter: DateTimeFormatter): Unit = {
usersRDD.foreachPartition(part => {
val conf = HBaseConfiguration.create()
val table = new HTable(conf, tablename)
part.foreach(userRow => {
val id = userRow.id
val name = userRow.name
val date1 = dateFormatter.parseDateTime(userRow.date1)
val hRow = new Put(Bytes.toBytes(id))
hRow.add(cf, q, Bytes.toBytes(date1))
hRow.add(cf, q, Bytes.toBytes(name))
...
table.put(hRow)
})
table.flushCommits()
table.close()
})
}
答案 0 :(得分:3)
它很慢,因为实施并没有利用数据的接近程度;服务器中的Spark RDD可以传输到另一台服务器上运行的HBase RegionServer。
目前没有Spark的RRD操作以高效的方式使用HBase数据存储。
答案 1 :(得分:0)
在Htable中有一个批处理api,你可以尝试发送put请求为100-500 put包。我认为它可以加快你的速度。它返回每个操作的单个结果,因此您可以根据需要检查失败的放置。
public void batch(List<? extends Row> actions, Object[] results)
答案 2 :(得分:0)
您必须查看可以分发您的传入数据到 Spark 作业的方法。在您当前的 foreachPartition 方法中,您必须查看map,mapToPair等转换。您需要评估整个 DAG生命周期以及可以节省更多时间的地方。
之后基于Parallelism实现,您可以调用 saveAsNewAPIHadoopDataset Spark的操作,以更快速和并行地写入HBase内部。像:
JavaPairRDD<ImmutableBytesWritable, Put> yourFinalRDD = yourRDD.<SparkTransformation>{()};
yourFinalRDD.saveAsNewAPIHadoopDataset(yourHBaseConfiguration);
注意: yourHBaseConfiguration 将是单例,并且将成为Executor节点上的单个对象,以便在任务之间共享
如果这个伪代码对您不起作用或者发现任何困难,请告诉我。