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 tâches de requête BigQuery en parallèle, ce qui démontre une amélioration des performances par rapport à l'exécution des tâches en série l'une après l'autre.

Objectifs

Au cours de ce tutoriel, vous allez :

  1. Exécutez une requête sur un ensemble de données public Wikipédia pour déterminer les titres les plus consultés au cours d'un mois spécifique.
  2. Déployez et exécutez un workflow qui exécute plusieurs tâches de requête BigQuery en série, l'une après l'autre.
  3. Déployez et exécutez un workflow qui exécute les tâches BigQuery à l'aide d'une itération parallèle, et dans lequel les boucles for ordinaires sont exécutées en parallèle.

Vous pouvez exécuter les commandes suivantes dans la console Google Cloud ou à l'aide de la Google Cloud CLI dans votre terminal ou dans Cloud Shell.

Coûts

Dans ce document, vous utilisez les composants facturables suivants de Google Cloud :

Obtenez une estimation des coûts en fonction de votre utilisation prévue à l'aide du simulateur de coût. Les nouveaux utilisateurs de Google Cloud peuvent bénéficier d'un essai gratuit.

Avant de commencer

Les contraintes de sécurité définies par votre organisation peuvent vous empêcher d'effectuer les étapes suivantes. Pour obtenir des informations de dépannage, consultez la page Développer des applications dans un environnement Google Cloud limité.

Console

  1. Connectez-vous à votre compte Google Cloud. Si vous débutez sur Google Cloud, créez un compte pour évaluer les performances de nos produits en conditions réelles. Les nouveaux clients bénéficient également de 300 $ de crédits gratuits pour exécuter, tester et déployer des charges de travail.
  2. Dans Google Cloud Console, sur la page de sélection du projet, sélectionnez ou créez un projet Google Cloud.

    Accéder au sélecteur de projet

  3. Vérifiez que la facturation est activée pour votre projet Google Cloud.

  4. Activez l'API Workflows

    Activer l'API

  5. Créez un compte de service :

    1. Dans la console Google Cloud, accédez à la page Créer un compte de service.

      Accéder à la page "Créer un compte de service"
    2. Sélectionnez votre projet.
    3. Dans le champ Nom du compte de service, saisissez un nom. La console Google Cloud remplit le champ ID du compte de service en fonction de ce nom.

      Dans le champ Description du compte de service, saisissez une description. Exemple : Service account for quickstart.

    4. Cliquez sur Créer et continuer.
    5. Attribuez les rôles suivants au compte de service : BigQuery > BigQuery Job User, Logging > Logs Writer.

      Pour attribuer un rôle, trouvez la liste Sélectionner un rôle, puis sélectionnez le rôle.

      Pour attribuer des rôles supplémentaires, cliquez sur Ajouter un autre rôle et ajoutez chaque rôle supplémentaire.

    6. Cliquez sur Continuer.
    7. Cliquez sur OK pour terminer la création du compte de service.

  6. Dans Google Cloud Console, sur la page de sélection du projet, sélectionnez ou créez un projet Google Cloud.

    Accéder au sélecteur de projet

  7. Vérifiez que la facturation est activée pour votre projet Google Cloud.

  8. Activez l'API Workflows

    Activer l'API

  9. Créez un compte de service :

    1. Dans la console Google Cloud, accédez à la page Créer un compte de service.

      Accéder à la page "Créer un compte de service"
    2. Sélectionnez votre projet.
    3. Dans le champ Nom du compte de service, saisissez un nom. La console Google Cloud remplit le champ ID du compte de service en fonction de ce nom.

      Dans le champ Description du compte de service, saisissez une description. Exemple : Service account for quickstart.

    4. Cliquez sur Créer et continuer.
    5. Attribuez les rôles suivants au compte de service : BigQuery > BigQuery Job User, Logging > Logs Writer.

      Pour attribuer un rôle, trouvez la liste Sélectionner un rôle, puis sélectionnez le rôle.

      Pour attribuer des rôles supplémentaires, cliquez sur Ajouter un autre rôle et ajoutez chaque rôle supplémentaire.

    6. Cliquez sur Continuer.
    7. Cliquez sur OK pour terminer la création du compte de service.

gcloud

  1. Connectez-vous à votre compte Google.

    Si vous n'en possédez pas déjà un, vous devez en créer un.

  2. Installez Google Cloud CLI.
  3. Pour initialiser gcloudCLI, exécutez la commande suivante :

    gcloud init
  4. Créez ou sélectionnez un projet Google Cloud.

    • Créez un projet Google Cloud :

      gcloud projects create PROJECT_ID

      Remplacez PROJECT_ID par le nom du projet Google Cloud que vous créez.

    • Sélectionnez le projet Google Cloud que vous avez créé :

      gcloud config set project PROJECT_ID

      Remplacez PROJECT_ID par le nom de votre projet Google Cloud.

  5. Vérifiez que la facturation est activée pour votre projet Google Cloud.

  6. Activer l'API Workflows :

    gcloud services enable workflows.googleapis.com
  7. Configurez l'authentification :

    1. Créez le compte de service :

      gcloud iam service-accounts create SERVICE_ACCOUNT_NAME

      Remplacez SERVICE_ACCOUNT_NAME par le nom que vous souhaitez donner au compte de service.

    2. Attribuez des rôles au compte de service. Exécutez la commande suivante une fois pour chacun des rôles IAM suivants : 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

      Remplacez les éléments suivants :

      • SERVICE_ACCOUNT_NAME : nom du compte de service.
      • PROJECT_ID : ID du projet dans lequel vous avez créé le compte de service.
      • ROLE : rôle à accorder
  8. Installez Google Cloud CLI.
  9. Pour initialiser gcloudCLI, exécutez la commande suivante :

    gcloud init
  10. Créez ou sélectionnez un projet Google Cloud.

    • Créez un projet Google Cloud :

      gcloud projects create PROJECT_ID

      Remplacez PROJECT_ID par le nom du projet Google Cloud que vous créez.

    • Sélectionnez le projet Google Cloud que vous avez créé :

      gcloud config set project PROJECT_ID

      Remplacez PROJECT_ID par le nom de votre projet Google Cloud.

  11. Vérifiez que la facturation est activée pour votre projet Google Cloud.

  12. Activer l'API Workflows :

    gcloud services enable workflows.googleapis.com
  13. Configurez l'authentification :

    1. Créez le compte de service :

      gcloud iam service-accounts create SERVICE_ACCOUNT_NAME

      Remplacez SERVICE_ACCOUNT_NAME par le nom que vous souhaitez donner au compte de service.

    2. Attribuez des rôles au compte de service. Exécutez la commande suivante une fois pour chacun des rôles IAM suivants : 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

      Remplacez les éléments suivants :

      • SERVICE_ACCOUNT_NAME : nom du compte de service.
      • PROJECT_ID : ID du projet dans lequel vous avez créé le compte de service.
      • ROLE : rôle à accorder

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 É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 opération exécute une requête qui renvoie les 100 titres Wikipédia ayant le plus de vues au cours d'un mois spécifique et écrit la sortie 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 composée d'une série d'étapes décrites à l'aide de la syntaxe Workflows. Après avoir créé un workflow, vous le déployez pour le rendre disponible à l'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 Workflows. Les requêtes sont exécutées en série, l'une après l'autre, et les titres les plus consultés de chaque table sont enregistrés dans un mappage de résultats.

Console

  1. Dans Google Cloud Console, 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 avoir déjà 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 Deploy (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 le 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 devez avoir déjà 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 Google Cloud Console, 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 doit prendre environ une minute à cinq fois par rapport à la durée d'exécution précédente. Le résultat inclura chaque table 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 permet d'être accessible en écriture par une branche, et le résultat de chaque branche peut y être ajouté.

Console

  1. Dans Google Cloud Console, 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 Deploy (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 le 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-serial-bqjob

Le résultat sera semblable au résultat précédent, mais l'exécution du workflow ne devrait pas prendre plus de 20 secondes.

Effectuer un nettoyage

Si vous avez créé un projet pour ce tutoriel, supprimez-le. Si vous avez utilisé un projet existant et que vous souhaitez le conserver sans les modifications du présent tutoriel, supprimez les ressources créées pour ce tutoriel.

Supprimer le projet

Le moyen le plus simple d'empêcher la facturation est de supprimer le projet que vous avez créé pour ce tutoriel.

Pour supprimer le projet :

  1. Dans la console Google Cloud, accédez à la page Gérer les ressources.

    Accéder à la page Gérer les ressources

  2. Dans la liste des projets, sélectionnez le projet que vous souhaitez supprimer, puis cliquez sur Supprimer.
  3. Dans la boîte de dialogue, saisissez l'ID du projet, puis cliquez sur Arrêter pour supprimer le projet.

Supprimer les ressources du tutoriel

Supprimez les workflows créés dans ce tutoriel:

gcloud workflows delete WORKFLOW_NAME

Étapes suivantes