Conectar Databricks a Azure Data Lake Storage (ADLS)

En esta guía veremos cómo podemos conectarnos a Azure Data Lake Storage (ADLS) desde Databricks a través de un mount. De esta forma, la conexión a los containers se realizará de manera directa y podremos importar archivos directamente a nuestros notebooks de Databricks.

A continuación, se muestran algunos de los contenedores presentes en mi cuenta de Almacenamiento Azure:

Creación de Scope

En primer lugar debemos de acceder al Almacén de Claves (Vault Keys), luego a “Configuracion”, “propiedadades”, y copiamos el valor de “URI de almacen” e “id. del recurso”





Accedemos al home-page de azure databricks y añadimos “#/secrets/createScope”a la URL del navegador. En caso de que aparezca la palabra “onboarding” debemos de eliminarla.

A continuación debemos darle nombre al scope y en “DNS Name” y “Resource ID” deberemos de pegar la información de “URI de almacén” e “id. del recurso” que copiamos en el paso anterior, donde “DNS Name” tendrá el valor de “URI de almacén” y “Resource ID” tendrá el valor “id. del recurso”.

Una vez creado el scope podemos listarlo ejecutando el siguiente comando:

dbutils.secrets.listScopes()


Añadir Claves al Scope

Ahora deberemos de añadir las claves a ese scope, para ello accedemos a “Azure active directory”, “registro de aplicaciones” y creamos una aplicación, en mi caso se llama "databricks1".

Luego debemos de crear 3 “secretos” en el “Almacén de claves” con los siguientes nombres: “Client_id”, “tenant” y “client_secret”.


A los dos primeros le asignamos los valores “cliente” e “inquilino” de la aplicación creada, para ello vamos a “Registro de aplicaciones”, seleccionamos la aplicación que acabamos de crear y copiamos el valor de “cliente” e “inquilino”










El tercer valor lo extraemos creando un secreto en “certificados y secretos” dentro de la aplicación:

Una vez tengamos los 3 secretos creados en el “Almacén de claves”, podemos ejecutar el siguiente comando en databricks para comprobar que nuestro scope tiene las 3 claves:

dbutils.secrets.list(scope = nombre_scope)


Ahora podemos crear un mount, es decir tratar como directorio interno de databricks un sistema de almacenamiento externo, en este caso Blob Storage de Azure.

Para ello, creamos 3 variables con nuestras keys:


**client_id** = dbutils.secrets.get(scope = 'scope3', key = 'clientid')

**tenant_id** = dbutils.secrets.get(scope = 'scope3', key = 'tenant')

**client_secret** = dbutils.secrets.get(scope = 'scope3', key = 'clientsecret')



Y ejecutamos el siguiente código en otra celda:

**configs** = {"fs.azure.account.auth.type": "OAuth",

"fs.azure.account.oauth.provider.type": "org.apache.hadoop.fs.azurebfs.oauth2.ClientCredsTokenProvider",

"fs.azure.account.oauth2.client.id": **client_id**,

"fs.azure.account.oauth2.client.secret": **client_secret**,

"fs.azure.account.oauth2.client.endpoint": f"<https://login.microsoftonline.com/{**tenant_id**}/oauth2/token>"}


Ahora ya podemos montar nuestro directorio con la información de nuestros contenedores de Azure Blob Storage. Para ello creamos una función que primeramente verifica si el mount ya existe para proceder a desmontarlo y volverlo a montar, en caso de que no exista se crea desde cero. Copiar todo este contenido en una celda y ejecutarlo:


**def mount_adls**(**storage_acccount_name**, **container_name**):

**client_id** = dbutils.secrets.get(scope = 'scope3', key = 'clientid')

**tenant_id** = dbutils.secrets.get(scope = 'scope3', key = 'tenant')

**client_secret** = dbutils.secrets.get(scope = 'scope3', key = 'clientsecret')

**configs** = {"fs.azure.account.auth.type": "OAuth",

"fs.azure.account.oauth.provider.type": "org.apache.hadoop.fs.azurebfs.oauth2.ClientCredsTokenProvider",

"fs.azure.account.oauth2.client.id": **client_id**,

"fs.azure.account.oauth2.client.secret": **client_secret**,

"fs.azure.account.oauth2.client.endpoint": f"<https://login.microsoftonline.com/{**tenant_id**}/oauth2/token>"}

#unmounting first if exist

if any(mount.mountPoint ==

f"/mnt/{**storage_acccount_name**}/{**container_name**}" for mount in dbutils.fs.mounts()):

print('unmounting')

dbutils.fs.unmount(

f"/mnt/{**storage_acccount_name**}/{**container_name**}")

#mounting

print('mounting')

dbutils.fs.mount(

source = f"abfss://{**container_name**}@{**storage_acccount_name**}.dfs.core.windows.net/",

mount_point = f"/mnt/{**storage_acccount_name**}/{**container_name**}",

extra_configs = configs)

display(dbutils.fs.mounts())



Por último llamamos a la función y le introducimos el nombre de nuestra cuenta de almacenamiento y el nombre del contenedor. Podemos hacer esto con todos nuestros contenedores (Solo hace falta hacerlo una vez, y luego los contenedores permanecerán montados para siempre)

display(mount_adls('cursodatabricks123','raw'))



El cual podemos guardar en una variable tanto para lectura como para escritura de archivos en otros contenedores pero en el propio mount:

**raw_folder_path** = '/mnt/cursodatabricks123/raw'

**processed_folder_path** = '/mnt/cursodatabricks123/processed'

**presentation_folder_path** = '/mnt/cursodatabricks123/presentation'


Permisos

Cuenta de almacenamiento:

  1. “Yo” como colaborador de “Storage Blob”

  2. La aplicación que creemos con “Azure active directory” (en mi caso “databricksapp”) como colaborador de “Storage Blob”


Comentarios

Entradas populares de este blog

Cluster de Spark Standalone + HDFS + Docker + PostgreSQL