除了多线程

时间:2018-04-20 10:16:40

标签: scala apache-spark hbase

我有一个rowPrefixes Array("a", "b", ...)

的列表

我需要为每个rowPrefix查询HBase(使用Nerdammer)。我目前的解决方案是

case class Data(x: String)

val rowPrefixes = Array("a", "b", "c")

rowPrefixes.par
    .map( rowPrefix => {
          val rdd = sc.hbaseTable[Data]("tableName")
            .inColumnFamily("columnFamily")
            .withStartRow(rowPrefix)

          rdd
        })
    .reduce(_ union _)

我基本上是使用多线程(.par)加载多个rdd,然后最后将所有这些加入工会。有一个更好的方法吗?除了nerdammer,我不介意使用其他库。

此外,我担心reflection API threadsafe issue,因为我正在将hbase读入案例类的RDD。

1 个答案:

答案 0 :(得分:0)

我没有使用过Nerdammer连接器但是如果我们考虑你的4个前缀行密钥过滤器的例子,使用par并行数量会受到限制,集群可能会得不到充分利用,结果可能会很慢。

您可以检查是否可以使用Nerdammer连接器实现以下功能,我使用了hbase-spark连接器(CDH),在下面的方法中,将在所有表分区中扫描行键前缀,即所有表区域分布在整个群集中并行,可以更有效地利用可用资源(核心/ RAM),更重要的是利用分布式计算的强大功能。

val hbaseConf = HBaseConfiguration.create()
// set zookeeper quorum properties in hbaseConf

val hbaseContext = new HBaseContext(sc, hbaseConf)

val rowPrefixes = Array("a", "b", "c")
val filterList = new FilterList()

rowPrefixes.foreach { x => filterList.addFilter(new PrefixFilter(Bytes.toBytes(x))) }

var scan = new Scan()  

scan.setFilter(filterList)
scan.addFamily(Bytes.toBytes("myCF"));

val rdd = hbaseContext.hbaseRDD(TableName.valueOf("tableName"), scan)
rdd.mapPartitions(populateCaseClass)

在你的情况下,如果你有足够的核心可用,并且par可以为rowPrefixes数组中的每个元素分配一个核心,那么只会进行全面的表扫描,但只有4个分区会做大量的工作。

希望这会有所帮助。