Esegui più job BigQuery in parallelo

BigQuery ospita una serie di set di dati pubblici disponibili per l'esecuzione di query da parte del pubblico. In questo tutorial, creerai un flusso di lavoro che esegue più job di query BigQuery in parallelo, dimostrando un miglioramento delle prestazioni rispetto all'esecuzione dei job in serie, uno dopo l'altro.

Esegui un job di query BigQuery

In BigQuery, puoi eseguire un job di query interattiva (on demand). Per ulteriori informazioni, consulta la sezione Esecuzione di job di query interattivi e batch.

Console

  1. Nella console Google Cloud , vai alla pagina BigQuery.

    Vai a BigQuery

  2. Inserisci la seguente query SQL di BigQuery nell'area di testo Editor query:

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

bq

Nel terminale, inserisci il seguente comando bq query per eseguire una query interattiva utilizzando la sintassi 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'

Esegue una query che restituisce i 100 titoli di Wikipedia con il maggior numero di visualizzazioni in un mese specifico e scrive l'output in una tabella temporanea.

Prendi nota del tempo necessario per l'esecuzione della query.

Esegui il deployment di un flusso di lavoro che esegue più query in serie

Una definizione di workflow è costituita da una serie di passaggi descritti utilizzando la sintassi dei workflow. Dopo aver creato un flusso di lavoro, esegui il deployment per renderlo disponibile per l'esecuzione. Il passaggio di deployment convalida anche che il file di origine possa essere eseguito.

Il seguente flusso di lavoro definisce un elenco di cinque tabelle su cui eseguire una query utilizzando il connettore BigQuery di Workflows. Le query vengono eseguite in sequenza, una dopo l'altra, e i titoli più visualizzati di ogni tabella vengono salvati in una mappa dei risultati.

Console

  1. Nella console Google Cloud , vai alla pagina Flussi di lavoro:

    Vai a Flussi di lavoro

  2. Fai clic su Crea.

  3. Inserisci un nome per il nuovo flusso di lavoro, ad esempio workflow-serial-bqjobs.

  4. Scegli una regione appropriata, ad esempio us-central1.

  5. Seleziona il service account che hai creato in precedenza.

    Dovresti aver già concesso i ruoli IAM BigQuery > Utente job BigQuery e Logging > Writer log al service account.

  6. Fai clic su Avanti.

  7. Nell'editor del workflow, inserisci la seguente definizione per il 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. Fai clic su Esegui il deployment.

gcloud

  1. Apri un terminale e crea un file di codice sorgente per il tuo workflow:

    touch workflow-serial-bqjobs.yaml
  2. Copia il seguente flusso di lavoro nel file del codice sorgente:

    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. Esegui il deployment del flusso di lavoro inserendo questo comando:

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

    Sostituisci MY_SERVICE_ACCOUNT@MY_PROJECT.iam.gserviceaccount.com con l'email del account di servizio che hai creato in precedenza.

    Dovresti aver già concesso i ruoli IAM roles/bigquery.jobUser e roles/logging.logWriter al service account.

Esegui il flusso di lavoro ed esegui più query in serie

L'esecuzione di un workflow esegue la definizione attuale del workflow associata al workflow.

Console

  1. Nella console Google Cloud , vai alla pagina Flussi di lavoro:

    Vai a Flussi di lavoro

  2. Nella pagina Workflow, seleziona il workflow workflow-serial-bqjobs per andare alla pagina dei dettagli.

  3. Nella pagina Dettagli workflow, fai clic su Esegui.

  4. Fai di nuovo clic su Esegui.

  5. Visualizza i risultati del flusso di lavoro nel riquadro Output.

gcloud

  1. Apri un terminale.

  2. Esegui il workflow:

     gcloud workflows run workflow-serial-bqjob

L'esecuzione del workflow dovrebbe richiedere circa un minuto o cinque volte il tempo di esecuzione precedente. Il risultato includerà ogni tabella e sarà simile a quanto segue:

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

Esegui il deployment ed esegui un flusso di lavoro che esegue più query in parallelo

Anziché eseguire cinque query in sequenza, puoi eseguirle in parallelo apportando alcune modifiche:

 - runQueries:
    parallel:
        shared: [results]
        for:
            value: table
            in: ${tables}
  • Un passaggio parallel consente a ogni iterazione del ciclo for di essere eseguita in parallelo.
  • La variabile results è dichiarata come shared, il che consente a un ramo di scriverla e di aggiungere il risultato di ogni ramo.

Console

  1. Nella console Google Cloud , vai alla pagina Flussi di lavoro:

    Vai a Flussi di lavoro

  2. Fai clic su Crea.

  3. Inserisci un nome per il nuovo flusso di lavoro, ad esempio workflow-parallel-bqjobs.

  4. Scegli una regione appropriata, ad esempio us-central1.

  5. Seleziona il service account che hai creato in precedenza.

  6. Fai clic su Avanti.

  7. Nell'editor del workflow, inserisci la seguente definizione per il 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. Fai clic su Esegui il deployment.

  9. Nella pagina Dettagli workflow, fai clic su Esegui.

  10. Fai di nuovo clic su Esegui.

  11. Visualizza i risultati del flusso di lavoro nel riquadro Output.

gcloud

  1. Apri un terminale e crea un file di codice sorgente per il tuo workflow:

    touch workflow-parallel-bqjobs.yaml
  2. Copia il seguente flusso di lavoro nel file del codice sorgente:

    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. Esegui il deployment del flusso di lavoro inserendo questo comando:

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

    Sostituisci MY_SERVICE_ACCOUNT@MY_PROJECT.iam.gserviceaccount.com con l'email del account di servizio che hai creato in precedenza.

  4. Esegui il workflow:

     gcloud workflows run workflow-parallel-bqjobs

Il risultato sarà simile all'output precedente, ma l'esecuzione del flusso di lavoro dovrebbe richiedere circa 20 secondi o meno.