Utiliser Bigtable avec Cloud Functions

Objectifs

Rédiger, déployer et déclencher une fonction Cloud HTTP qui accède à Cloud Spanner

Coûts

Cet article fait appel à Bigtable et Cloud Functions, qui sont des composants facturables de Google Cloud.

  • Pour en savoir plus sur le coût d'utilisation de Bigtable, consultez la section Tarifs de Bigtable.

  • Pour en savoir plus sur le coût d'utilisation de Cloud Functions, y compris les appels gratuits, consultez la section Tarifs de Cloud Functions.

Avant de commencer

  1. Dans cet article, nous supposons que vous disposez d'une instance Bigtable nommée test-instance et d'une table nommée test-table. Vous pouvez créer ces ressources en suivant les étapes décrites à la page Créer une table de test. Veillez à supprimer les ressources une fois que vous avez terminé pour éviter des coûts inutiles.

  2. Activez l'API Cloud Functions.

    Activer l'API

  3. Installez et initialisez le SDK Cloud.

    Si le SDK Cloud est déjà installé, mettez-le à jour en exécutant la commande suivante :

    gcloud components update
    
  4. Préparez votre environnement de développement :

Préparer l'application

  1. Clonez le dépôt de l'exemple d'application sur votre ordinateur local :

    Node.js

    git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git

    Vous pouvez également télécharger l'exemple en tant que fichier ZIP et l'extraire.

    Python

    git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git

    Vous pouvez également télécharger l'exemple en tant que fichier ZIP et l'extraire.

    Go

    git clone https://github.com/GoogleCloudPlatform/golang-samples.git

    Vous pouvez également télécharger l'exemple en tant que fichier ZIP et l'extraire.

  2. Ouvrez le répertoire qui contient l'exemple de code Cloud Functions permettant d'accéder à Bigtable :

    Node.js

    cd nodejs-docs-samples/functions/bigtable/

    Python

    cd python-docs-samples/functions/bigtable/

    Go

    cd golang-samples/functions/bigtable/
  3. Consultez l'exemple de code :

    Node.js

    // Imports the Google Cloud client library
    const {Bigtable} = require('@google-cloud/bigtable');
    
    // Instantiates a client
    const bigtable = new Bigtable();
    
    exports.readRows = async (req, res) => {
      // Gets a reference to a Cloud Bigtable instance and database
      const instance = bigtable.instance(req.body.instanceId);
      const table = instance.table(req.body.tableId);
    
      // Execute the query
      try {
        const prefix = 'phone#';
        const rows = [];
        await table
          .createReadStream({
            prefix,
          })
          .on('error', err => {
            res.send(`Error querying Bigtable: ${err}`);
            res.status(500).end();
          })
          .on('data', row => {
            rows.push(
              `rowkey: ${row.id}, ` +
                `os_build: ${row.data['stats_summary']['os_build'][0].value}\n`
            );
          })
          .on('end', () => {
            rows.forEach(r => res.write(r));
            res.status(200).end();
          });
      } catch (err) {
        res.send(`Error querying Bigtable: ${err}`);
        res.status(500).end();
      }
    };
    

    Python

    from google.cloud import bigtable
    from google.cloud.bigtable.row_set import RowSet
    
    client = bigtable.Client()
    
    def bigtable_read_data(request):
        instance = client.instance(request.headers.get("instance_id"))
        table = instance.table(request.headers.get("table_id"))
    
        prefix = 'phone#'
        end_key = prefix[:-1] + chr(ord(prefix[-1]) + 1)
    
        outputs = []
        row_set = RowSet()
        row_set.add_row_range_from_keys(prefix.encode("utf-8"),
                                        end_key.encode("utf-8"))
    
        rows = table.read_rows(row_set=row_set)
        for row in rows:
            output = 'Rowkey: {}, os_build: {}'.format(
                row.row_key.decode('utf-8'),
                row.cells["stats_summary"]["os_build".encode('utf-8')][0]
                .value.decode('utf-8'))
            outputs.append(output)
    
        return '\n'.join(outputs)
    

    Go

    
    // Package bigtable contains an example of using Bigtable from a Cloud Function.
    package bigtable
    
    import (
    	"context"
    	"fmt"
    	"log"
    	"net/http"
    	"sync"
    
    	"cloud.google.com/go/bigtable"
    )
    
    // client is a global Bigtable client, to avoid initializing a new client for
    // every request.
    var client *bigtable.Client
    var clientOnce sync.Once
    
    // BigtableRead is an example of reading Bigtable from a Cloud Function.
    func BigtableRead(w http.ResponseWriter, r *http.Request) {
    	clientOnce.Do(func() {
    		// Declare a separate err variable to avoid shadowing client.
    		var err error
    		client, err = bigtable.NewClient(context.Background(), r.Header.Get("projectID"), r.Header.Get("instanceId"))
    		if err != nil {
    			http.Error(w, "Error initializing client", http.StatusInternalServerError)
    			log.Printf("bigtable.NewClient: %v", err)
    			return
    		}
    	})
    
    	tbl := client.Open(r.Header.Get("tableID"))
    	err := tbl.ReadRows(r.Context(), bigtable.PrefixRange("phone#"),
    		func(row bigtable.Row) bool {
    			osBuild := ""
    			for _, col := range row["stats_summary"] {
    				if col.Column == "stats_summary:os_build" {
    					osBuild = string(col.Value)
    				}
    			}
    
    			fmt.Fprintf(w, "Rowkey: %s, os_build:  %s\n", row.Key(), osBuild)
    			return true
    		})
    
    	if err != nil {
    		http.Error(w, "Error reading rows", http.StatusInternalServerError)
    		log.Printf("tbl.ReadRows(): %v", err)
    	}
    }
    

    La fonction envoie à la table une requête de lecture pour extraire toutes les données stats_summary des lignes ayant comme préfixe de clé de ligne phone. La fonction est exécutée lorsque vous effectuez une requête HTTP sur le point de terminaison de la fonction.

Déployer la fonction

Pour déployer la fonction avec un déclencheur HTTP, exécutez la commande suivante dans le répertoire bigtable :

Node.js

gcloud functions deploy get \
--runtime nodejs14 --trigger-http
Vous pouvez attribuer les valeurs suivantes à l'option --runtime, afin de spécifier votre version préférée de Node.js :
  • nodejs16 (version bêta)
  • nodejs14 (recommandé)
  • nodejs12
  • nodejs10

Python

gcloud functions deploy bigtable_read_data \
--runtime python39 --trigger-http
Vous pouvez attribuer les valeurs suivantes à l'option --runtime, afin de spécifier votre version préférée de Python :
  • python39 (recommandé)
  • python38
  • python37

Go

gcloud functions deploy HelloBigtable \
--runtime go113 --trigger-http
Vous pouvez attribuer les valeurs suivantes à l'option --runtime, afin de spécifier votre version préférée de Go :
  • go116 (version bêta)
  • go113 (recommandé)
  • go111

Le déploiement de la fonction peut prendre jusqu'à deux minutes.

Une fois le déploiement de votre fonction terminé, la valeur url est renvoyée. Vous l'utiliserez lorsque vous déclencherez la fonction.

Vous pouvez afficher les fonctions que vous avez déployées sur la page Cloud Functions de Google Cloud Console. Cette page vous permet également de créer et de modifier des fonctions, et d'obtenir des détails ou des diagnostics sur vos fonctions.

Déclencher la fonction

Envoyez une requête HTTP à votre fonction :

Node.js

curl "https://REGION-PROJECT_ID.cloudfunctions.net/get" -H "instance_id: test-instance" -H "table_id: test-table"

Python

curl "https://REGION-PROJECT_ID.cloudfunctions.net/bigtable_read_data" -H "instance_id: test-instance" -H "table_id: test-table"

Go

curl "https://REGION-PROJECT_ID.cloudfunctions.net/HelloBigtable" -H "instance_id: test-instance" -H "table_id: test-table"

REGION et PROJECT_ID correspondent aux valeurs visibles dans votre terminal une fois le déploiement de la fonction terminé. Vous devriez voir apparaître en sortie les résultats de la requête de lecture.

Vous pouvez également accéder à l'URL de la fonction dans votre navigateur pour visualiser le résultat de votre requête de lecture.

Nettoyer

Afin d'éviter que des frais supplémentaires ne soient facturés sur votre compte Google Cloud pour les ressources Bigtable et Cloud Functions utilisées dans ce tutoriel, effectuez les opérations suivantes :

  1. Supprimez l'instance :

    gcloud bigtable instances delete test-instance
    
  2. Supprimez la fonction que vous avez déployée :

    Node.js

    gcloud functions delete get -H "instance_id: test-instance" -H "table_id: test-table"

    Python

    gcloud functions delete bigtable_read_data -H "instance_id: test-instance" -H "table_id: test-table"

    Go

    gcloud functions delete HelloBigtable -H "instance_id: test-instance" -H "table_id: test-table"

Étape suivante