Utiliza Spark en Kubernetes Engine para procesar datos en BigQuery

En este instructivo, se muestra cómo crear y ejecutar una canalización de datos que usa BigQuery con el fin de almacenar datos y Spark en Google Kubernetes Engine (GKE) para procesar esos datos. Esta canalización es útil para los equipos que estandarizaron su infraestructura de procesamiento en GKE y buscan formas de trasladar los flujos de trabajo existentes. Para la mayoría de los equipos, ejecutar Spark en Cloud Dataproc es la forma más fácil y escalable de ejecutar las aplicaciones Spark. En el instructivo, se evalúa un conjunto de datos público de BigQuery, datos de GitHub, para encontrar los proyectos que más se beneficiarían de una contribución. En este instructivo, se supone que estás familiarizado con GKE y Apache Spark. En el siguiente diagrama de arquitectura de alto nivel, se muestran las tecnologías que usarás.

diagrama de arquitectura

Muchos proyectos en GitHub se escriben en Go, pero pocos indicadores señalan a los colaboradores que un proyecto necesita ayuda o el lugar de la base de código requiere más atención.

En este instructivo, utilizarás los siguientes indicadores para señalar si un proyecto necesita contribuciones:

  • Número de problemas vigentes
  • Número de colaboradores
  • Cantidad de veces que otros proyectos importan los paquetes de un proyecto
  • Frecuencia de comentarios FIXME o TODO

El siguiente diagrama muestra la canalización de la aplicación Spark:

Canalización de la aplicación Spark

Objetivos

  • Crear un clúster de Kubernetes Engine para ejecutar la aplicación Spark
  • Implementar una aplicación Spark en Kubernetes Engine
  • Consultar y escribir las tablas de BigQuery en la aplicación Spark
  • Analizar los resultados mediante el uso de BigQuery

Costos

En este instructivo, se usan los siguientes componentes facturables de Google Cloud:

Usa la calculadora de precios para generar una estimación de los costos según el uso previsto. Los usuarios nuevos de Google Cloud pueden ser aptos para una prueba gratuita.

Antes de comenzar

  1. Accede a tu cuenta de Google Cloud. Si eres nuevo en Google Cloud, crea una cuenta para evaluar el rendimiento de nuestros productos en situaciones reales. Los clientes nuevos también obtienen $300 en créditos gratuitos para ejecutar, probar y, además, implementar cargas de trabajo.
  2. En la página del selector de proyectos de Google Cloud Console, selecciona o crea un proyecto de Google Cloud.

    Ir al selector de proyecto

  3. Asegúrate de que la facturación esté habilitada para tu proyecto de Cloud. Descubre cómo confirmar que tienes habilitada la facturación en un proyecto.

  4. Habilita las API de Kubernetes Engine and BigQuery.

    Habilita las API

Configura tu entorno

En esta sección, puedes configurar la configuración del proyecto que necesitas para completar el instructivo.

Iniciar una instancia de Cloud Shell

Abra Cloud Shell

Trabaja el resto del instructivo en Cloud Shell.

Ejecuta la canalización de manera manual

En los siguientes pasos, iniciarás la canalización. Para ello, harás que BigQuery extraiga todos los archivos con la extensión .go de la tabla sample_files, que es un subconjunto de [bigquery-public-data:github_repos.files]. El uso del subconjunto de datos te permite lograr una experimentación más rentable.

  1. En Cloud Shell, ejecuta los siguientes comandos a fin de crear un conjunto de datos y una tabla nuevos en BigQuery para almacenar resultados intermedios de consultas:

    export PROJECT=$(gcloud info --format='value(config.project)')
    bq mk --project_id $PROJECT spark_on_k8s_manual
    bq mk --project_id $PROJECT spark_on_k8s_manual.go_files
    
  2. Visualiza un ejemplo de los archivos de Go del conjunto de datos del repositorio de GitHub y, luego, almacena los archivos en una tabla intermedia con la opción --destination_table:

    export PROJECT=$(gcloud info --format='value(config.project)')
    bq query --project_id $PROJECT --replace \
             --destination_table spark_on_k8s_manual.go_files \
        'SELECT id, repo_name, path FROM
    [bigquery-public-data:github_repos.sample_files]
         WHERE RIGHT(path, 3) = ".go"'
    

    Deberías ver rutas de archivos junto con el repositorio del que provienen. Por ejemplo:

    Waiting on bqjob_r311c807f17003279_0000015fb8007c47_1 ... (0s) Current status: DONE
    +------------------------------------------+------------------+-------------------------+
    |                    id                    |    repo_name     |          path           |
    +------------------------------------------+------------------+-------------------------+
    | 31a4559c1e636e | mandelsoft/spiff | spiff++/spiff.go        |
    | 15f7611dd21a89 | bep/gr           | examples/router/main.go |
    | 15cbb0b0f096a2 | knq/xo           | internal/fkmode.go      |
    +------------------------------------------+------------------+-------------------------+
    

    La lista de todos los archivos de Go identificados ahora se almacena en la tabla spark_on_k8s_manual.go_files.

  3. Ejecuta la siguiente consulta para mostrar los primeros 10 caracteres de cada archivo:

    export PROJECT=$(gcloud info --format='value(config.project)')
    bq query --project_id $PROJECT 'SELECT sample_repo_name as
    repo_name, SUBSTR(content, 0, 10) FROM
    [bigquery-public-data:github_repos.sample_contents] WHERE id IN
    (SELECT id FROM spark_on_k8s_manual.go_files)'
    

Ejecutar la canalización con Spark en Kubernetes

A continuación, automatiza un procedimiento similar con una aplicación Spark que utilice el conector spark-bigquery para ejecutar directamente las consultas de SQL frente a BigQuery. La aplicación manipula entonces los resultados y los guarda en BigQuery; para ello, utiliza las API de Spark SQL y DataFrames.

Crea un clúster de Kubernetes Engine

Para implementar Spark y la aplicación de muestra, crea un clúster de Kubernetes Engine; para ello, ejecuta los siguientes comandos:

gcloud config set compute/zone us-central1-f
gcloud container clusters create spark-on-gke --machine-type n1-standard-2

Descargar el código de muestra

Clona el repositorio de la aplicación de muestra:

git clone https://github.com/GoogleCloudPlatform/spark-on-k8s-gcp-examples.git
cd spark-on-k8s-gcp-examples/github-insights

Configura la administración de identidades y accesos

Debes crear una cuenta de servicio de Identity and Access Management (IAM) para que Spark pueda acceder a BigQuery.

  1. Crea la cuenta de servicio:

    gcloud iam service-accounts create spark-bq --display-name spark-bq
    
  2. Almacena la dirección de correo electrónico de la cuenta de servicio y el ID del proyecto actual en las variables del entorno que se van a usar en comandos posteriores:

    export SA_EMAIL=$(gcloud iam service-accounts list --filter="displayName:spark-bq" --format='value(email)')
    export PROJECT=$(gcloud info --format='value(config.project)')
    
  3. La aplicación de muestra debe crear y manipular los conjuntos de datos y las tablas de BigQuery, y quitar los artefactos de Cloud Storage. Vincula las funciones bigquery.dataOwner, bigQuery.jobUser y storage.admin a la cuenta de servicio:

    gcloud projects add-iam-policy-binding $PROJECT --member serviceAccount:$SA_EMAIL --role roles/storage.admin
    gcloud projects add-iam-policy-binding $PROJECT --member serviceAccount:$SA_EMAIL --role roles/bigquery.dataOwner
    gcloud projects add-iam-policy-binding $PROJECT --member serviceAccount:$SA_EMAIL --role roles/bigquery.jobUser
    
  4. Descarga la clave JSON de la cuenta de servicio y guárdala en una secreto de Kubernetes. Los controladores y los ejecutores de Spark utilizan este secreto para autenticar con BigQuery:

    gcloud iam service-accounts keys create spark-sa.json --iam-account $SA_EMAIL
    kubectl create secret generic spark-sa --from-file=spark-sa.json
    
  5. Agrega permisos para Spark a fin de poder iniciar trabajos en el clúster de Kubernetes.

    kubectl create clusterrolebinding user-admin-binding --clusterrole=cluster-admin --user=$(gcloud config get-value account)
    kubectl create clusterrolebinding --clusterrole=cluster-admin --serviceaccount=default:default spark-admin
    

Configurar y ejecutar la aplicación Spark

Ahora descarga, instala y configura Spark para ejecutar la aplicación de muestra Spark en el clúster de Kubernetes Engine.

  1. Instala Maven, que utilizas para administrar el proceso de compilación para la aplicación de muestra:

    sudo apt-get install -y maven
  2. Compila el archivo jar de la aplicación de muestra:

    mvn clean package
  3. Crea un bucket de Cloud Storage para almacenar el archivo jar de la aplicación y los resultados de la canalización Spark:

    export PROJECT=$(gcloud info --format='value(config.project)')
    gsutil mb gs://$PROJECT-spark-on-k8s
    
  4. Sube el archivo jar de la aplicación al bucket de Cloud Storage:

    gsutil cp target/github-insights-1.0-SNAPSHOT-jar-with-dependencies.jar \
                   gs://$PROJECT-spark-on-k8s/jars/
    
  5. Crea un conjunto de datos nuevo de BigQuery:

    bq mk --project_id $PROJECT spark_on_k8s
  6. Descarga la distribución oficial de Spark 2.3 y desarchívala:

    wget https://archive.apache.org/dist/spark/spark-2.3.0/spark-2.3.0-bin-hadoop2.7.tgz
    tar xvf spark-2.3.0-bin-hadoop2.7.tgz
    cd spark-2.3.0-bin-hadoop2.7
    
  7. Configura la aplicación Spark, para ello, crea un archivo de propiedades que contenga el información específica del proyecto:

    cat > properties << EOF
    spark.app.name  github-insights
    spark.kubernetes.namespace default
    spark.kubernetes.driverEnv.GCS_PROJECT_ID $PROJECT
    spark.kubernetes.driverEnv.GOOGLE_APPLICATION_CREDENTIALS /mnt/secrets/spark-sa.json
    spark.kubernetes.container.image gcr.io/cloud-solutions-images/spark:v2.3.0-gcs
    spark.kubernetes.driver.secrets.spark-sa  /mnt/secrets
    spark.kubernetes.executor.secrets.spark-sa /mnt/secrets
    spark.driver.cores 0.1
    spark.executor.instances 3
    spark.executor.cores 1
    spark.executor.memory 512m
    spark.executorEnv.GCS_PROJECT_ID    $PROJECT
    spark.executorEnv.GOOGLE_APPLICATION_CREDENTIALS /mnt/secrets/spark-sa.json
    spark.hadoop.google.cloud.auth.service.account.enable true
    spark.hadoop.google.cloud.auth.service.account.json.keyfile /mnt/secrets/spark-sa.json
    spark.hadoop.fs.gs.project.id $PROJECT
    EOF
    
  8. Ejecuta la aplicación Spark en el conjunto de datos de muestra de GitHub mediante los siguientes comandos:

    export KUBERNETES_MASTER_IP=$(gcloud container clusters list --filter name=spark-on-gke --format='value(MASTER_IP)')
    bin/spark-submit \
    --properties-file properties \
    --deploy-mode cluster \
    --class spark.bigquery.example.github.NeedingHelpGoPackageFinder \
    --master k8s://https://$KUBERNETES_MASTER_IP:443 \
    --jars http://central.maven.org/maven2/com/databricks/spark-avro_2.11/4.0.0/spark-avro_2.11-4.0.0.jar \
    gs://$PROJECT-spark-on-k8s/jars/github-insights-1.0-SNAPSHOT-jar-with-dependencies.jar \
    $PROJECT spark_on_k8s $PROJECT-spark-on-k8s --usesample
    
  9. Abre una sesión nueva de Cloud Shell. Para ello, haz clic en el botón Agregar sesión de Cloud Shell:

    Botón Agregar sesiones de Cloud Shell

  10. En la sesión nueva de Cloud Shell, examina los registros del pod del controlador mediante el siguiente comando para realizar un seguimiento del progreso de la aplicación. La aplicación demora unos cinco minutos en ejecutarse.

    kubectl logs -l spark-role=driver
  11. Cuando la aplicación termine de ejecutarse, verifica los 10 paquetes más populares mediante la ejecución del siguiente comando:

    bq query "SELECT * FROM spark_on_k8s.popular_go_packages
    ORDER BY popularity DESC LIMIT 10"
    

Puedes ejecutar la misma canalización en el conjunto completo de tablas en el conjunto de datos de GitHub si quitas la opción --usesample en el paso 8. Ten en cuenta que el tamaño del conjunto de datos completo es mucho mayor que el del conjunto de datos de muestra, por lo que es probable que necesites un clúster más grande para ejecutar la canalización hasta completarse en un tiempo razonable.

Limpia

Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos usados en este instructivo, borra el proyecto que contiene los recursos o conserva el proyecto y borra los recursos individuales.

Una vez que completes el instructivo, puedes limpiar los recursos que creaste para que dejen de usar la cuota y generen cargos. En las siguientes secciones, se describe cómo borrar o desactivar estos recursos.

Borra el proyecto

La manera más fácil de eliminar la facturación es borrar el proyecto que creaste para el instructivo.

Para borrar el proyecto, sigue estos pasos:

  1. En Cloud Console, ve a la página Administrar recursos.

    Ir a Administrar recursos

  2. En la lista de proyectos, elige el proyecto que quieres borrar y haz clic en Borrar.
  3. En el diálogo, escribe el ID del proyecto y, luego, haz clic en Cerrar para borrar el proyecto.

¿Qué sigue?

  • Mira otro ejemplo sobre el uso de Spark con BigQuery y Dataproc.
  • Revisa este instructivo que utiliza Cloud Dataproc, BigQuery y Apache Spark ML para el aprendizaje automático.

  • Explora arquitecturas de referencia, diagramas, instructivos y prácticas recomendadas sobre Google Cloud. Consulta nuestro Cloud Architecture Center.