【问题标题】:How to use Hive Metastore with MySQL (for Thrift Server or spark-shell)?如何将 Hive Metastore 与 MySQL 一起使用(用于 Thrift Server 或 spark-shell)?
【发布时间】:2017-12-19 07:28:17
【问题描述】:

我正在使用 Apache Spark 2.1.1,我想使用外部 Hive 元存储(专门针对 Spark Thrift 服务器)设置它。

我已将hive-site.xml 添加到$SPARK_HOME/conf 文件夹,如下所示:

<?xml version="1.0"?>
<configuration>
  <property>
    <name>javax.jdo.option.ConnectionURL</name>
    <value>jdbc:mysql://home.cu:3306/hive_metastore?createDatabaseIfNotExist=true&amp;useLegacyDatetimeCode=false&amp;serverTimezone=Europe/Berlin&amp;nullNamePatternMatchesAll=true </value>
    <description>JDBC connect string for a JDBC metastore</description>
  </property>

  <property>
    <name>javax.jdo.option.ConnectionDriverName</name>
    <value>com.mysql.jdbc.Driver</value>
    <description>Driver class name for a JDBC metastore</description>
  </property>

  <property>
    <name>javax.jdo.option.ConnectionUserName</name>
    <value>hive</value>
    <description>username to use against metastore database</description>
  </property>

  <property>
    <name>javax.jdo.option.ConnectionPassword</name>
    <value>hive</value>
    <description>password to use against metastore database</description>
  </property>
  <property>
    <name>hive.metastore.schema.verification</name>
    <value>false</value>
    <description>password to use against metastore database</description>
  </property>

  <property>
    <name>hive.metastore.warehouse.dir</name>
    <value>hdfs://spark-master.cu:9000/value_iq/hive_warehouse/</value>
    <description>Warehouse Location</description>
  </property>
</configuration>

每当我尝试运行 spark-shell 或 Spark Thrift Server 时,它们都会尝试在 MySQL 上创建 Hive 元存储(因为还没有元存储),但它们失败并出现以下错误:

17/07/13 19:57:55 ERROR Datastore: Error thrown executing ALTER TABLE `PARTITIONS` ADD COLUMN `TBL_ID` BIGINT NULL : Table 'hive_metastore.partitions' doesn't exist
java.sql.SQLSyntaxErrorException: Table 'hive_metastore.partitions' doesn't exist
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:536)
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:513)
        at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:115)
        at com.mysql.cj.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:1983)
        at com.mysql.cj.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:1936)
        at com.mysql.cj.jdbc.StatementImpl.executeInternal(StatementImpl.java:891)
        at com.mysql.cj.jdbc.StatementImpl.execute(StatementImpl.java:795)
        at com.jolbox.bonecp.StatementHandle.execute(StatementHandle.java:254)
        at org.datanucleus.store.rdbms.table.AbstractTable.executeDdlStatement(AbstractTable.java:760)
        at org.datanucleus.store.rdbms.table.AbstractTable.executeDdlStatementList(AbstractTable.java:711)
        at org.datanucleus.store.rdbms.table.TableImpl.validateColumns(TableImpl.java:259)
        at org.datanucleus.store.rdbms.RDBMSStoreManager$ClassAdder.performTablesValidation(RDBMSStoreManager.java:3393)
        at org.datanucleus.store.rdbms.RDBMSStoreManager$ClassAdder.addClassTablesAndValidate(RDBMSStoreManager.java:3190)
        at org.datanucleus.store.rdbms.RDBMSStoreManager$ClassAdder.run(RDBMSStoreManager.java:2841)
        at org.datanucleus.store.rdbms.AbstractSchemaTransaction.execute(AbstractSchemaTransaction.java:122)
        at org.datanucleus.store.rdbms.RDBMSStoreManager.addClasses(RDBMSStoreManager.java:1605)
        at org.datanucleus.store.AbstractStoreManager.addClass(AbstractStoreManager.java:954)
        at org.datanucleus.store.rdbms.RDBMSStoreManager.getDatastoreClass(RDBMSStoreManager.java:679)
        at org.datanucleus.store.rdbms.query.RDBMSQueryUtils.getStatementForCandidates(RDBMSQueryUtils.java:408)
        at org.datanucleus.store.rdbms.query.JDOQLQuery.compileQueryFull(JDOQLQuery.java:947)
        at org.datanucleus.store.rdbms.query.JDOQLQuery.compileInternal(JDOQLQuery.java:370)
        at org.datanucleus.store.query.Query.executeQuery(Query.java:1744)
        at org.datanucleus.store.query.Query.executeWithArray(Query.java:1672)
        at org.datanucleus.store.query.Query.execute(Query.java:1654)
        at org.datanucleus.api.jdo.JDOQuery.execute(JDOQuery.java:221)

【问题讨论】:

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


    【解决方案1】:

    我发现了问题,它与 MySQL 驱动程序有关,我使用的是 mysql-connector-java-6.0.6-bin.jar,我已将其替换为旧的 mysql-connector-java-5.1.23-bin.jar,现在它可以工作了。

    【讨论】:

      【解决方案2】:

      我觉得你的仓库dir属性配置不正确,应该是HDFS上的路径

      <configuration>
      <property>
          <name>hive.metastore.uris</name>
          <value>thrift://maprdemo:9083</value>
      </property>
      <property>
          <name>hive.metastore.warehouse.dir</name>
          <value>/user/hive/warehouse</value>
      </property>
      

      【讨论】:

      • 但它是hdfs中的路径:&lt;property&gt; &lt;name&gt;hive.metastore.warehouse.dir&lt;/name&gt; &lt;value&gt;hdfs://spark-master.cu:9000/value_iq/hive_warehouse/&lt;/value&gt; &lt;description&gt;Warehouse Location&lt;/description&gt; &lt;/property&gt;
      • 确保它是可访问的,如果你有 Hue 而不是导航到它。如果它比在其上执行 hadoop fs -ls 应该产生仓库目录是正确的,但我会像这样 hdfs://value_iq/hive_warehouse/ (删除地址和端口)
      • 是的,它是可访问的,但这与元存储创建脚本(或它们使用的任何东西)失败的事实有关,因为它试图更改表 partitions 但不存在:ERROR Datastore: Error thrown executing ALTER TABLE PARTITIONS ADD COLUMN TBL_ID BIGINT NULL : Table hive_metastore.partitions doesn't exist java.sql.SQLSyntaxErrorException: Table 'hive_metastore.partitions' doesn't exist
      • 您是否创建了数据库,请尝试在您的语句中使用 ${dbname}.${tableName}。还要记住,“分区”是 Hive 中的关键字
      • 我还没有执行任何查询,该查询是在创建 hive 元存储时由 spark 或 hive 执行的。我已经设置了MySQL url连接createDatabaseIfNotExist=true因为没有数据库,我是从0开始的。
      【解决方案3】:

      我已经尝试使用不同版本的 spark 将元数据管理从 derby 迁移到 mysql/postgres,并且我在 spark-2.2.1 及更高版本上取得了成功。之前的版本不允许我迁移到其他数据库。他们对 spark 有纯粹的版本依赖性。我的建议尝试将 spark 版本升级到 2.2.1,你应该很高兴!!

      【讨论】:

        【解决方案4】:

        对于所有尝试使用带有 mysql 驱动程序 8.x 并降级到 5.x 的 hive Metastore 的用户:

        另一种解决方案是使用 mysql 选项配置 URL:

        connectionURL: "jdbc:mysql://localhost:3306/hive_db?databaseTerm=SCHEMA&nullDatabaseMeansCurrent=true"
        

        From release notes of mysql connector 8

        一个新的连接属性 databaseTerm 设置在应用程序中使用这两个术语中的哪一个来引用数据库。该属性采用 CATALOG 或 SCHEMA 这两个值之一,并使用它来确定可以使用哪些 Connection 方法来设置/获取当前数据库,哪些参数可以在各种 DatabaseMetaData 方法中用于过滤结果,以及 ResultSet 中的哪些字段DatabaseMetaData 方法返回的包含数据库标识信息。有关详细信息,请参阅配置属性中的 databaseTerm 条目。 此外,连接属性 nullCatalogMeansCurrent 已重命名为 nullDatabaseMeansCurrent。旧名称仍然是连接属性的别名。 感谢 Harald Aamot 对补丁的贡献。 (错误 #11891000、错误 #27356869、错误 #89133)

        感兴趣的人:我们看到的问题是 hive 试图解析 mysql 中的所有模式,但它没有这样做的权限。将其限制为当前数据库(URL 中指定的 hive_db)为我们解决了问题

        【讨论】:

          猜你喜欢
          • 2022-01-25
          • 2016-08-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-04-18
          • 1970-01-01
          • 1970-01-01
          • 2018-01-27
          相关资源
          最近更新 更多