【问题标题】:HBase Spark connection options [Java]HBase Spark 连接选项 [Java]
【发布时间】:2018-02-14 12:32:26
【问题描述】:

我正在尝试从运行在 YARN 上的 java Spark 应用程序访问 HBase,但我需要一些有关如何执行此操作的线索。我已经在网上搜索过,但我找不到确切的答案。他们在这里:

  • 基本问题:如何从 Spark 与 HBase 交互?我是否需要在每个工作人员上设置 HBase 连接(可能通过 mapPartition 来保存一些连接),或者我可以在创建后从驱动程序共享它?
  • 是否可以由驱动程序实例化 HBase 表对象并将其传送给工作人员,以便对其执行 Put 和 Get 操作?
  • (与上一个相关)在 Spark 中使用单个 Put/Get 操作与 HBase 交互是一种好习惯吗?还有其他选择吗?

感谢您的回答

【问题讨论】:

  • 不确定是否仍然与您相关——刚刚发布了适用于 Java 的以下内容 (stackoverflow.com/questions/49494483/…)。似乎工作正常,但我担心的是它似乎没有像预期的那样重用分布式扫描的 HBase 连接。如果您尝试,会很好奇您对此有何看法...

标签: java hadoop apache-spark hbase database-connection


【解决方案1】:

Q1:您可以使用Hortonworks Spark HBase Connector(在可用的 3 个连接器中,它支持 Spark 2.x)

这将简化上面的 q2 和 q3。您将能够从 HBase 作为 RDD 加载数据,然后按照您的喜好对其进行操作(转换为 Dataframe 并在此处操作,或转换为 tmp 表 im-memory 并在顶部编写 sql 查询等)

按照上面链接的设置,就可以了..

加载表格:

def catalog = s"""{
        |"table":{"namespace":"default", "name":"table1"},
        |"rowkey":"key",
        |"columns":{
          |"col0":{"cf":"rowkey", "col":"key", "type":"string"},
          |"col1":{"cf":"cf1", "col":"col1", "type":"boolean"},
          |"col2":{"cf":"cf2", "col":"col2", "type":"double"},
          |"col3":{"cf":"cf3", "col":"col3", "type":"float"},
          |"col4":{"cf":"cf4", "col":"col4", "type":"int"},
          |"col5":{"cf":"cf5", "col":"col5", "type":"bigint"},
          |"col6":{"cf":"cf6", "col":"col6", "type":"smallint"},
          |"col7":{"cf":"cf7", "col":"col7", "type":"string"},
          |"col8":{"cf":"cf8", "col":"col8", "type":"tinyint"}
        |}
      |}""".stripMargin

  sqlContext
  .read
  .options(Map(HBaseTableCatalog.tableCatalog->catalog))
  .format("org.apache.spark.sql.execution.datasources.hbase")
  .load()
}

写一个表格:

sc.parallelize(data).toDF.write.options(
  Map(HBaseTableCatalog.tableCatalog -> catalog, HBaseTableCatalog.newTable -> "5"))
  .format("org.apache.spark.sql.execution.datasources.hbase")
  .save()

【讨论】:

  • 谢谢@jayfah 的回答。糟糕的是,我没有指出编程语言(Java),以及数据高度非结构化的事实,因此提供目录并非易事。是否可以使用提到的连接器执行单个 Get 和 Put?
【解决方案2】:

您可以同时使用这两个选项:

  1. 在每个分区(在 mapPartition 或 foreachPartition 内)上设置 HBase 连接。如果您希望每个执行程序有一个连接,则必须在 mapPartition/foreachPartition 中实现一种单例连接对象/池,并在该执行程序执行的所有任务之间共享它(请注意,某些 HBase 客户端 API 不是线程安全的,最后完成的任务必须关闭连接,客户端缓冲区可能会快速增长)。

  2. 使用 Spark-Hbase 连接器 (SHC):您可以在非常原始的级别(放置、获取、扫描、删除、变异等)与 HBase 进行交互,而不仅仅是通过结构化数据帧

【讨论】:

    【解决方案3】:

    “最基本的:如何从 Spark 与 HBase 交互?是否需要在每个 worker 上建立一个 HBase 连接(可能通过 mapPartition 来保存一些连接),或者我可以在创建后从驱动程序共享它? "

    答:使用 HBase 文档中提供的 HBase Spark: https://hbase.apache.org/book.html#spark 它有一个名为 HBaseContext 的对象为您管理它。如果您对它的完成方式感兴趣,您也可以在此处查看源代码以及一些示例:https://github.com/apache/hbase-connectors/tree/master/spark/hbase-spark 有关详细信息,请参阅本教程:https://sparkbyexamples.com/hbase/spark-hbase-connectors-which-one-to-use/#hbase-spark

    “HBase 表对象能否由驱动程序实例化并传送给工作人员,以便对其执行 Put 和 Get 操作?”

    答:有些可以。这正是上面的库所做的。它们必须是/实现可串行化的。 您可以深入了解 HBaseContext 的实现作为示例:https://sparkbyexamples.com/hbase/spark-hbase-connectors-which-one-to-use/#hbase-spark 有关向工作人员运送对象的更多信息,请阅读 spark 文档中有关广播和累加器的信息:https://spark.apache.org/docs/latest/rdd-programming-guide.html#shared-variables

    “(与上一个相关)在 Spark 中使用单个 Put/Get 操作与 HBase 交互是一种好习惯吗?还有其他选择吗?”

    答:它的效果很好,具体取决于您的用例。如果您需要每个键的随机读/写(例如,在 Spark Streaming 管道中)和低级功能,那么可以使用这个库。但是,如果您需要更多结构化功能(并且具有结构化数据)、使用 DataFrame 并扫描表的全部/大部分,您可以使用其他更简单的 API,例如 Phoenix 连接器或 SHC api。请参阅:hbase-spark for Spark 2https://sparkbyexamples.com/hbase/spark-hbase-connectors-which-one-to-use/

    作为参考,我已经用 Java 检查了所有这些可能性。

    【讨论】:

      猜你喜欢
      • 2017-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-04
      • 2017-03-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多