如何通过Spark Job将DELETE查询发送到HBase

时间:2019-04-04 12:31:37

标签: apache-spark apache-spark-sql hbase phoenix

我有一个用于自动SparkSQL作业的用例,我想在其中使用该例:

  1. 使用Spark从Phoenix读取一个表(我们称之为table1),并将所有找到的负值收集到一个DataFrame中(我们将其称为df1)

  2. 然后,我想从另一个表(表2)中删除记录,在该表中,列中的值位于df1中(想做一个JOIN查询,但我想知道这是否可以用DataFrame进行,以及是否存在是使用HBase和Spark DataFrames的API)

  3. AFAIK Phoenix不直接通过Spark支持DELETE操作(如果我错了,并且有一种我很想听到的方法,请纠正我),这就是为什么我倾向于使用HBase Spark API


这里是一个更直观地说明的模式:

schema


这是一些代码。

在DataFrame中收集负值:

// Collect negative values
val negativeValues = spark
  .sqlContext
  .phoenixTableAsDataFrame("phoenix.table1", Seq(), conf = hbaseConf)
  .select('COLUMN1)
  .where('COLUMN2.lt(0))

// Send the query
[...]

从table2中删除其中COLUMN1为negativeValues的值,因此在SQL中是这样的(如果可以将IN直接应用于DF):

DELETE FROM table2 WHERE COLUMN1 IN negativeValues

我的预期结果是:

table1

column1 |   column2
        |
123456  |   123
234567  |   456
345678  |   -789
456789  |   012
567891  |   -123



table2

column1 |   column2
        |
123456  |   321
234567  |   654
345678  |   945 <---- same column1 as table1's, so delete
456789  |   987
567891  |   675 <---- same column1 as table1's, so delete

所以最终,我想知道是否有一种方法可以通过Spark将DELETE请求发送到HBase,而不必大惊小怪。

谢谢。

1 个答案:

答案 0 :(得分:0)

如果需要从Spark通过Phoenix(sql engine)到Hbase运行“ DELETE”查询,则必须创建一个自定义API。

可以使用以下方法,

  1. 从源数据框中获取table2行键列以进行删除(在table2上)。
  2. 构造代码以对源数据帧的每个分区进行操作,并构建“ DELETE”查询。假设查询为“从table2 WHERE column1 =?中删除”,准备它并以您看到的正确批处理大小将其执行。由于我们是在数据帧的每个分区上并行执行它,因此源数据帧中的分区数将驱动并行性。因此,您可以尝试使用合适的大小对其进行重新分区,以查看正确的性能指标。

如果该选项是跳过sql引擎,则还可以使用spark-hbase直接API。这是一个这样的例子-https://github.com/tmalaska/SparkOnHBase/blob/master/src/main/scala/org/apache/hadoop/hbase/spark/example/hbasecontext/HBaseBulkDeleteExample.scala