【问题标题】:How to connect Spark SQL to remote Hive metastore (via thrift protocol) with no hive-site.xml?如何在没有 hive-site.xml 的情况下将 Spark SQL 连接到远程 Hive 元存储(通过节俭协议)?
【发布时间】:2015-11-05 23:16:26
【问题描述】:

我正在将 HiveContext 与 SparkSQL 一起使用,并且我正在尝试连接到远程 Hive 元存储,设置 hive 元存储的唯一方法是在类路径中包含 hive-site.xml(或将其复制到 /etc /spark/conf/)。

有没有办法在不包含 hive-site.xml 的 java 代码中以编程方式设置此参数?如果是这样,要使用什么 Spark 配置?

【问题讨论】:

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


    【解决方案1】:

    对于 Spark 3.x:

    // Scala
    import org.apache.spark.sql.{Row, SaveMode, SparkSession}
    
    val spark = SparkSession
      .builder()
      .appName("Spark Hive Example")
      .config("spark.sql.warehouse.dir", "hive_warehouse_hdfs_path")
      .enableHiveSupport()
      .getOrCreate()
    
    # Python
    from pyspark.sql import SparkSession
    
    spark = SparkSession \
        .builder \
        .appName("Python Spark SQL Hive integration example") \
        .config("spark.sql.warehouse.dir", "hive_warehouse_hdfs_path") \
        .enableHiveSupport() \
        .getOrCreate()
    

    检查可用的数据库:

    spark.catalog.listDatabases().show()
    

    source

    【讨论】:

      【解决方案2】:

      我在不使用 hive-site.xml 的情况下尝试从 spark 连接到 hive Metastore 时观察到一种奇怪的行为。

      当我们在创建 SparkSession 时在 spark 代码中使用 hive.metastore.uris 属性时,一切正常。 但是,如果我们不在代码中指定,而是在使用 spark-shellspark-submit--conf 标志时指定,它将不起作用。

      它会抛出如下所示的警告,并且它不会连接到远程元存储。

      Warning: Ignoring non-Spark config property: hive.metastore.uris
      

      一种解决方法是使用以下属性。

      spark.hadoop.hive.metastore.uris
      

      【讨论】:

        【解决方案3】:

        设置 spark.hadoop.metastore.catalog.default=hive 对我有用。

        【讨论】:

          【解决方案4】:

          在 Hadoop 3 中,Spark 和 Hive 目录是分开的:

          对于spark-shell(默认带有.enableHiveSupport())试试:

          pyspark-shell --conf spark.hadoop.metastore.catalog.default=hive
          

          对于 spark-submit 工作,您可以像这样创建 Spark 会话:

          SparkSession.builder.appName("Test").enableHiveSupport().getOrCreate()
          

          然后在您的 spark-submit 命令中添加此配置:

          --conf spark.hadoop.metastore.catalog.default=hive
          

          但对于 ORC 表(以及更普遍的内部表),建议使用 HiveWareHouse 连接器。

          【讨论】:

            【解决方案5】:

            一些类似的问题被标记为重复,这是从 Spark 连接到 Hive 而不使用 hive.metastore.uris 或单独的 thrift server(9083) 并且不将 hive-site.xml 复制到 SPARK_CONF_DIR。

            import org.apache.spark.sql.SparkSession
            val spark = SparkSession
              .builder()
              .appName("hive-check")
              .config(
                "spark.hadoop.javax.jdo.option.ConnectionURL",
                "JDBC_CONNECT_STRING"
              )
              .config(
                "spark.hadoop.javax.jdo.option.ConnectionDriverName",
                "org.postgresql.Driver"
              )
              .config("spark.sql.warehouse.dir", "/user/hive/warehouse")
              .config("spark.hadoop.javax.jdo.option.ConnectionUserName", "JDBC_USER")
              .config("spark.hadoop.javax.jdo.option.ConnectionPassword", "JDBC_PASSWORD")
              .enableHiveSupport()
              .getOrCreate()
            spark.catalog.listDatabases.show(false)
            

            【讨论】:

              【解决方案6】:

              Spark 版本:2.0.2

              Hive 版本:1.2.1

              以下 Java 代码帮助我从 Spark 连接到 Hive 元存储:

              import org.apache.spark.sql.SparkSession;
              
              public class SparkHiveTest {
              
                  public static void main(String[] args) {
              
                      SparkSession spark = SparkSession
                                .builder()
                                .appName("Java Spark Hive Example")
                                .config("spark.master", "local")
                                .config("hive.metastore.uris",                
                                 "thrift://abc123.com:9083")
                                .config("spark.sql.warehouse.dir", "/apps/hive/warehouse")
                                .enableHiveSupport()
                                .getOrCreate();
              
                      spark.sql("SELECT * FROM default.survey_data limit 5").show();
                  }
              }
              

              【讨论】:

              • 嗨!如果您想恢复一个老问题,为什么不尝试一些未回答的问题,而不是一个已经排名靠前的问题?致敬!
              【解决方案7】:

              以下代码对我有用。我们可以忽略hive.metastore.uris对于本地metastore的配置,spark会在本地的spare-warehouse目录中创建hive对象。

              import org.apache.spark.sql.SparkSession;
              
              object spark_hive_support1 
              {
                def main (args: Array[String]) 
                 {
                  val spark = SparkSession
                    .builder()
                    .master("yarn")
                    .appName("Test Hive Support")
                    //.config("hive.metastore.uris", "jdbc:mysql://localhost/metastore")
                    .enableHiveSupport
                    .getOrCreate();
              
                  import spark.implicits._
              
                  val testdf = Seq(("Word1", 1), ("Word4", 4), ("Word8", 8)).toDF;
                  testdf.show;
                  testdf.write.mode("overwrite").saveAsTable("WordCount");
                }
              }
              

              【讨论】:

              • hive.metastore.uris 应该指定一个thrift:// 地址,而不是jdbc:
              【解决方案8】:

              我也遇到了同样的问题,但解决了。只需在 Spark 2.0 版本中执行此步骤

              步骤 1: 将 hive-site.xml 文件从 Hive conf 文件夹复制到 spark conf。

              第 2 步: 编辑 spark-env.sh 文件并配置您的 mysql 驱动程序。 (如果您使用 Mysql 作为配置单元元存储。)

              或将 MySQL 驱动程序添加到 Maven/SBT(如果使用这些驱动程序)

              第 3 步: 在创建 spark 会话时添加 enableHiveSupport()

              val spark = SparkSession.builder.master("local").appName("testing").enableHiveSupport().getOrCreate()

              示例代码:

              package sparkSQL
              
              /**
                * Created by venuk on 7/12/16.
                */
              
              import org.apache.spark.sql.SparkSession
              
              object hivetable {
                def main(args: Array[String]): Unit = {
                  val spark = SparkSession.builder.master("local[*]").appName("hivetable").enableHiveSupport().getOrCreate()
              
                  spark.sql("create table hivetab (name string, age int, location string) row format delimited fields terminated by ',' stored as textfile")
                  spark.sql("load data local inpath '/home/hadoop/Desktop/asl' into table hivetab").show()
                  val x = spark.sql("select * from hivetab")
                  x.write.saveAsTable("hivetab")
                }
              }
              

              输出:

              【讨论】:

              • x.write.saveAsTable("hivetab") 不是多余的吗?您已经通过load data local inpath 编写了值
              • 您使用的是哪个版本的 Hive、hadoop 和 Spark?你能具体说明吗?我正在尝试连接但遇到问题
              • spark 没有通过 thrift 协议与 hive 元存储进行通信吗?为什么需要mysql驱动?
              【解决方案9】:

              对于 Spark 1.x,您可以设置:

              System.setProperty("hive.metastore.uris", "thrift://METASTORE:9083");
              
              final SparkConf conf = new SparkConf();
              SparkContext sc = new SparkContext(conf);
              HiveContext hiveContext = new HiveContext(sc);
              

              或者

              final SparkConf conf = new SparkConf();
              SparkContext sc = new SparkContext(conf);
              HiveContext hiveContext = new HiveContext(sc);
              hiveContext.setConf("hive.metastore.uris", "thrift://METASTORE:9083");
              

              如果您的 Hive 是 Kerberized 则更新

              在创建 HiveContext 之前尝试设置这些:

              System.setProperty("hive.metastore.sasl.enabled", "true");
              System.setProperty("hive.security.authorization.enabled", "false");
              System.setProperty("hive.metastore.kerberos.principal", hivePrincipal);
              System.setProperty("hive.metastore.execute.setugi", "true");
              

              【讨论】:

              • 如果是 Kerberized 远程 Hive 集群,需要哪些额外的 HiveContext 配置设置?在这种情况下,上面的代码对我不起作用,我想知道您是否有解决方案。谢谢。
              • 还是不行。我的设置: ("hive.metastore.uris","myValue") ("login.user","myValue") ("keytab.file","myValue") ("sun.security.krb5.debug"," false") ("java.security.krb5.conf","myValue") ("java.library.path","myValue") ("hadoop.home.dir","myValue") ("hadoop.security.身份验证","kerberos") ("hive.metastore.sasl.enabled", "true") ("hive.security.authorization.enabled", "false") ("hive.metastore.kerberos.principal", "myValue ") ("hive.metastore.execute.setugi", "true")
              • 根据我在日志中看到的内容,我的本地 Spark 甚至没有尝试连接远程 Hive
              【解决方案10】:

              在 spark 2.0.+ 中应该是这样的:

              不要忘记用你的替换“hive.metastore.uris”。这 假设您已经启动了一个配置单元元存储服务(不是 蜂巢服务器)。

               val spark = SparkSession
                        .builder()
                        .appName("interfacing spark sql to hive metastore without configuration file")
                        .config("hive.metastore.uris", "thrift://localhost:9083") // replace with your hivemetastore service's thrift url
                        .enableHiveSupport() // don't forget to enable hive support
                        .getOrCreate()
              
                      import spark.implicits._
                      import spark.sql
                      // create an arbitrary frame
                      val frame = Seq(("one", 1), ("two", 2), ("three", 3)).toDF("word", "count")
                      // see the frame created
                      frame.show()
                      /**
                       * +-----+-----+
                       * | word|count|
                       * +-----+-----+
                       * |  one|    1|
                       * |  two|    2|
                       * |three|    3|
                       * +-----+-----+
                       */
                      // write the frame
                      frame.write.mode("overwrite").saveAsTable("t4")
              

              【讨论】:

              • 如果我使用上述config(..) 方法提供配置,同时还提供hive-site.xml,哪一个会持续存在?有没有办法控制它?
              • 两者。 hive-site.xml 用作被 Spark 属性覆盖的基本配置。我推荐的方法是将配置保留在代码之外(conf/hive-site.xml),因此无需重新编译应用程序以进行任何配置更改。
              猜你喜欢
              • 2019-06-09
              • 1970-01-01
              • 2018-05-06
              • 1970-01-01
              • 2018-10-21
              • 1970-01-01
              • 2016-06-17
              • 2021-03-04
              • 1970-01-01
              相关资源
              最近更新 更多