Azure Databricks: acessando spark session remotamente

O script spark-submit distribuído com o spark é a opção padrão para execução de aplicações spark em clusters, porém, em alguns cenários temos a necessidade de acessar diretamente uma spark session já existente em um cluster remoto. Nesse post vamos entender como fazer isso utilizando o databricks-connect.

A biblioteca databricks-connect é o componente que nos permite acessar uma spark session em um cluster remoto e utilizá-la no desenvolvimento de aplicações spark. A construção da representação lógica do job é realizada localmente e então submetida para execução em um cluster no Azure Databricks.

Essa abordagem possibilita utilizarmos IDEs em nossa estação de trabalho local para desenvolver, executar e debugar aplicações que processam dados em larga escala em um cluster remoto, além de facilitar a integração com ferramentas que visam facilitar o desenvolvimento de pipelines de ciência de dados, como o kedro.

Instalação

Pré-Requisitos

As versões do databricks runtime que suportam o databricks-connect oficialmente são listadas abaixo, recomendo acompanhar a documentação para futuras atualizações.

Databricks Runtime VersionPython Version
8.1 ML, 8.13.8
7.3 LTS ML, 7.3 LTS3.7
6.4 ML, 6.43.7
5.5 LTS ML3.6
5.5 LTS3.5
Versões do Databricks Runtime que suportam a biblioteca databricks-connect em 23/06/2021 às 00h35min

Também é necessário que o pacote pyspark seja desinstalado do ambiente de desenvolvimento em detrimento do databricks-connect, que intermediará toda a interação com o spark sem necessidade de qualquer alteração no código. Se o pyspark não for removido do ambiente isso acarretará em problemas na execução dos scripts.

Instalação

O processo de instalação do databricks-connect então seguirá as seguintes etapas:

# 1. Remoção do pyspark
pip uninstall pyspark
# 2. Instalação do databricks-connect
#    X e Y representam a versão do Databricks Runtime
pip install -U "databricks-connect==X.Y.*"

Configuração de acesso ao cluster

Para configurar o acesso ao cluster precisamos dos seguintes dados: workspace url, personal access token, cluster id e organization id.

A workspace url é a parte da url destacada na Figura 1, que deve ser informada com o https, no exemplo o valor de workspace url seria https://adb-7325159314549292.12.azuredatabricks.net/

Figura 1 – Workspace URL

O personal access token deve ser gerado no painel de configurações do usuário, esse processo pode ser observado na Figura 2, Figura 3, Figura 4 e Figura 5.

Figura 2 – Acessando as configurações de usuários na página inicial do workspace
Figura 3 – Selecione o menu Access Tokens e clique no botão Generate New Token
Figura 4 – Informe um nome para o token e a validade em dias
Figura 5 – Copie o token, pois após clicar em done não é possível visualizá-lo novamente

O cluster id pode ser obtido acessando o menu compute, selecionando o cluster de interesse e copiando o id presente na url; esse processo pode ser observado na Figura 6, Figura 7 e Figura 8.

Figura 6 – Acessando o menu compute
Figura 7 – Selecionando o cluster de interesse
Figura 8 – Identificando o cluster id

O dado organization id também pode ser identificado na url do workspace, como pode ser visto na Figura 9

Figura 9 – Identificando a organization id

Com os dados necessários para a configuração em mão, iremos seguir as etapas abaixo.

# 1. Comando para iniciar a configuração
databricks-connect configure
# 2. Informe o workspace url
Databricks Host [no current value, must start with https://]: https://adb-7325159314549292.12.azuredatabricks.net/
# 3. Informe o access token
Databricks Token [no current value]: dapif89dc28d4b025e0c9d33cc9d376aa97d-3
# 4. Informe o cluster id
Cluster ID (e.g., 0921-001415-jelly628) [no current value]: 0723-035745-loan940
# 5. Informe o organization id
Org ID (Azure-only, see ?o=orgId in URL) [0]: 7325159314549292
# 6. Dê enter, neste caso é a porta padrão
Port [15001]:

Após a configuração, siga os passos abaixo para checar se tudo ocorreu conforme o esperado, a última linha deve conter a frase * All tests passed.

databricks-connect test

Conclusão

Em alguns cenários de uso temos a necessidade de acessar uma spark session remotamente, utilizando a biblioteca databricks-connect junto ao Azure Databricks conseguimos realizar essa tarefa de forma simples.

Me deparei com essa necessidade em um cliente que precisava desenvolver pipelines de data science com o kedro e ter a possibilidade de utilizar os recursos de um workspace Azure Databricks disponível para o treinamento de modelos; e você, já se deparou com a necessidade? Me conte nos comentários!

Até a próxima!

O que a PEP8 diz sobre os imports?

A PEP8 é um guia de estilo que contém várias recomendações para organizarmos o código escrito na linguagem python, facilitando a legibilidade e criando um padrão comum entre as soluções. Hoje vamos explorar as recomendações que dizem respeito a seção de imports que está presente em quase todos os nossos scripts.

imports sempre devem estar no começo do script

As instruções de import devem estar localizadas no ínicio do script, após comentários e/ou docstrings dos módulos e antes das variáveis globais e constantes, além de seguir a seguinte ordem: 1) imports da biblioteca padrão, 2) imports de bibliotecas de terceiros e 3) imports da aplicação que estamos desenvolvendo. Uma linha em branco deve separar cada um dos grupos mencionados.

O bloco a seguir não segue as recomendações da PEP8:

import pandas as pd
import numpy as np
import os
import math

O bloco a seguir segue as recomendações da PEP8:

# imports da biblioteca padrão
import math
import os

# imports de bibliotecas de terceiros
import numpy as np
import pandas as pd

# imports locais devem ser colocados neste bloco
import meumodulo

imports normalmente devem ser separados em linhas

Não é recomendado a utilização de uma instrução import para adicionar diferentes módulos ao script, eles devem ser preferencialmente importados em linhas separadas, como o exemplo a seguir.

# Forma incorreta
import os, sys

# Forma correta
import os
import sys

Porém, quando estamos lidando com submódulos de um módulos a seguinte forma é recomendada:

# Está forma está correta
from datetime import datetime, timedelta
from subprocess import Popen, PIPE

imports com caminho absolutos são recomendados

É recomendado o uso de caminhos absolutos quando estamos importando algum módulo da nossa própria solução, isso facilita a identificação da origem de determinado trecho de código.

import meumodulo.submodulo
from meumodulo import submodulo
from meumodulo.submodulo import classexemplo

imports relativos explícitos também são aceitos e imports relativos implícitos não são suportados, porém, sempre dê preferência para imports absolutos.

'''
Exemplo de import explícito.
Aqui estamos importando um módulo que está
dentro da mesma pasta que nosso script.
'''
from . import submodulo
from .submodulo import classexemplo

O que fazer em caso de conflito de classes de módulos e locais?

Em alguns casos podemos ter conflitos de nomes entre funções e/ou classes de algum módulo com nossas funções e/ou classes locais, quando isso acontecer as funções e/ou classes podem ser importadas da seguinte maneira:

# Exemplo utilizando o submódulo os.path
from os import path
# Chamada do submódulo: path.join('/home', 'leobiscassi')

'''
Caso exista algum conflito de nome com meu módulo
podemos realizar o import da seguinte maneira
'''
import os.path
# Chamada do submódulo: 
# os.path.join('/home', 'leobiscassi')

imports wildcard devem ser evitados

imports utilizando o wildcard * devem ser evitados, como no exemplo abaixo:

from os import *

Eu particularmente utilizo o wildcard quando possuo muitos submódulos e vou utilizar todos no meu script, porém, esse tipo de situação não costuma acontecer com frequência.

Conclusão

A PEP8 é um guia de boas práticas que nos ajuda a estruturar o código de maneira mais legível, isso inclui a seção de imports que na maioria das vezes está presente em nossos scripts python.

Nesta postagem conferimos algumas dicas presentes na PEP8 que nem sempre tomamos conhecimento, até pouco tempo atrás eu não sabia dessas recomendações, e vocês sabiam que existia uma recomendação específica de como organizar os imports no seu script? Deixa ai nos comentários! 🙂