启动Hive独立元数据存储3.0.0时PartitionExpressionProxy加载失败
在Kubernetes中部署连接启用SSL的PostgreSQL的HMS(独立版v3.0.0)时,执行schematool -dbType postgres -initSchema可成功初始化PostgreSQL中的所需表,但运行./start-metastore时出现错误:Error loading PartitionExpressionProxy: org.apache.hadoop.hive.metastore.DefaultPartitionExpressionProxy class not found。
配置文件
HMS Dockerfile
FROM alpine:latest COPY hadoop-3.1.0.tar.gz /opt/hadoop-3.1.0.tar.gz COPY hive-standalone-metastore-3.0.0-bin.tar.gz /opt/hive-standalone-metastore-3.0.0-bin.tar.gz RUN wget -O /etc/apk/keys/amazoncorretto.rsa.pub https://apk.corretto.aws/amazoncorretto.rsa.pub && \ echo "https://apk.corretto.aws/" >> /etc/apk/repositories && \ apk update && apk upgrade && \ apk add --no-cache curl bash && \ apk add amazon-corretto-8 && \ apk add amazon-corretto-8-jre && \ tar -xvf /opt/hive-standalone-metastore-3.0.0-bin.tar.gz -C /opt/ && \ tar -xvf /opt/hadoop-3.1.0.tar.gz -C /opt/ && \ rm /opt/*.tar.gz COPY postgresql-42.5.4.jar /opt/apache-hive-metastore-3.0.0-bin/lib ENV HIVE_HOME=/opt/apache-hive-metastore-3.0.0-bin \ CLASSPATH=/opt/apache-hive-metastore-3.0.0-bin/lib/ \ HADOOP_HOME=/opt/hadoop-3.1.0 \ JAVA_HOME=/usr/lib/jvm/java-8-amazon-corretto
metastore-site.xml
<configuration> <!-- Configure MetaStore as a server. To start more servers, change port--> <property> <name>metastore.thrift.uris</name> <value>thrift://meta-store.default.svc.cluster.local:9083</value> <description> - Thrift URI for the remote metastore. Used by metastore client to connect to remote metastore. - IP address (or fully-qualified domain name) and port of the metastore host </description> </property> <!-- For running MetaStore in standalone mode. --> <property> <name>metastore.task.threads.always </name> <value>org.apache.hadoop.hive.metastore.events.EventCleanerTask</value> </property> <property> <name>metastore.expression.proxy</name> <value>org.apache.hadoop.hive.metastore.DefaultPartitionExpressionProxy </value> </property> <!--Postgres' connection details --> <property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:postgresql://postgres-svc.default.svc.cluster.local:5432/hive?ssl=true&sslMode=verify-ca&sslcert=/etc/tls.crt&sslkey=/etc/postgresql.pk8&sslrootcert=/etc/root.crt&sslpassword=postgres</value> </property> <property> <name>javax.jdo.option.ConnectionDriverName</name> <value>org.postgresql.Driver</value> </property> <property> <name>javax.jdo.option.ConnectionUserName</name> <value>postgres</value> </property> <property> <name>javax.jdo.option.ConnectionPassword</name> <value>postgres</value> </property> <!--URL of the default location for --> <!-- <property>--> <!-- <name>hive.metastore.warehouse.dir</name>--> <!-- <value>hdfs://localhost:9000/user/hive/warehouse</value>--> <!-- <description>--> <!-- URI of the default location for tables in the default catalog and database.--> <!-- </description>--> <!-- </property>--> <property> <name>datanucleus.schema.autoCreateAll</name> <value>false</value> <description> - Auto creates the necessary schema in the RDBMS at startup if one does not exist. - Set this to false after creating it once. - To enable auto create also set hive.metastore.schema.verification=false. - Auto creation is not recommended in production; run schematool instead. </description> </property> <property> <name>datanucleus.autoStartMechanism</name> <value>SchemaTable</value> </property> <property> <name>datanucleus.fixedDatastore</name> <value>true</value> </property> </configuration>
Kubernetes部署YAML
apiVersion: apps/v1 kind: Deployment metadata: name: hive-meta-store namespace: default spec: replicas: 1 selector: matchLabels: app: hive-metastore-deployment template: metadata: labels: app: hive-metastore-deployment spec: securityContext: runAsUser: 0 containers: - name: metastore image: hive-metastore-v0.0.1 imagePullPolicy: "IfNotPresent" ports: - containerPort: 9083 name: thrift-port # envFrom: # - configMapRef: # name: postgres-config volumeMounts: - name: metastore-xml mountPath: /opt/apache-hive-metastore-3.0.0-bin/conf/metastore-site.xml subPath: metastore-site.xml - name: postgres-ssl-crt mountPath: /etc/tls.crt subPath: tls.crt - name: postgres-ssl-key mountPath: /etc/tls.key subPath: tls.key - name: postgres-ssl-root mountPath: /etc/root.crt subPath: root.crt - name: postgres-ssl-pk8 mountPath: /etc/postgresql.pk8 subPath: postgresql.pk8 command: - /bin/sh - -c - "watch ps" volumes: - name: metastore-xml configMap: name: metastore-site.xml - name: postgres-ssl-crt secret: secretName: postgres-ssl-secret items: - key: tls.crt path: tls.crt mode: 0444 - name: postgres-ssl-key secret: secretName: postgres-ssl-secret items: - key: tls.key path: tls.key mode: 0444 - name: postgres-ssl-root secret: secretName: postgres-ssl-secret items: - key: root.crt path: root.crt mode: 0444 - name: postgres-ssl-pk8 secret: secretName: postgres-ssl-secret items: - key: postgresql.pk8 path: postgresql.pk8 mode: 0444
解决办法
修复CLASSPATH环境变量:Dockerfile中设置的
CLASSPATH=/opt/apache-hive-metastore-3.0.0-bin/lib/无法加载目录下的所有JAR包,Java类路径需要明确指定JAR文件。修改为:CLASSPATH=$HIVE_HOME/lib/*:$HADOOP_HOME/share/hadoop/common/*:$HADOOP_HOME/share/hadoop/hdfs/*:$HADOOP_HOME/share/hadoop/common/lib/*确保HMS启动时能加载所有依赖类。
修正metastore-site.xml中的类名格式:
metastore.expression.proxy配置项的value值存在换行,会导致类名解析错误。将其改为一行无多余空格的类名:<property> <name>metastore.expression.proxy</name> <value>org.apache.hadoop.hive.metastore.DefaultPartitionExpressionProxy</value> </property>修正Kubernetes部署的启动命令:当前YAML中的
watch ps并未启动HMS服务,替换为正确的启动命令:command: - /bin/sh - -c - "$HIVE_HOME/bin/start-metastore"校验HMS包完整性:确认
hive-standalone-metastore-3.0.0-bin.tar.gz解压后的$HIVE_HOME/lib目录中存在hive-metastore-3.0.0.jar,该JAR包包含DefaultPartitionExpressionProxy类。若缺失,重新下载完整的HMS安装包。
内容的提问来源于stack exchange,提问作者jake wong

