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