Metastore de Apache Hive externo (heredado)

En este artículo se describe cómo configurar clústeres de Azure Databricks para conectarse a metastores externos de Apache Hive existentes. En él encontrará información sobre la configuración recomendada de los metastores y los requisitos de configuración de clústeres, así como las instrucciones necesarias para configurar clústeres para conectarse a un metastore externo. Para ver las versiones de la biblioteca de Hive incluidas en Databricks Runtime, consulte las notas de la versión pertinentes de Databricks Runtime.

Importante

  • Aunque SQL Server funciona como la base de datos de metastore subyacente para Hive 2.0 y versiones posteriores, los ejemplos de este artículo usan Azure SQL Database.
  • Para obtener información sobre la compatibilidad de metastore de Hive con HDInsight, consulte Uso de almacenes de metadatos externos en Azure HDInsight.
  • Si utiliza Azure Database for MySQL como metastore externo, debe cambiar el valor de la propiedad lower_case_table_names de 1 (valor predeterminado) a 2 en la configuración de la base de datos del servidor. Para más información, consulte el artículo sobre la distinción entre mayúsculas y minúsculas en el identificador.

Nota:

El uso de metastores externos es un modelo de gobernanza de datos heredado. Databricks recomienda actualizar al catálogo de Unity. Unity Catalog simplifica la seguridad y la gobernanza de los datos al proporcionar un lugar central para administrar y auditar el acceso a los datos en varias áreas de trabajo de la cuenta. Consulte ¿Qué es Unity Catalog?

Configuración de metastore de Hive

El cliente de metastore que se ejecuta dentro de un clúster se conecta a su base de datos de metastore subyacente directamente mediante JDBC.

Para probar la conectividad de red desde un clúster al metastore, puede ejecutar el siguiente comando en un cuaderno:

%sh
nc -vz <DNS name> <port>

where

  • <DNS name> es el nombre del servidor de Azure SQL Database.
  • <port> es el puerto de la base de datos.

Configuraciones de clústeres

Debe establecer dos conjuntos de opciones de configuración para conectar un clúster a un metastore externo:

  • Las opciones de Spark configuran Spark con la versión de metastore de Hive y los archivos JAR para el cliente de metastore.
  • Las opciones de Hive configuran el cliente de metastore para conectarse al metastore externo.

Opciones de configuración de Spark

Establezca spark.sql.hive.metastore.version en la versión de metastore de Hive y spark.sql.hive.metastore.jars como se muestra a continuación:

  • Hive 0.13: no establezca spark.sql.hive.metastore.jars.

    Nota:

    Hive 1.2.0 y 1.2.1 no son el metastore integrado ni Databricks Runtime 7.0 ni en las versiones posteriores. Si desea usar Hive 1.2.0 o 1.2.1 con Databricks Runtime 7.0, y las versiones posteriores, siga el procedimiento que se describe en Descarga y selección de los archivos JAR de metastore.

  • Hive 2.3.7 (Databricks Runtime 7.0 - 9.x) o Hive 2.3.9 (Databricks Runtime 10.0 y versiones posteriores): establecer spark.sql.hive.metastore.jars en builtin.

  • Para las restantes versiones de Hive, Azure Databricks recomienda descargar los archivos JAR del metastore y establecer la configuración spark.sql.hive.metastore.jars para que apunte a los archivos JAR descargados mediante el procedimiento descrito en Descarga y selección de los archivos JAR de metastore.

Descarga y selección de los archivos JAR de metastore

  1. Cree un clúster con spark.sql.hive.metastore.jars establecido en maven y spark.sql.hive.metastore.version para que coincida con la versión del metastore.

  2. Cuando el clúster se esté ejecutando, busque en el registro del controlador una línea como la siguiente:

    17/11/18 22:41:19 INFO IsolatedClientLoader: Downloaded metastore jars to <path>
    

    El directorio <path> es la ubicación de los archivos JAR descargados en el nodo del controlador del clúster.

    Como alternativa, puede ejecutar el código siguiente en un cuaderno de Scala para imprimir la ubicación de los archivos JAR:

    import com.typesafe.config.ConfigFactory
    val path = ConfigFactory.load().getString("java.io.tmpdir")
    
    println(s"\nHive JARs are downloaded to the path: $path \n")
    
  3. Ejecute %sh cp -r <path> /dbfs/hive_metastore_jar (reemplace <path> por la información del clúster) para copiar este directorio en un directorio en la raíz de DBFS denominado hive_metastore_jar a través del cliente DBFS en el nodo del controlador.

  4. Cree un script de inicialización que copie /dbfs/hive_metastore_jar en el sistema de archivos local del nodo y asegúrese de que el script de inicialización se queda en suspensión unos segundos antes de acceder al cliente de DBFS. Esto garantiza que el cliente está listo.

  5. Establezca spark.sql.hive.metastore.jars para que use este directorio. Si el script de inicio copia /dbfs/hive_metastore_jar en /databricks/hive_metastore_jars/, establezca spark.sql.hive.metastore.jars en /databricks/hive_metastore_jars/*. La ubicación debe incluir el carácter /* final.

  6. Reinicie el clúster.

Opciones de configuración de Hive

En esta sección se describen las opciones específicas de Hive.

Para conectarse a un metastore externo mediante el modo local, establezca las siguientes opciones de configuración de Hive:

# JDBC connect string for a JDBC metastore
javax.jdo.option.ConnectionURL <mssql-connection-string>

# Username to use against metastore database
javax.jdo.option.ConnectionUserName <mssql-username>

# Password to use against metastore database
javax.jdo.option.ConnectionPassword <mssql-password>

# Driver class name for a JDBC metastore
javax.jdo.option.ConnectionDriverName com.microsoft.sqlserver.jdbc.SQLServerDriver

where

  • <mssql-connection-string> es la cadena de conexión de JDBC (que puede obtener en Azure Portal). No es necesario incluir el nombre de usuario y la contraseña en la cadena de conexión, ya que los establecerán javax.jdo.option.ConnectionUserName y javax.jdo.option.ConnectionDriverName.
  • <mssql-username> y <mssql-password> especifican el nombre de usuario y la contraseña de la cuenta de Azure SQL Database que tiene acceso de lectura y escritura a la base de datos.

Nota:

Para entornos de producción, se recomienda establecer hive.metastore.schema.verification en true. Esto evita que el cliente de metastore de Hive modifique implícitamente el esquema de la base de datos de metastore cuando la versión del cliente de metastore no coincida con la versión de la base de datos de metastore. Al habilitar esta configuración para las versiones de cliente de metastore inferiores a Hive 1.2.0, asegúrese de que el cliente de metastore tiene permiso de escritura en la base de datos de metastore (para evitar el problema descrito en HIVE-9749).

  • Tanto la versión 1.2.0 de metastore de Hive como en las superiores, establezca hive.metastore.schema.verification.record.version en true para habilitar hive.metastore.schema.verification.
  • En la versión 1.2.0 de metastore de Hive, y en las superiores, establezca hive.metastore.schema.verification.record.version en true, ya que está establecido en false forma predeterminada.

Configuración de un metastore externo mediante la interfaz de usuario

Para configurar un metastore externo mediante la interfaz de usuario de Azure Databricks:

  1. Haga clic en el botón Clusters (Clústeres) de la barra lateral.

  2. Haga clic en Create Cluster (Crear clúster).

  3. Escriba las siguientes opciones de configuración de Spark:

    # Hive-specific configuration options.
    # spark.hadoop prefix is added to make sure these Hive specific options propagate to the metastore client.
    # JDBC connect string for a JDBC metastore
    spark.hadoop.javax.jdo.option.ConnectionURL <mssql-connection-string>
    
    # Username to use against metastore database
    spark.hadoop.javax.jdo.option.ConnectionUserName <mssql-username>
    
    # Password to use against metastore database
    spark.hadoop.javax.jdo.option.ConnectionPassword <mssql-password>
    
    # Driver class name for a JDBC metastore
    spark.hadoop.javax.jdo.option.ConnectionDriverName com.microsoft.sqlserver.jdbc.SQLServerDriver
    
    # Spark specific configuration options
    spark.sql.hive.metastore.version <hive-version>
    # Skip this one if <hive-version> is 0.13.x.
    spark.sql.hive.metastore.jars <hive-jar-source>
    
  4. Continúe con la configuración del clúster siguiendo las instrucciones en referencia de configuración de proceso.

  5. Haga clic en Create Cluster (Crear clúster) para crear el clúster.

Configuración de un metastore externo mediante un script de inicialización

Los scripts de inicialización permiten conectarse a un metastore de Hive existente sin establecer manualmente las configuraciones necesarias.

  1. Cree el directorio base en el que quiere almacenar el script de inicialización, en caso de que no exista. En el ejemplo siguiente se utiliza dbfs:/databricks/scripts.
  2. Ejecute el siguiente fragmento de código en un cuaderno. El fragmento de código crea el script de inicialización /databricks/scripts/external-metastore.sh en Databricks File System (DBFS). Como alternativa, puede usar la operación put de la API REST de DBFS para crear el script de inicialización. Este script de inicialización escribe las opciones de configuración necesarias en un archivo de configuración denominado 00-custom-spark.conf en un formato similar a JSON en /databricks/driver/conf/ dentro de cada nodo del clúster, siempre que se inicie un clúster con el nombre especificado como <cluster-name>. Azure Databricks proporciona configuraciones predeterminadas de Spark en el archivo /databricks/driver/conf/spark-branch.conf. Los archivos de configuración del directorio /databricks/driver/conf se aplican en orden alfabético inverso. Si desea cambiar el nombre del archivo 00-custom-spark.conf, asegúrese de que se sigue aplicando antes que el archivo spark-branch.conf.

Scala

dbutils.fs.put(
    "/databricks/scripts/external-metastore.sh",
    """#!/bin/sh
      |# Loads environment variables to determine the correct JDBC driver to use.
      |source /etc/environment
      |# Quoting the label (i.e. EOF) with single quotes to disable variable interpolation.
      |cat << 'EOF' > /databricks/driver/conf/00-custom-spark.conf
      |[driver] {
      |    # Hive specific configuration options.
      |    # spark.hadoop prefix is added to make sure these Hive specific options will propagate to the metastore client.
      |    # JDBC connect string for a JDBC metastore
      |    "spark.hadoop.javax.jdo.option.ConnectionURL" = "<mssql-connection-string>"
      |
      |    # Username to use against metastore database
      |    "spark.hadoop.javax.jdo.option.ConnectionUserName" = "<mssql-username>"
      |
      |    # Password to use against metastore database
      |    "spark.hadoop.javax.jdo.option.ConnectionPassword" = "<mssql-password>"
      |
      |    # Driver class name for a JDBC metastore
      |    "spark.hadoop.javax.jdo.option.ConnectionDriverName" = "com.microsoft.sqlserver.jdbc.SQLServerDriver"
      |
      |    # Spark specific configuration options
      |    "spark.sql.hive.metastore.version" = "<hive-version>"
      |    # Skip this one if <hive-version> is 0.13.x.
      |    "spark.sql.hive.metastore.jars" = "<hive-jar-source>"
      |}
      |EOF
      |""".stripMargin,
    overwrite = true
)

Python

contents = """#!/bin/sh
# Loads environment variables to determine the correct JDBC driver to use.
source /etc/environment
# Quoting the label (i.e. EOF) with single quotes to disable variable interpolation.
cat << 'EOF' > /databricks/driver/conf/00-custom-spark.conf
[driver] {
    # Hive specific configuration options.
    # spark.hadoop prefix is added to make sure these Hive specific options will propagate to the metastore client.
    # JDBC connect string for a JDBC metastore
    "spark.hadoop.javax.jdo.option.ConnectionURL" = "<mssql-connection-string>"

    # Username to use against metastore database
    "spark.hadoop.javax.jdo.option.ConnectionUserName" = "<mssql-username>"

    # Password to use against metastore database
    "spark.hadoop.javax.jdo.option.ConnectionPassword" = "<mssql-password>"

    # Driver class name for a JDBC metastore
    "spark.hadoop.javax.jdo.option.ConnectionDriverName" = "com.microsoft.sqlserver.jdbc.SQLServerDriver"

    # Spark specific configuration options
    "spark.sql.hive.metastore.version" = "<hive-version>"
    # Skip this one if <hive-version> is 0.13.x.
    "spark.sql.hive.metastore.jars" = "<hive-jar-source>"
    }
EOF
"""

dbutils.fs.put(
    file = "/databricks/scripts/external-metastore.sh",
    contents = contents,
    overwrite = True
)
  1. Configure el clúster con el script de inicialización.
  2. Reinicie el clúster.

Solución de problemas

Los clústeres no se inician (debido a una configuración incorrecta del script de inicialización)

Si un script de inicialización para configurar el metastore externo genera un error de creación de clústeres, configúrelo para que se registre y depúrelo mediante los registros.

Error en instrucción SQL: InvocationTargetException

  • Patrón de mensaje de error en el seguimiento de toda la pila de excepciones:

    Caused by: javax.jdo.JDOFatalDataStoreException: Unable to open a test connection to the given database. JDBC url = [...]
    

    La información de la conexión JDBC del metastore externo está mal configurada. Compruebe el nombre de host, el puerto, el nombre de usuario, la contraseña y el nombre de clase del controlador JDBC configurados. Además, asegúrese de que el nombre de usuario tiene el privilegio adecuado para acceder a la base de datos de metastore.

  • Patrón de mensaje de error en el seguimiento de toda la pila de excepciones:

    Required table missing : "`DBS`" in Catalog "" Schema "". DataNucleus requires this table to perform its persistence operations. [...]
    

    La base de datos del metastore externo no se ha inicializado correctamente. Compruebe que creó la base de datos de metastore y puso el nombre correcto de la base de datos en la cadena de conexión de JDBC. Luego, inicie un nuevo clúster con las dos opciones de configuración de Spark siguientes:

    datanucleus.schema.autoCreateTables true
    datanucleus.fixedDatastore false
    

    De este modo, la biblioteca cliente de Hive intentará crear e inicializar tablas en la base de datos de metastore automáticamente cuando intente acceder a ellas pero se de cuenta de que no están.

Error en instrucción SQL: AnalysisException: no se puede crear una instancia de org.apache.hadoop.hive.metastore.HiveMetastoreClient

Mensaje de error en el seguimiento de toda la pila de excepciones:

The specified datastore driver (driver name) was not found in the CLASSPATH

El clúster está configurado para usar un controlador JDBC incorrecto.

Establecer datanucleus.autoCreateSchema en true no funciona como cabría esperar

De forma predeterminada, Databricks también establece datanucleus.fixedDatastore en true, lo que evita cualquier cambio estructural accidental en las bases de datos de metastore. Por consiguiente, la biblioteca cliente de Hive no puede crear tablas de metastore aunque datanucleus.autoCreateSchema se establezca en true. Esta estrategia es, en general, más segura para entornos de producción, ya que impide que la base de datos de metastore se actualice accidentalmente.

Si desea usar datanucleus.autoCreateSchema para ayudar a inicializar la base de datos de metastore, asegúrese de establecer datanucleus.fixedDatastore en false. Además, puede que quiera voltear ambas marcas después de inicializar la base de datos de metastore para proporcionar una mejor protección al entorno de producción.