Metastore do Apache Hive externo (herdado)

Este artigo descreve como configurar clusters Azure Databricks para se conectar a metastores Apache Hive externos existentes. Ele fornece informações sobre a configuração de metastore recomendada e os requisitos de configuração de cluster, seguidas por instruções para configurar clusters para se conectar a um metastore externo. Para versões da biblioteca do Hive incluídas no Databricks Runtime, confira as notas de versão relevantes do Databricks Runtime.

Importante

  • Embora o SQL Server funcione como o banco de dados de metastore subjacente para o Hive 2.0 e superior, os exemplos neste artigo usam o Banco de Dados SQL do Azure.
  • Para obter informações sobre a compatibilidade do metastore do Hive com o HDInsight, consulte Usar armazenamentos de metadados externos no Azure HDInsight.
  • Se você usar o banco de dados do Azure para MySQL como um Metastore externo, deverá ser alterado o valor da propriedade lower_case_table_names de 1 (o padrão) para 2 na configuração do banco de dados do lado do servidor. Para obter detalhes, consulte Identificador de maiúsculas e minúsculas.

Observação

O uso de metastores externos é um modelo de governança de dados herdado. O Databricks recomenda que você atualize para o Catálogo do Unity. O Unity Catalog simplifica a segurança e a governança de seus dados fornecendo um local central para administrar e auditar o acesso a dados em vários workspaces em sua conta. Veja O que é o Catálogo do Unity?.

Configuração do Metastore do Hive

O cliente metastore em execução dentro de um cluster conecta-se ao banco de dados metastore subjacente diretamente usando o JDBC.

Para testar a conectividade de rede de um cluster para o metastore, você pode executar o seguinte comando dentro de um notebook:

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

onde

  • <DNS name> é o nome do servidor Banco de Dados SQL do Azure.
  • <port> é a porta do banco de dados.

Configurações de cluster

Você deve definir dois conjuntos de opções de configuração para conectar um cluster a um metastore externo:

  • As opções do Spark configuram o Spark com a versão do metastore do Hive e os JARs para o cliente de metastore.
  • As opções do Hive configuram o cliente metastore para se conectar ao metastore externo.

Opções de configuração do Spark

Defina spark.sql.hive.metastore.version para a versão do metastore do Hive e spark.sql.hive.metastore.jars da seguinte forma:

  • Hive 0.13: não definir spark.sql.hive.metastore.jars.

    Observação

    O Hive 1.2.0 e 1.2.1 não são o metastore integrado no Databricks Runtime 7.0 e superior. Se você quiser usar o Hive 1.2.0 ou 1.2.1 com Databricks Runtime 7.0 e superior, siga o procedimento descrito em Baixar os jars de metastore e apontar para eles.

  • Hive 2.3.7 (Databricks Runtime 7.0 – 9.x) ou Hive 2.3.9 (Databricks Runtime 10.0 e superior): spark.sql.hive.metastore.jars definido como builtin.

  • Para todas as outras versões do Hive, o Azure Databricks recomenda fazer download dos JARs de metastore e definir a configuração spark.sql.hive.metastore.jars para apontar para os JARs baixados usando o procedimento descrito em Fazer download e apontar para os jars de metastore.

Baixe os jars de metastore e aponte para eles

  1. Crie um cluster com spark.sql.hive.metastore.jars definido como maven e spark.sql.hive.metastore.version para corresponder à versão do metastore.

  2. Quando o cluster estiver em execução, pesquise o log do driver e encontre uma linha como a seguinte:

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

    O diretório <path> é o local dos JARs baixados no nó de driver do cluster.

    Como alternativa, você pode executar o seguinte código em um notebook Scala para imprimir o local dos JARs:

    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. Execute %sh cp -r <path> /dbfs/hive_metastore_jar (substituindo <path> pelas informações do cluster) para copiar esse diretório para um diretório na raiz do DBFS hive_metastore_jar chamado por meio do cliente DBFS no nó do driver.

  4. Crie um script init que copia /dbfs/hive_metastore_jar para o sistema de arquivos local do nó, fazendo com que o script de init compartilhamento alguns segundos antes de acessar o cliente do DBFS. Isso garante que o cliente esteja pronto.

  5. Defina spark.sql.hive.metastore.jars para usar esse diretório. Se o script de init copia /dbfs/hive_metastore_jar para /databricks/hive_metastore_jars/, defina spark.sql.hive.metastore.jars como /databricks/hive_metastore_jars/*. O local deve incluir /* à parte final.

  6. Reinicie o cluster.

Opções de configuração do Hive

Esta seção descreve as opções específicas para o Hive.

Para se conectar a um metastore externo usando o modo local, de definir as seguintes opções de configuração do 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

onde

  • <mssql-connection-string> é a cadeia de conexão JDBC (que você pode obter no portal do Azure). Você não precisa incluir nome de usuário e senha na cadeia de conexão, pois eles serão definidos por javax.jdo.option.ConnectionUserName e javax.jdo.option.ConnectionDriverName.
  • <mssql-username>e <mssql-password> especifique o nome de usuário e a senha Banco de Dados SQL do Azure conta que tem acesso de leitura/gravação ao banco de dados.

Observação

Para ambientes de produção, é recomendável definir hive.metastore.schema.verification como true. Isso impede que o cliente de metastore do Hive modifique implicitamente o esquema de banco de dados metastore quando a versão do cliente metastore não corresponder à versão do banco de dados metastore. Ao habitar essa configuração para versões de cliente de metastore inferiores ao Hive 1.2.0, certifique-se de que o cliente metastore tenha a permissão de gravação para o banco de dados metastore (para evitar o problema descrito em HIVE-9749).

  • Para o metastore do Hive 1.2.0 e superior, definirhive.metastore.schema.verification.record.version como true para habilitar o hive.metastore.schema.verification.
  • Para o metastore do Hive 2.1.1 e superior, definir hive.metastore.schema.verification.record.version comotrue como está definido em false por padrão.

Configurar um metastore externo usando a interface do usuário

Para configurar um metastore externo usando a interface Azure Databricks interface do usuário:

  1. Na barra lateral, clique no botão Clusters.

  2. Clique em Criar Cluster.

  3. Insira as seguintes opções de Configuração do 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. Continue a configuração do cluster, seguindo as instruções em Referência de configuração de computação.

  5. Clique em Criar cluster para criar o cluster.

Configurar um metastore externo usando um script de inicialização

Os scripts de init permitem que você se conecte a um metastore do Hive existente sem definir manualmente as configurações necessárias.

  1. Crie o diretório base no qual você deseja armazenar o script de inicialização, caso ele ainda não exista. O exemplo a seguir usa dbfs:/databricks/scripts.
  2. Execute o snippet a seguir em um notebook. O snippet cria o script de init /databricks/scripts/external-metastore.sh no Sistema de Arquivos do Databricks (DBFS). Como alternativa, você pode usar a operação put da API REST do DBFS para criar o script de inicialização. Esse script de inicialização grava as opções de configuração necessárias em um arquivo de configuração chamado 00-custom-spark.conf em um formato JSON em /databricks/driver/conf/ dentro de cada nó do cluster, sempre que um cluster com o nome especificado como <cluster-name> é iniciado. O Azure Databricks fornece as configurações padrão do Spark no arquivo /databricks/driver/conf/spark-branch.conf. Os arquivos de configuração no diretório /databricks/driver/conf se aplicam em ordem alfabética inversa. Se você quiser alterar o nome do arquivo 00-custom-spark.conf, certifique-se de que ele continue a ser aplicado antes do arquivo 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 o cluster com o script de inicialização.
  2. Reinicie o cluster.

Solução de problemas

Os clusters não iniciam (devido a configurações incorretas de script de inicialização)

Se um script de inicialização para configurar o metastore externo causar falha na criação do cluster, configure o script de inicialização para registrar em log e depure o script de inicialização usando os logs.

Erro na instrução SQL: InvocationTargetException

  • Padrão de mensagem de erro no rastreamento completo da pilha de exceção:

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

    As informações de conexão JDBC do metastore externo estão configuradas incompatibilidade. Verifique o nome do host, a porta, o nome de usuário, a senha e o nome de classe do driver JDBC configurados. Além disso, certifique-se de que o nome de usuário tenha o privilégio certo para acessar o banco de dados metastore.

  • Padrão de mensagem de erro no rastreamento completo da pilha de exceção:

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

    Banco de dados metastore externo não inicializado corretamente. Verifique se você criou o banco de dados metastore e colocou o nome correto do banco de dados na cadeia de conexão JDBC. Em seguida, inicie um novo cluster com as duas opções de configuração do Spark a seguir:

    datanucleus.schema.autoCreateTables true
    datanucleus.fixedDatastore false
    

    Dessa forma, a biblioteca de clientes do Hive tentará criar e inicializar tabelas no banco de dados metastore automaticamente quando tentar acessá-las, mas as encontra ausentes.

Erro na instrução SQL: AnalysisException: não é possível iniciar org.apache.hadoop.hive.metastore.HiveMetastoreClient

Mensagem de erro no stacktrace de exceção completo:

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

O cluster está configurado para usar um driver JDBC incorreto.

Definir datanucleus.autoCreateSchema como true não funciona conforme o esperado

Por padrão, o Databricks também define datanucleus.fixedDatastore como true, o que impede alterações estruturais acidentais nos bancos de dados de metastore. Portanto, a biblioteca de clientes do Hive não poderá criar tabelas de metastore mesmo se você definir datanucleus.autoCreateSchema como true. Essa estratégia é, em geral, mais segura para ambientes de produção, pois impede que o banco de dados metastore seja atualizado acidentalmente.

Se você quiser usar para datanucleus.autoCreateSchema ajudar a inicializar o banco de dados metastore, certifique-se de definir datanucleus.fixedDatastore como false. Além disso, talvez você queira inverter os dois sinalizadores depois de inicializar o banco de dados metastore para fornecer melhor proteção ao seu ambiente de produção.