【问题标题】:How to connect to remote hive server from spark [duplicate]如何从火花连接到远程配置单元服务器[重复]
【发布时间】:2017-02-21 04:10:50
【问题描述】:

我在本地运行 spark 并希望访问位于远程 Hadoop 集群中的 Hive 表。

我可以通过在 SPARK_HOME 下启动 beeline 来访问蜂巢表

[ml@master spark-2.0.0]$./bin/beeline 
Beeline version 1.2.1.spark2 by Apache Hive
beeline> !connect jdbc:hive2://remote_hive:10000
Connecting to jdbc:hive2://remote_hive:10000
Enter username for jdbc:hive2://remote_hive:10000: root
Enter password for jdbc:hive2://remote_hive:10000: ******
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/home/ml/spark/spark-2.0.0/jars/slf4j-log4j12-1.7.16.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/usr/hadoop/share/hadoop/common/lib/slf4j-log4j12-1.7.10.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
16/10/12 19:06:39 INFO jdbc.Utils: Supplied authorities: remote_hive:10000
16/10/12 19:06:39 INFO jdbc.Utils: Resolved authority: remote_hive:10000
16/10/12 19:06:39 INFO jdbc.HiveConnection: Will try to open client transport with JDBC Uri: jdbc:hive2://remote_hive:10000
Connected to: Apache Hive (version 1.2.1000.2.4.2.0-258)
Driver: Hive JDBC (version 1.2.1.spark2)
Transaction isolation: TRANSACTION_REPEATABLE_READ
0: jdbc:hive2://remote_hive:10000>

如何从 spark 以编程方式访问远程配置单元表?

【问题讨论】:

  • val sqlContext = new org.apache.spark.sql.hive.HiveContext(sc) sqlContext.sql("show tables") 不会工作?

标签: apache-spark hive apache-spark-sql spark-thriftserver


【解决方案1】:

JDBC 不是必需的

Spark 直接连接到 Hive 元存储,而不是通过 HiveServer2。要配置它,

  1. hive-site.xml 放在您的classpath 上,并将hive.metastore.uris 指定到您的hive Metastore 托管位置。另见How to connect to a Hive metastore programmatically in SparkSQL?

  2. 导入 org.apache.spark.sql.hive.HiveContext,因为它可以对 Hive 表执行 SQL 查询。

  3. 定义val sqlContext = new org.apache.spark.sql.hive.HiveContext(sc)

  4. 验证sqlContext.sql("show tables") 看看它是否有效

SparkSQL on Hive tables

结论:如果一定要走jdbc方式

看看connecting apache spark with apache hive remotely.

请注意,beeline 也通过 jdbc 连接。从您的日志中可以看出。

[ml@master spark-2.0.0]$./bin/beeline 直线版本 1.2.1.spark2 由 Apache Hive beeline> !connect jdbc:hive2://remote_hive:10000

连接到 jdbc:hive2://remote_hive:10000

所以请看看这个interesting article

  • 方法一:使用 JDBC 将表拉入 Spark
  • 方法 2:使用 Spark JdbcRDD 和 HiveServer2 JDBC 驱动程序
  • 方法3:在客户端获取数据集,然后手动创建RDD

目前 HiveServer2 驱动不允许我们使用“Sparkling”方法 1 和 2,我们只能依赖方法 3

下面是示例代码sn-p,通过它可以实现

通过 HiveServer2 JDBC 连接将数据从一个 Hadoop 集群(又名“远程”)加载到另一个(我的 Spark 所在的集群,又名“国内”)。

import java.sql.Timestamp
import scala.collection.mutable.MutableList

case class StatsRec (
  first_name: String,
  last_name: String,
  action_dtm: Timestamp,
  size: Long,
  size_p: Long,
  size_d: Long
)

val conn: Connection = DriverManager.getConnection(url, user, password)
val res: ResultSet = conn.createStatement
                   .executeQuery("SELECT * FROM stats_201512301914")
val fetchedRes = MutableList[StatsRec]()
while(res.next()) {
  var rec = StatsRec(res.getString("first_name"), 
     res.getString("last_name"), 
     Timestamp.valueOf(res.getString("action_dtm")), 
     res.getLong("size"), 
     res.getLong("size_p"), 
     res.getLong("size_d"))
  fetchedRes += rec
}
conn.close()
val rddStatsDelta = sc.parallelize(fetchedRes)
rddStatsDelta.cache()




 // Basically we are done. To check loaded data:

println(rddStatsDelta.count)
rddStatsDelta.collect.take(10).foreach(println)

【讨论】:

  • Spark 是否应该始终与 Hive 位于同一个集群上?是否可以将它放在另一个集群上?
  • @MichaelD: 1) 可能会也可能不会 2) 可能
  • @RamGhadiyaram 我也在尝试同样的方法,但我有疑问。当数据量很大时,这种方法会起作用吗,比如如果我的 hive 表有几百 GB,它不会导致“内存不足”异常吗?在这种情况下我该怎么办??
  • @aladeen :我假设您在谈论方法 3 .. 如果是这样,您可以在此处使用批处理技术来获取结果,让我们说 100000 条记录作为列表并将其转换为一个 rdd 然后清除列出并再次对所有记录执行相同操作....我们将得到 rdd1 ....rddn,所以现在您可以通过 union all 组合这些 rdd 并制作一个 rdd。由于我们正在准备 100000 的列表。然后清除 OOM 不会到来。如果出现,则进一步减少记录数。
  • @RamGhadiyaram 对不起,是的,我指的是第三种方法。能否请您解释一下如何批量提取一个连续写入的 Hive 表??
【解决方案2】:

在向 SPARK 提供 hive-ste.xml 配置并启动 HIVE Metastore 服务后,

在连接到 HIVE 时,需要在 SPARK Session 中配置两件事:

  1. 由于 Spark SQL 使用 thrift 连接到 Hive Metastore,我们需要在创建 Spark 会话时提供 thrift 服务器 uri。
  2. Hive Metastore 仓库,这是 Spark SQL 保存表的目录。 使用对应于“hive.metastore.warehouse.dir”的属性“spark.sql.warehouse.dir”(因为这在 Spark 2.0 中已弃用)

类似:

    SparkSession spark=SparkSession.builder().appName("Spark_SQL_5_Save To Hive").enableHiveSupport().getOrCreate();
    spark.sparkContext().conf().set("spark.sql.warehouse.dir", "/user/hive/warehouse");
    spark.sparkContext().conf().set("hive.metastore.uris", "thrift://localhost:9083");

希望对您有所帮助!!

【讨论】:

    【解决方案3】:

    根据文档:

    请注意,hive-site.xml 中的 hive.metastore.warehouse.dir 属性自 Spark 2.0.0 以来已弃用。而是使用 spark.sql.warehouse.dir 指定仓库中数据库的默认位置。

    所以在SparkSession 中你需要指定spark.sql.uris 而不是hive.metastore.uris

        from pyspark.sql import SparkSession
        spark = SparkSession \
            .builder \
            .appName("Python Spark SQL Hive integration example") \
            .config("spark.sql.uris", "thrift://<remote_ip>:9083") \
            .enableHiveSupport() \
            .getOrCreate()
        spark.sql("show tables").show()
    

    【讨论】:

    • 它正在显示表格。但是当我对该表应用查询时,它返回空数据框。
    • 设置后我可以看到“显示表格”的记录。但是在对特定表的 sql 查询中,它给出了这个错误 "No FileSystem for scheme s3" 。我已经为 spark 设置了 s3a,如果我使用 s3,那么 spark 会抛出错误以使用 S3a。这是僵局吗?
    猜你喜欢
    • 1970-01-01
    • 2019-06-16
    • 2019-02-07
    • 2014-06-29
    • 2021-10-31
    • 2018-04-13
    • 1970-01-01
    • 2018-09-17
    • 1970-01-01
    相关资源
    最近更新 更多