Exécuter plusieurs jobs BigQuery en parallèle

BigQuery héberge un certain nombre d'ensembles de données publics que le grand public peut interroger. Dans ce tutoriel, vous allez créer un workflow qui exécute plusieurs jobs de requête BigQuery en parallèle. Vous constaterez ainsi une amélioration des performances par rapport à l'exécution des jobs en série, les uns après les autres.

Exécuter un job de requête BigQuery

Dans BigQuery, vous pouvez exécuter une tâche de requête interactive (à la demande). Pour en savoir plus, consultez la page Exécuter des tâches de requête interactives et par lot.

Console

  1. Dans la console Google Cloud , accédez à la page BigQuery.

    Accéder à BigQuery

  2. Saisissez la requête SQL BigQuery suivante dans la zone de texte de l'éditeur de requête :

    SELECT TITLE, SUM(views)
    FROM `bigquery-samples.wikipedia_pageviews.201207h`
    GROUP BY TITLE
    ORDER BY SUM(views) DESC
    LIMIT 100
    
  3. Cliquez sur Exécuter.

bq

Dans votre terminal, saisissez la commande bq query suivante pour exécuter une requête interactive à l'aide de la syntaxe SQL standard :

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'

Cette requête renvoie les 100 titres Wikipédia les plus consultés au cours d'un mois donné et écrit les résultats dans une table temporaire.

Notez la durée d'exécution de la requête.

Déployer un workflow qui exécute plusieurs requêtes en série

Une définition de workflow est constituée d'une série d'étapes décrites à l'aide de la syntaxe Workflows. Après avoir créé un workflow, vous pouvez le déployer pour le rendre disponible en exécution. L'étape de déploiement vérifie également que le fichier source peut être exécuté.

Le workflow suivant définit une liste de cinq tables sur lesquelles exécuter une requête à l'aide du connecteur BigQuery de Workflows. Les requêtes sont exécutées en série, les unes après les autres, et les titres les plus regardés de chaque tableau sont enregistrés dans une carte de résultats.

Console

  1. Dans la console Google Cloud , accédez à la page Workflows :

    Accéder à "Workflows"

  2. Cliquez sur Créer.

  3. Saisissez un nom pour le nouveau workflow, par exemple workflow-serial-bqjobs.

  4. Choisissez une région appropriée. Exemple : us-central1.

  5. Sélectionnez le compte de service que vous avez créé précédemment.

    Vous devez déjà avoir attribué les rôles IAM BigQuery> Utilisateur de tâche BigQuery et Logging> Rédacteur de journaux au compte de service.

  6. Cliquez sur Suivant.

  7. Dans l'éditeur de workflow, saisissez la définition suivante pour votre workflow :

    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. Cliquez sur Déployer.

gcloud

  1. Ouvrez un terminal et créez un fichier de code source pour votre workflow :

    touch workflow-serial-bqjobs.yaml
  2. Copiez le workflow suivant dans votre fichier de code source :

    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. Déployez le workflow en saisissant la commande suivante :

    gcloud workflows deploy workflow-serial-bqjobs \
       --source=workflow-serial-bqjobs.yaml \
       --service-account=MY_SERVICE_ACCOUNT@MY_PROJECT.iam.gserviceaccount.com

    Remplacez MY_SERVICE_ACCOUNT@MY_PROJECT.iam.gserviceaccount.com par l'adresse e-mail du compte de service que vous avez créé précédemment.

    Vous devriez déjà avoir attribué les rôles IAM roles/bigquery.jobUser et roles/logging.logWriter au compte de service.

Exécuter le workflow et exécuter plusieurs requêtes en série

L'exécution d'un workflow exécute la définition actuelle du workflow associé au workflow.

Console

  1. Dans la console Google Cloud , accédez à la page Workflows :

    Accéder à "Workflows"

  2. Sur la page Workflows, sélectionnez le workflow workflow-serial-bqjobs pour accéder à sa page d'informations.

  3. Sur la page Détails du workflow, cliquez sur Exécuter.

  4. Cliquez à nouveau sur Exécuter.

  5. Affichez les résultats du workflow dans le volet Output (Résultat).

gcloud

  1. Ouvrez un terminal.

  2. Exécutez le workflow :

     gcloud workflows run workflow-serial-bqjob

L'exécution du workflow devrait prendre environ une minute ou cinq fois le temps d'exécution précédent. Le résultat inclura chaque tableau et ressemblera à ce qui suit :

{
  "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"
  }
}

Déployer et exécuter un workflow qui exécute plusieurs requêtes en parallèle

Au lieu d'exécuter cinq requêtes de manière séquentielle, vous pouvez les exécuter en parallèle en apportant quelques modifications :

 - runQueries:
    parallel:
        shared: [results]
        for:
            value: table
            in: ${tables}
  • Une étape parallel permet à chaque itération de la boucle for de s'exécuter en parallèle.
  • La variable results est déclarée comme shared, ce qui lui permet d'être accessible en écriture par une branche, et le résultat de chaque branche peut y être ajouté.

Console

  1. Dans la console Google Cloud , accédez à la page Workflows :

    Accéder à "Workflows"

  2. Cliquez sur Créer.

  3. Saisissez un nom pour le nouveau workflow, par exemple workflow-parallel-bqjobs.

  4. Choisissez une région appropriée. Exemple : us-central1.

  5. Sélectionnez le compte de service que vous avez créé précédemment.

  6. Cliquez sur Suivant.

  7. Dans l'éditeur de workflow, saisissez la définition suivante pour votre workflow :

    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. Cliquez sur Déployer.

  9. Sur la page Détails du workflow, cliquez sur Exécuter.

  10. Cliquez à nouveau sur Exécuter.

  11. Affichez les résultats du workflow dans le volet Output (Résultat).

gcloud

  1. Ouvrez un terminal et créez un fichier de code source pour votre workflow :

    touch workflow-parallel-bqjobs.yaml
  2. Copiez le workflow suivant dans votre fichier de code source :

    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. Déployez le workflow en saisissant la commande suivante :

    gcloud workflows deploy workflow-parallell-bqjobs \
       --source=workflow-parallel-bqjobs.yaml \
       --service-account=MY_SERVICE_ACCOUNT@MY_PROJECT.iam.gserviceaccount.com

    Remplacez MY_SERVICE_ACCOUNT@MY_PROJECT.iam.gserviceaccount.com par l'adresse e-mail du compte de service que vous avez créé précédemment.

  4. Exécutez le workflow :

     gcloud workflows run workflow-parallel-bqjobs

Le résultat sera semblable à celui de la sortie précédente, mais l'exécution du workflow devrait prendre environ 20 secondes ou moins.