Así está mejorando la tecnología el Marketing
18 marzo, 2021
Los datos y la Inteligencia Artificial impulsarán el futuro de la banca
25 marzo, 2021

Si no has estado viviendo en una cueva en los últimos años, seguro que ya conoces lo que es Databricks. Pero por si acaso, te lo recordamos:

Databricks es una herramienta líder de ingeniería de datos basada en la nube que se utiliza para procesar y transformar cantidades masivas de datos y explorar los datos a través de modelos de aprendizaje automático. Disponible para todas las organizaciones, permite alcanzar fácilmente todo el potencial de combinar sus datos, procesos ETL y aprendizaje automático, con toda la potencia que ofrece Apache Spark.

Sin embargo, una pregunta muy importante surge al empezar a trabajar con Databricks, sobre todo cuando trabajamos en un escenario en el que tenemos varios entornos funcionales (desarrollo, QA, producción, etc):

 

¿Cómo organizo todo mi código y como lo despliego de manera automática entre diferentes entornos?

Aquí te lo vamos a contar. Y la verdad es que no es ningún misterio. Simplemente copiaremos una técnica que ha estado funcionando de manera exitosa en el desarrollo de aplicaciones tradicional: La Integración Continua y el Despliegue Continuo

Este es el proceso o pipeline completo que, en general, nos permite adoptar esta técnica:

  • El primer paso, consiste en versionar el código de nuestros ETL’s o modelos de ML, en repositorios de Git. Una vez tengamos el código versionado, seremos capaces de registrar y guardar cualquier cambio que hayamos hecho, organizando el trabajo por ramas dentro del repositorio
  • A continuación, y por cada cambio realizado, se ejecutará un proceso automático que compilará todo el código que tengamos hasta el momento y ejecutará pruebas unitarias sobre el mismo, siempre y cuando las hayamos incluido en nuestro código.
  • Si todo ha ido bien, el código se empaqueta y despliega en un entorno previo al productivo en el que podemos ejecutar pruebas de Q&A y UAT, con el fin de validar la funcionalidad introducida al 100%
  • El último paso consiste, en realizar una fusión del código, una vez validada toda la funcionalidad, sobre la rama principal del repositorio, lo que despliega el código directamente en el entorno productivo

Adoptando esta técnica, podemos beneficiarnos de lo siguiente:

  • Los equipos de Q&A dedican menos tiempo a realizar pruebas
  • Las regresiones que puedan introducirse de manera accidental en el código, son identificadas en una etapa temprana por las pruebas automatizadas
  • La complejidad a la hora de desplegar el código se reduce drásticamente
  • Se puede entregar nueva funcionalidad de manera más ágil, mejorando así la interacción con los clientes, y facilitando una iteración más rápida favoreciendo el time-to-market

¿Y cómo lo puedo hacer?

Si trabajas habitualmente con Databricks (ya sea en Azure o AWS), vamos a contarte cómo, usando Azure Devops, conseguirás implementar de manera exitosa tu ciclo de CI/CD

Para este ejemplo, hemos creado un sencillo proceso ETL que leerá los datos de origen de un blob storage, los procesará y escribirá unas tablas dentro del mismo storage en formato Delta. Es un proceso muy sencillo, pero nos servirá para describir como sería el flujo de trabajo en el mundo real

 

A modo de resumen, esta es la secuencia de pasos que implementaremos:

  • En primer lugar, crearemos una aplicación de Spark, que lea los datos de origen de un blob storage. Es una aplicación sencilla que lee un csv que contiene un dataset con información de películas procedentes de IDMB. Leeremos el fichero, convertiremos al esquema adecuado, y guardaremos una primera versión en formato Delta, con el esquema correcto. Posteriormente crearemos tres tablas de agregado sencillas, que también guardaremos en el mismo proceso
  • Crearemos un pipeline de Azure Devops, que compilará nuestro código y lo desplegará en Databricks, almacenando la librería compilada en el sistema de ficheros del workspace de Databricks
  • Para lanzar el proceso de Databricks que ejecutará nuestro código lo podríamos hacer de manera manual, pero en este caso, usaremos Azure Data Factory, ya que en entornos reales se suele combinar el uso de ADF como orquestador en combinación con Databricks para los procesos de transformación de datos

Como decíamos, el primer paso es crear un repositorio en el que subiremos nuestro código:

Tenemos una rama principal, “master”, donde hemos hecho la subida inicial de código.

A medida que vamos trabajando con un proyecto y éste va creciendo, es recomendable utilizar un workflow como el de GitFlow (https://www.atlassian.com/es/git/tutorials/comparing-workflows/gitflow-workflow).

Dependiendo del tamaño del proyecto, es posible utilizar una versión “resumida” de este flujo de trabajo, como haremos más adelante.

 

 

 

 

Llega el momento del CI/CD. Todo en un único pipeline

Ahora es cuando vamos a definir nuestro pipeline de CI/CD. Para ello, lo vamos a realizar enteramente en YAML, ya que esto nos va a permitir versionar completamente nuestro proceso:

trigger:
- master

pool:
  vmImage: ubuntu-latest

variables:
  - group: Databricks-jarnau
  - name: "artifactName"
    value: "spark-scala-job"

stages:
- stage: Build
  jobs:
  - job: Build
    pool: 
      vmImage: 'ubuntu-latest'
    steps:
    - task: Maven@3
      inputs:
        mavenPomFile: 'pom.xml'
        mavenOptions: '-Xmx3072m'
        javaHomeOption: 'JDKVersion'
        jdkVersionOption: '1.8'
        jdkArchitectureOption: 'x64'
        publishJUnitResults: true
        testResultsFiles: '**/surefire-reports/TEST-*.xml'
        goals: 'clean package'
    - task: CopyFiles@2
      inputs:
        sourceFolder: '$(Agent.BuildDirectory)'
        contents: '**/*.jar'
        targetFolder: '$(Build.ArtifactStagingDirectory)'
        cleanTargetFolder: true
        overWrite: true
        flattenFolders: true
        preserveTimestamp: false
    - task: PublishBuildArtifacts@1
      inputs:
        PathtoPublish: '$(Build.ArtifactStagingDirectory)'
        ArtifactName: '$(artifactName)'
        publishLocation: 'Container'

- stage: Deploy_Artifacts
  condition: succeeded()
  jobs:
    - job:
      pool:
        vmImage: 'windows-2019'
      steps:
      - task: DownloadBuildArtifacts@0
        inputs:
          buildType: 'current'
          downloadType: 'single'
          artifactName: '$(artifactName)'
          downloadPath: '$(System.ArtifactsDirectory)'
      - task: databricksDeployDBFSFilesTask@0
        inputs:
          authMethod: 'bearer'
          region: 'westeurope'
          LocalRootFolder: '$(System.ArtifactsDirectory)/$(artifactName)'
          FilePattern: '*.jar'
          TargetLocation: '/job-jars-ci'
          bearerToken: $(databricks-token)
        displayName: Databricks - Deploy Spark Jobs

A continuación, vamos a “diseccionar” paso por paso el YAML, para detallar los pasos que se ejecutarán:

  • Las propiedades trigger, pool, y variables son generales a todos los pasos del pipeline, y realizan cada uno la siguiente función:
    • Trigger: indica las ramas a partir de las cuales se ejecutará el pipeline
    • Pool: El sistema operativo con el que va a ejecutar el pipeline
    • Variables: Variables con las que se puede parametrizar el pipeline. Pueden ser variables explicitas (como, por ejemplo, “artifactName”), o grupos de variables, que puedan proceder de un Azure Key Vault, para variables con datos sensibles.
  • Stages: Cada uno de los subprocesos del pipeline. En este caso tenemos dos, “Build”, para compilar nuestra aplicación como una librería y “Deploy Artifacts”, para desplegarlo en Databricks:
    • Build: Compilaremos el proyecto Maven que hemos construido, y posteriormente copiaremos los archivos que hemos generado (en este caso el .jar resultante de la compilación) y lo publicaremos en el pipeline para que la tarea de Deploy_Artifacts, lo pueda leer correctamente
    • Deploy Artifacts: Ahora utilizaremos el artefacto que hemos publicado en el paso anterior, para desplegarlo en Azure Databricks. En este caso, utilizaremos un pool diferente, ya que necesitaremos un sistema operativo Windows para poder publicar el artefacto en Databricks
      • En este paso necesitaremos un token de acceso a databricks para poder desplegar nuestro artefacto. Dicho token se puede obtener de manera sencilla desde el propio portal de Databricks, o bien lo podremos crear de manera automática usando una tarea de Azure Devops
      • Una vez obtengamos el token, lo recomendable es almacenarlo en un Azure Key Vault, que leeremos en el pipeline desde un grupo de variables:

Una vez tenemos el código ya versionado, podremos crear el pipeline desde el portal de Azure Devops, seleccionando “New Pipeline”, y el repositorio y fichero que definen nuestro pipeline, en este caso el fichero YAML que acabamos de comentar.

Una vez creado, si lo ejecutamos y todo está correctamente configurado, veremos lo siguiente:

Es decir, nuestro pipeline se ha ejecutado correctamente y si ahora vamos al portal de Databricks y examinamos el sistema de ficheros (DBFS), veremos que ha instalado correctamente nuestra librería en la ruta que hemos elegido:

Ahora que ya tenemos nuestro código desplegado en Azure Databricks, podemos usar Azure Data Factory, para crear un nuevo cluster de Spark, y ejecutar nuestra librería.

Hemos creado un pipeline de Azure Datafactory muy sencillo, que nos permitirá invocar el código que hemos desplegado en Azure Databricks:

Como vemos en la imagen, vamos a seleccionar la librería que hemos instalado en el dbfs de Azure Databricks, y pasarle un par de parámetros, que indicaran la ruta de donde tiene que leer el fichero de origen y la ruta de destino donde se guardaran los datos procesados.

Y aquí, el resultado final

Si ejecutamos el pipeline de Azure Data Factory:

Todo ha ido correctamente, así que, si leemos las rutas desde, por ejemplo, un simple notebook de Databricks, podremos ver como se han almacenado los datos que comentábamos al principio del artículo:

Aquí podemos ver el listado de películas al completo

En la siguiente imagen, se muestra los 10 actores que mas aparecen en las películas:

A continuación, las 10 películas con más presupuesto:

Por último, las 10 películas mejor valoradas:

Gracias a esta técnica, como comentábamos al principio del artículo, si queremos hacer cualquier modificación podremos desplegar rápidamente los cambios de manera automatizada

¿Y si utilizo notebooks como puedo hacer esto?

Pues estás de enhorabuena, el equipo de Databricks acaba de estrenar una integración mejorada con repositorios .Git, que tiene una pinta fantástica. Échale un vistazo aquí

 

Si queréis poneros en contacto con nosotros, podéis hacerlo en info@kabel.es

También podéis seguirnos en TwitterLinkedInFacebook

Licencia de Creative Commons

Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial 4.0 Internación 

Compártelo: Share on FacebookTweet about this on TwitterShare on LinkedInPin on Pinterest

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

NEWSLETTER