Ejecuta múltiples trabajos de BigQuery en paralelo


BigQuery aloja una serie de conjuntos de datos públicos que están disponibles para que el público en general los consulte. En este instructivo, crearás un flujo de trabajo que ejecute varios trabajos de consulta de BigQuery en paralelo, lo que demuestra una mejora en el rendimiento en comparación con ejecutar los trabajos en serie, uno tras otro.

Objetivos

En este instructivo, realizarás las siguientes acciones:

  1. Ejecutar una consulta en un conjunto de datos públicos de Wikipedia para determinar los títulos más vistos en un mes específico
  2. Implementar y ejecutar un flujo de trabajo que ejecute varios trabajos de consulta de BigQuery en serie, uno después del otro
  3. Implementar y ejecutar un flujo de trabajo que ejecute los trabajos de BigQuery con una iteración paralela, en la que los bucles for comunes se ejecuten en paralelo

Puedes ejecutar los siguientes comandos en la consola de Google Cloud, o bien con Google Cloud CLI en tu terminal o en Cloud Shell.

Costos

En este documento, usarás los siguientes componentes facturables de Google Cloud:

Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios. Es posible que los usuarios nuevos de Google Cloud califiquen para obtener una prueba gratuita.

Antes de comenzar

Es posible que las restricciones de seguridad que define tu organización no te permitan completar los siguientes pasos. Para obtener información sobre la solución de problemas, consulta Desarrolla aplicaciones en un entorno de Google Cloud restringido.

Console

  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 la consola de Google Cloud, selecciona o crea un proyecto de Google Cloud.

    Ir al selector de proyectos

  3. Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.

  4. Habilita la API de Workflows.

    Habilita la API

  5. Crear una cuenta de servicio:

    1. En la consola de Google Cloud, ve a la página Crear cuenta de servicio.

      Ve a Crear cuenta de servicio
    2. Elige tu proyecto.
    3. Ingresa un nombre en el campo Nombre de cuenta de servicio. La consola de Google Cloud completa el campo ID de cuenta de servicio en función de este nombre.

      Opcional: en el campo Descripción de la cuenta de servicio, ingresa una descripción. Por ejemplo, Service account for quickstart.

    4. Haz clic en Crear y continuar.
    5. Otorga los siguientes roles a la cuenta de servicio: BigQuery > BigQuery Job User, Logging > Logs Writer.

      Para otorgar un rol, busca la lista Selecciona un rol y, luego, selecciona el rol.

      Para otorgar roles adicionales, haz clic en Agregar otro rol y agrega cada rol adicional.

    6. Haga clic en Continuar.
    7. Haz clic en Listo para terminar de crear la cuenta de servicio.

  6. En la página del selector de proyectos de la consola de Google Cloud, selecciona o crea un proyecto de Google Cloud.

    Ir al selector de proyectos

  7. Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.

  8. Habilita la API de Workflows.

    Habilita la API

  9. Crear una cuenta de servicio:

    1. En la consola de Google Cloud, ve a la página Crear cuenta de servicio.

      Ve a Crear cuenta de servicio
    2. Elige tu proyecto.
    3. Ingresa un nombre en el campo Nombre de cuenta de servicio. La consola de Google Cloud completa el campo ID de cuenta de servicio en función de este nombre.

      Opcional: en el campo Descripción de la cuenta de servicio, ingresa una descripción. Por ejemplo, Service account for quickstart.

    4. Haz clic en Crear y continuar.
    5. Otorga los siguientes roles a la cuenta de servicio: BigQuery > BigQuery Job User, Logging > Logs Writer.

      Para otorgar un rol, busca la lista Selecciona un rol y, luego, selecciona el rol.

      Para otorgar roles adicionales, haz clic en Agregar otro rol y agrega cada rol adicional.

    6. Haga clic en Continuar.
    7. Haz clic en Listo para terminar de crear la cuenta de servicio.

gcloud

  1. Accede a tu cuenta de Google.

    Si todavía no tienes una cuenta, regístrate para obtener una nueva.

  2. Instala Google Cloud CLI.
  3. Para inicializar la CLI de gcloud, ejecuta el siguiente comando:

    gcloud init
  4. Crea o selecciona un proyecto de Google Cloud.

    • Crea un proyecto de Google Cloud:

      gcloud projects create PROJECT_ID

      Reemplaza PROJECT_ID por un nombre para el proyecto de Google Cloud que estás creando.

    • Selecciona el proyecto de Google Cloud que creaste:

      gcloud config set project PROJECT_ID

      Reemplaza PROJECT_ID por el nombre del proyecto de Google Cloud.

  5. Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.

  6. Habilita la API de Workflows:

    gcloud services enable workflows.googleapis.com
  7. Configura la autenticación:

    1. Crea la cuenta de servicio:

      gcloud iam service-accounts create SERVICE_ACCOUNT_NAME

      Reemplaza SERVICE_ACCOUNT_NAME por un nombre para la cuenta de servicio.

    2. Otorga roles a la cuenta de servicio. Ejecuta el siguiente comando una vez para cada uno de los siguientes roles de IAM: roles/bigquery.jobUser, roles/logging.logWriter:

      gcloud projects add-iam-policy-binding PROJECT_ID --member="serviceAccount:SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com" --role=ROLE

      Reemplaza lo siguiente:

      • SERVICE_ACCOUNT_NAME: el nombre de la cuenta de servicio
      • PROJECT_ID: el ID del proyecto en el que creaste la cuenta de servicio
      • ROLE: el rol a otorgar
  8. Instala Google Cloud CLI.
  9. Para inicializar la CLI de gcloud, ejecuta el siguiente comando:

    gcloud init
  10. Crea o selecciona un proyecto de Google Cloud.

    • Crea un proyecto de Google Cloud:

      gcloud projects create PROJECT_ID

      Reemplaza PROJECT_ID por un nombre para el proyecto de Google Cloud que estás creando.

    • Selecciona el proyecto de Google Cloud que creaste:

      gcloud config set project PROJECT_ID

      Reemplaza PROJECT_ID por el nombre del proyecto de Google Cloud.

  11. Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.

  12. Habilita la API de Workflows:

    gcloud services enable workflows.googleapis.com
  13. Configura la autenticación:

    1. Crea la cuenta de servicio:

      gcloud iam service-accounts create SERVICE_ACCOUNT_NAME

      Reemplaza SERVICE_ACCOUNT_NAME por un nombre para la cuenta de servicio.

    2. Otorga roles a la cuenta de servicio. Ejecuta el siguiente comando una vez para cada uno de los siguientes roles de IAM: roles/bigquery.jobUser, roles/logging.logWriter:

      gcloud projects add-iam-policy-binding PROJECT_ID --member="serviceAccount:SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com" --role=ROLE

      Reemplaza lo siguiente:

      • SERVICE_ACCOUNT_NAME: el nombre de la cuenta de servicio
      • PROJECT_ID: el ID del proyecto en el que creaste la cuenta de servicio
      • ROLE: el rol a otorgar

Ejecuta un trabajo de consulta de BigQuery

En BigQuery, puedes ejecutar un trabajo de consulta interactiva (a pedido). Para obtener más información, consulta Ejecuta trabajos de consulta interactivos y por lotes.

Console

  1. En la consola de Google Cloud, ve a la página de BigQuery.

    Ir a BigQuery

  2. Ingresa la siguiente consulta en SQL de BigQuery en el área de texto del Editor de consultas:

    SELECT TITLE, SUM(views)
    FROM `bigquery-samples.wikipedia_pageviews.201207h`
    GROUP BY TITLE
    ORDER BY SUM(views) DESC
    LIMIT 100
    
  3. Haz clic en Ejecutar.

bq

En la terminal, ingresa el siguiente comando de bq query para ejecutar una consulta interactiva con la sintaxis de SQL estándar:

bq query \
--use_legacy_sql=false \
'SELECT
  TITLE, SUM(views)
FROM
  `bigquery-samples.wikipedia_pageviews.201207h`
GROUP BY
  TITLE
ORDER BY
  SUM(views) DESC
LIMIT 100'

Esto ejecuta una consulta que muestra los 100 títulos más populares de Wikipedia con la mayor cantidad de vistas en un mes específico y escribe el resultado en una tabla temporal.

Observa cuánto tarda en ejecutarse la consulta.

Implementa un flujo de trabajo que ejecute varias consultas en serie

Una definición de flujo de trabajo se compone de una serie de pasos que se describen mediante la sintaxis de Workflows. Después de crear un flujo de trabajo, lo implementas a fin de que esté disponible para su ejecución. El paso de implementación también valida que el archivo de origen se pueda ejecutar.

En el siguiente flujo de trabajo, se define una lista de cinco tablas en las que se debe ejecutar una consulta mediante el conector de BigQuery de Workflows. Las consultas se ejecutan en serie, una tras otra, y los títulos más vistos de cada tabla se guardan en un mapa de resultados.

Console

  1. En la consola de Google Cloud, ve a la página Workflows.

    Ir a Workflows

  2. Haz clic en Crear.

  3. Ingresa un nombre para el flujo de trabajo nuevo, como workflow-serial-bqjobs.

  4. Elegir una región adecuada por ejemplo, us-central1.

  5. Selecciona la cuenta de servicio que creaste anteriormente.

    Ya deberías haber otorgado los roles de IAM BigQuery > de usuario de trabajo de BigQuery y Logging > Escritor de registros a la cuenta de servicio.

  6. Haz clic en Siguiente.

  7. En el editor de flujo de trabajo, ingresa la siguiente definición para tu flujo de trabajo:

    main:
        steps:
        - init:
            assign:
                - results : {} # result from each iteration keyed by table name
                - tables:
                    - 201201h
                    - 201202h
                    - 201203h
                    - 201204h
                    - 201205h
        - runQueries:
            for:
                value: table
                in: ${tables}
                steps:
                - logTable:
                    call: sys.log
                    args:
                        text: ${"Running query for table " + table}
                - runQuery:
                    call: googleapis.bigquery.v2.jobs.query
                    args:
                        projectId: ${sys.get_env("GOOGLE_CLOUD_PROJECT_ID")}
                        body:
                            useLegacySql: false
                            useQueryCache: false
                            timeoutMs: 30000
                            # Find top 100 titles with most views on Wikipedia
                            query: ${
                                "SELECT TITLE, SUM(views)
                                FROM `bigquery-samples.wikipedia_pageviews." + table + "`
                                WHERE LENGTH(TITLE) > 10
                                GROUP BY TITLE
                                ORDER BY SUM(VIEWS) DESC
                                LIMIT 100"
                                }
                    result: queryResult
                - returnResult:
                    assign:
                        # Return the top title from each table
                        - results[table]: {}
                        - results[table].title: ${queryResult.rows[0].f[0].v}
                        - results[table].views: ${queryResult.rows[0].f[1].v}
        - returnResults:
            return: ${results}
  8. Haz clic en Implementar.

gcloud

  1. Abre una terminal y crea un archivo de código fuente para tu flujo de trabajo:

    touch workflow-serial-bqjobs.yaml
    
  2. Copia el siguiente flujo de trabajo en tu archivo de código fuente:

    main:
        steps:
        - init:
            assign:
                - results : {} # result from each iteration keyed by table name
                - tables:
                    - 201201h
                    - 201202h
                    - 201203h
                    - 201204h
                    - 201205h
        - runQueries:
            for:
                value: table
                in: ${tables}
                steps:
                - logTable:
                    call: sys.log
                    args:
                        text: ${"Running query for table " + table}
                - runQuery:
                    call: googleapis.bigquery.v2.jobs.query
                    args:
                        projectId: ${sys.get_env("GOOGLE_CLOUD_PROJECT_ID")}
                        body:
                            useLegacySql: false
                            useQueryCache: false
                            timeoutMs: 30000
                            # Find top 100 titles with most views on Wikipedia
                            query: ${
                                "SELECT TITLE, SUM(views)
                                FROM `bigquery-samples.wikipedia_pageviews." + table + "`
                                WHERE LENGTH(TITLE) > 10
                                GROUP BY TITLE
                                ORDER BY SUM(VIEWS) DESC
                                LIMIT 100"
                                }
                    result: queryResult
                - returnResult:
                    assign:
                        # Return the top title from each table
                        - results[table]: {}
                        - results[table].title: ${queryResult.rows[0].f[0].v}
                        - results[table].views: ${queryResult.rows[0].f[1].v}
        - returnResults:
            return: ${results}
  3. Para implementar el flujo de trabajo, ingresa el siguiente comando:

    gcloud workflows deploy workflow-serial-bqjobs \
       --source=workflow-serial-bqjobs.yaml \
       --service-account=MY_SERVICE_ACCOUNT@MY_PROJECT.IAM.GSERVICEACCOUNT.COM
    

    Reemplaza MY_SERVICE_ACCOUNT@MY_PROJECT.IAM.GSERVICEACCOUNT.COM por el correo electrónico de la cuenta de servicio que creaste antes.

    Ya deberías haber otorgado las funciones de IAM roles/bigquery.jobUser y roles/logging.logWriter a la cuenta de servicio.

Ejecutar el flujo de trabajo y ejecutar varias consultas en serie

Cuando se ejecuta un flujo de trabajo, se ejecuta la definición actual del flujo de trabajo asociada con este.

Console

  1. En la consola de Google Cloud, ve a la página Workflows.

    Ir a Workflows

  2. En la página Flujos de trabajo, selecciona el flujo de trabajo workflow-serial-bqjobs para ir a su página de detalles.

  3. En la página Detalles del flujo de trabajo, haz clic en Ejecutar.

  4. Haz clic de nuevo en Ejecutar.

  5. Visualiza los resultados del flujo de trabajo en el panel Resultado.

gcloud

  1. Abre una terminal.

  2. Ejecuta el flujo de trabajo:

     gcloud workflows run workflow-serial-bqjob

La ejecución del flujo de trabajo debería tardar alrededor de un minuto o cinco veces que el tiempo de ejecución anterior. El resultado incluirá cada tabla y será similar al siguiente:

{
  "201201h": {
    "title": "Special:Search",
    "views": "14591339"
  },
  "201202h": {
    "title": "Special:Search",
    "views": "132765420"
  },
  "201203h": {
    "title": "Special:Search",
    "views": "123316818"
  },
  "201204h": {
    "title": "Special:Search",
    "views": "116830614"
  },
  "201205h": {
    "title": "Special:Search",
    "views": "131357063"
  }
}

Implementar y ejecutar un flujo de trabajo que ejecute varias consultas en paralelo

En lugar de ejecutar cinco consultas de forma secuencial, puedes ejecutar las consultas en paralelo con los siguientes cambios:

 - runQueries:
    parallel:
        shared: [results]
        for:
            value: table
            in: ${tables}
  • Un paso parallel permite que cada iteración del bucle for se ejecute en paralelo.
  • La variable results se declara como shared, lo que permite que una rama pueda escribir en ella, y se le puede agregar el resultado de cada rama.

Console

  1. En la consola de Google Cloud, ve a la página Workflows.

    Ir a Workflows

  2. Haz clic en Crear.

  3. Ingresa un nombre para el flujo de trabajo nuevo, como workflow-parallel-bqjobs.

  4. Elegir una región adecuada por ejemplo, us-central1.

  5. Selecciona la cuenta de servicio que creaste anteriormente.

  6. Haz clic en Siguiente.

  7. En el editor de flujo de trabajo, ingresa la siguiente definición para tu flujo de trabajo:

    main:
        steps:
        - init:
            assign:
                - results : {} # result from each iteration keyed by table name
                - tables:
                    - 201201h
                    - 201202h
                    - 201203h
                    - 201204h
                    - 201205h
        - runQueries:
            parallel:
                shared: [results]
                for:
                    value: table
                    in: ${tables}
                    steps:
                    - logTable:
                        call: sys.log
                        args:
                            text: ${"Running query for table " + table}
                    - runQuery:
                        call: googleapis.bigquery.v2.jobs.query
                        args:
                            projectId: ${sys.get_env("GOOGLE_CLOUD_PROJECT_ID")}
                            body:
                                useLegacySql: false
                                useQueryCache: false
                                timeoutMs: 30000
                                # Find top 100 titles with most views on Wikipedia
                                query: ${
                                    "SELECT TITLE, SUM(views)
                                    FROM `bigquery-samples.wikipedia_pageviews." + table + "`
                                    WHERE LENGTH(TITLE) > 10
                                    GROUP BY TITLE
                                    ORDER BY SUM(VIEWS) DESC
                                    LIMIT 100"
                                    }
                        result: queryResult
                    - returnResult:
                        assign:
                            # Return the top title from each table
                            - results[table]: {}
                            - results[table].title: ${queryResult.rows[0].f[0].v}
                            - results[table].views: ${queryResult.rows[0].f[1].v}
        - returnResults:
            return: ${results}
  8. Haz clic en Implementar.

  9. En la página Detalles del flujo de trabajo, haz clic en Ejecutar.

  10. Haz clic de nuevo en Ejecutar.

  11. Visualiza los resultados del flujo de trabajo en el panel Resultado.

gcloud

  1. Abre una terminal y crea un archivo de código fuente para tu flujo de trabajo:

    touch workflow-parallel-bqjobs.yaml
    
  2. Copia el siguiente flujo de trabajo en tu archivo de código fuente:

    main:
        steps:
        - init:
            assign:
                - results : {} # result from each iteration keyed by table name
                - tables:
                    - 201201h
                    - 201202h
                    - 201203h
                    - 201204h
                    - 201205h
        - runQueries:
            parallel:
                shared: [results]
                for:
                    value: table
                    in: ${tables}
                    steps:
                    - logTable:
                        call: sys.log
                        args:
                            text: ${"Running query for table " + table}
                    - runQuery:
                        call: googleapis.bigquery.v2.jobs.query
                        args:
                            projectId: ${sys.get_env("GOOGLE_CLOUD_PROJECT_ID")}
                            body:
                                useLegacySql: false
                                useQueryCache: false
                                timeoutMs: 30000
                                # Find top 100 titles with most views on Wikipedia
                                query: ${
                                    "SELECT TITLE, SUM(views)
                                    FROM `bigquery-samples.wikipedia_pageviews." + table + "`
                                    WHERE LENGTH(TITLE) > 10
                                    GROUP BY TITLE
                                    ORDER BY SUM(VIEWS) DESC
                                    LIMIT 100"
                                    }
                        result: queryResult
                    - returnResult:
                        assign:
                            # Return the top title from each table
                            - results[table]: {}
                            - results[table].title: ${queryResult.rows[0].f[0].v}
                            - results[table].views: ${queryResult.rows[0].f[1].v}
        - returnResults:
            return: ${results}
  3. Para implementar el flujo de trabajo, ingresa el siguiente comando:

    gcloud workflows deploy workflow-parallell-bqjobs \
       --source=workflow-parallel-bqjobs.yaml \
       --service-account=MY_SERVICE_ACCOUNT@MY_PROJECT.IAM.GSERVICEACCOUNT.COM
    

    Reemplaza MY_SERVICE_ACCOUNT@MY_PROJECT.IAM.GSERVICEACCOUNT.COM por el correo electrónico de la cuenta de servicio que creaste antes.

  4. Ejecuta el flujo de trabajo:

     gcloud workflows run workflow-serial-bqjob

El resultado será similar al resultado anterior, pero la ejecución del flujo de trabajo debería tardar aproximadamente veinte segundos o menos.

Limpia

Si creaste un proyecto nuevo para este instructivo, bórralo. Si usaste un proyecto existente y deseas conservarlo sin los cambios que se agregaron en este instructivo, borra los recursos creados para el instructivo.

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, haz lo siguiente:

  1. En la consola de Google Cloud, 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.

Elimina recursos de instructivos

Borra los flujos de trabajo creados en este instructivo:

gcloud workflows delete WORKFLOW_NAME

¿Qué sigue?