Spark metastore 配置

作者: AlienPaul | 来源:发表于2023-03-13 14:47 被阅读0次

背景和问题

在使用Spark SQL创建写入Hudi表的时候出现如下错误(错误很长,无关部分省略):

ERROR XJ040: Failed to start database 'metastore_db' with class loader org.apache.spark.sql.hive.client.IsolatedClientLoader$$anon$1@1ebb10fb, see the next exception for details.

...

ERROR XSDB6: Another instance of Derby may have already booted the database /xxx/metastore_db.

...

原因是Derby作为嵌入式数据库,不支持多用户同时访问。但作者并没有同时使用多个spark-sql/spark-shell来操作。百思不得其解。

经过调研得到两个可行的解决方案:

  • 升级Spark使用的JDK为JDK17。方法为下载解压JDK17到各个spark节点,然后配置各个节点的$SPARK_HOME/conf/spark-env.sh增加export JAVA_HOME=/path/to/jdk17。最后重新运行任务。
  • 放弃使用Derby,使用Hive metastore或者直接使用MySQL作为metastore的存储后端。

两种方式均可解决此问题。下面借此问题,引申出配置Spark metastore的方法。

环境信息

  • JDK 8
  • Spark 3.x
  • MySQL 8.x
  • Hive 3.x

Spark SQL自身metastore使用MySQL替换Derby

安装和部署MySQL的步骤因篇幅所限这里省略。可参考其他相关文档。

配置MySQL JDBC驱动

下载和环境中MySQL版本对应的MySQL JDBC驱动,复制到各个Spark节点的$SPARK_HOME/jars目录中。

MySQL配置

创建metastore专用的数据库:

create database metastore character set utf8mb4;

创建访问metastore元数据专用的用户和权限配置:

create user 'metastore'@'%' identified by 'password';

然后给metastore用户metastore数据库的访问权限:

grant all privileges on `metastore`.* to 'metastore'@'%' identified by 'password';

flush privileges;

在MySQL中导入metastore schema

在MySQL所在节点下载Hive 3.x版本,解压后找到scripts/metastore/upgrade/mysql/hive-schema-版本号.mysql.sql。然后使用metastore用户进入MySQL执行:

use metastore;
source /path/to/hive/scripts/metastore/upgrade/mysql/hive-schema-版本号.mysql.sql;

配置hive-site.xml

编写如下hive-site.xml文件,放置在所有Spark节点$SPARK_HOME/conf目录中。

<property>
  <name>javax.jdo.option.ConnectionURL</name>
  <value>jdbc:mysql://mysql_server_hostname:3306/metastore</value>
</property>

<property>
  <name>javax.jdo.option.ConnectionDriverName</name>
  <value>com.mysql.jdbc.Driver</value>
</property>

<property>
  <name>javax.jdo.option.ConnectionUserName</name>
  <value>metastore</value>
</property>

<property>
  <name>javax.jdo.option.ConnectionPassword</name>
  <value>password</value>
</property>

<property>
  <name>datanucleus.autoCreateSchema</name>
  <value>false</value>
</property>

<property>
  <name>datanucleus.fixedDatastore</name>
  <value>true</value>
</property>

注意:生产环境为了保证MySQL Schema稳定,避免意外的数据库结构变更,需要设置datanucleus.fixedDatastoretrue。如果配置datanucleus.autoCreateSchematruedatanucleus.fixedDatastorefalse,MySQL metastore库的表结构会自动创建。无需再导入metastore schema。

参考链接:https://docs.databricks.com/data/metastores/external-hive-metastore.html

到这里为止使用MySQL替换Derby作为metastore元数据存储配置完毕。

使用Hive metastore

除了上面的方式之外,生产环境更为通用和稳定的解决方案为统一使用Hive的metastore。下面列出Spark使用Hive metastore的配置步骤。

配置spark-defaults.conf

编辑$SPARK_HOME/conf/spark-defaults.conf文件,增加如下内容。然后将修改过后的文件分发到所有Spark节点的conf目录。

spark.sql.hive.metastore.jars /path/to/standalone-metastore/*
spark.sql.hive.metastore.version 3.0

配置项解释:

  • spark.sql.hive.metastore.jars: 指定Hive standalone-metastore jar文件所在的路径
  • spark.sql.hive.metastore.version: Hive的版本号

配置hive-site.xml

复制包含如下内容的hive-site.xml到所有Spark节点的$SPARK_HOME/conf目录。

<configuration>
    <property>
        <name>hive.exec.scratchdir</name>
        <value>/tmp/spark</value>
    </property>

    <property>
        <name>hive.metastore.client.connect.retry.delay</name>
        <value>5</value>
    </property>

    <property>
        <name>hive.metastore.client.socket.timeout</name>
        <value>1800</value>
    </property>

    <property>
        <name>hive.metastore.uris</name>
        <value>thrift://metastore_host:9083</value>
    </property>

    <property>
        <name>hive.server2.enable.doAs</name>
        <value>false</value>
    </property>

    <property>
        <name>hive.server2.thrift.http.port</name>
        <value>10002</value>
    </property>

    <property>
        <name>hive.server2.thrift.port</name>
        <value>10016</value>
    </property>

    <property>
        <name>hive.server2.transport.mode</name>
        <value>binary</value>
    </property>
    
    <property>
        <name>metastore.catalog.default</name>
        <value>hive</value>
    </property>
</configuration>

需要注意的是需要修改hive.metastore.uris为真实环境下metastore安装所在节点的URL。hive.server2.thrift.http.porthive.server2.thrift.port也修改为对应服务的端口号。这些配置项可以从Hive集群的hive-site.xml文件中复制出来直接使用。

到这里Spark使用Hive metastore的配置已完成。

本博客为作者原创,欢迎大家参与讨论和批评指正。如需转载请注明出处。

相关文章

网友评论

    本文标题:Spark metastore 配置

    本文链接:https://www.haomeiwen.com/subject/roycrdtx.html