Spark metastore 配置 背景和問題 環境信息 Spark SQL自身metastore使用MySQL替換Derby 使用Hive metastore

背景和問題

在使用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的配置已完成。

本博客爲作者原創,歡迎大家參與討論和批評指正。如需轉載請註明出處。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章