sparkOnHbase 解决spark读取hbase数据后不能分布式操作

问题描述在hbase数据库中保存了许多的图像帧数据,其中图像一行帧数据用在数据表中对应一个rowkey,需要用这许多的rowkey合成一个图像,发现很慢,和单机上合成图像有的一比;

影响因为图像需要实时合成,合成数据的快慢直接影响了用户的体验;

之前的解决思路:在hbase中的rowkey对应的一行图像帧数据很多,需要先对其进行处理,比如去掉图像行帧数据中的格式、校验图像行等无关信息的去除。之前的解决思路是:通过spark连接hbase,扫描需要合成图像的行,将其全部读取出来转换成rdd,然后查询出来的数据parallelized操作分区,接着对rdd中数据进行map操作如数据过滤,处理完了后collect合并图像行,最后调用jar包将图像行合成图像,其中合成图像那里很快,在处理图像行帧数据时很慢,无解。

新的思路:http://www.tuicool.com/articles/6ZBnQz2,在这里似乎已经做好了。其中有一段是这样描述的:

SparkOnHBase Design : We experimented with many designs for how Spark and HBase integration should work and ended up focusing on a few goals:

Create RDDs through Scan actions or from an existing RDD which are used to generate Get commands.(通过scan和存在的rdd中生成新的rdd,用于生成get命名)为此他们看了下GraphX API in Spark的实现方式。

最终他们写了个类HBaseContext,将sparkcontext和hbase结合在一起,完美的解决了sparkrdd 与hbase相结合的问题。 看段代码:

//造点数据,这些数据就认为是数据表中的rowkey吧
val rdd = sc.parallelize(Array(
(Bytes.toBytes("1")),
	…
	(Bytes.toBytes("6")),
	(Bytes.toBytes("7"))))
//创建HBaseContext
val conf = HBaseConfiguration.create()
//读取配置文件,如果将这2个xml放在该类的路径下如:resource,HBaseConfiguation默认读取,下面可以省略
conf.addResource(new Path("/etc/hbase/conf/core-site.xml"))
conf.addResource(new Path("/etc/hbase/conf/hbase-site.xml"))
val hbaseContext = new HBaseContext(sc, conf);//将sc和hbase结合在一起
//This is the method we are going to focus on
val getRdd = hbaseContext.bulkGet[Array[Byte], String](
  tableName,  //查询数据的表名
  2,  //设置批查询的大小,一般小于 1000
  rdd,  //RDD 用于生成记录的get
  record => {	 //将查询记录转换成get的方法
	 new Get(record)
  },
  (result: Result) > {  //这个方法用来将查询结果转换成序列的对象
	 val it = result.list().iterator()
	 val b = new StringBuilder
	 b.append(Bytes.toString(result.getRow()) + ":")
	 while (it.hasNext()) {
		val kv = it.next()
		val q = Bytes.toString(kv.getQualifier())
		if (q.equals("counter")) {
		  b.append("(" + Bytes.toString(kv.getQualifier()) + "," + Bytes.toLong(kv.getValue()) + ")")
		} else {
		 b.append("(" + Bytes.toString(kv.getQualifier()) + "," + Bytes.toString(kv.getValue()) + ")")
		}
	 }
	 b.toString
  }).collect
上面的getRdd就是处理好的行数据信息rdd集合了。


总结

hbaseContext类结合了sparkrdd的特点,整合hbase表数据Region能最大性能的发挥出spark分布式多核运算的特点。回想之前思路失败的原因是,将数据从habse中查询出来后,之后对图像帧数据所做的所有操作都是在同一个分区下的map操作,或者说始终是基于父类的窄依赖suffle,导致了数据的处理并没有完全使用集群的资源。

你可能感兴趣的:(spark)