Utiliser Spark sur Kubernetes Engine pour traiter des données dans BigQuery

Ce tutoriel explique comment créer et exécuter un pipeline de données qui utilise BigQuery pour stocker des données et Spark sur Google Kubernetes Engine (GKE) pour traiter ces données. Ce pipeline est utile pour les équipes qui ont normalisé leur infrastructure de calcul sur GKE et qui cherchent à transférer leurs workflows existants. Pour la plupart des équipes, l'exécution de Spark sur Cloud Dataproc est le moyen le plus simple et le plus évolutif d'exécuter leurs applications Spark. Pour ce faire, nous évaluons un ensemble de données public BigQuery intitulé données GitHub pour trouver les projets qui bénéficieraient le plus d'une contribution. Pour ce tutoriel, nous partons du principe que vous connaissez bien GKE et Apache Spark. Le diagramme de haut niveau suivant indique les technologies que vous utiliserez.

schéma de l'architecture

De nombreux projets sur GitHub sont écrits en Go, mais peu d'indicateurs signalent aux contributeurs qu'un projet nécessite de l'aide ou à quel emplacement la base de code requiert le plus d'attention.

Dans ce tutoriel, vous allez utiliser les indicateurs suivants pour déterminer si un projet nécessite des contributions :

  • Nombre de questions en suspens
  • Nombre de contributeurs
  • Nombre de fois que les packages d'un projet sont importés par d'autres projets
  • Fréquence des commentaires FIXME ou TODO

Le diagramme suivant représente le pipeline de l'application Spark :

Pipeline d'application Spark

Objectifs

  • Créer un cluster Kubernetes Engine pour exécuter votre application Spark
  • Déployer une application Spark sur Kubernetes Engine
  • Interroger et écrire des tables BigQuery dans l'application Spark
  • Analyser les résultats à l'aide de BigQuery

Coûts

Ce tutoriel utilise des composants facturables de Google Cloud, dont :

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

  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. Assurez-vous que la facturation est activée pour votre projet Cloud. Découvrez comment vérifier que la facturation est activée pour votre projet.

  4. Activer les API Kubernetes Engine and BigQuery.

    Activer les API

Configurer votre environnement

Dans cette section, vous allez configurer les paramètres de projet dont vous avez besoin pour exécuter le tutoriel.

Démarrer une instance Cloud Shell

Ouvrir Cloud Shell

Pour la suite du tutoriel, vous allez utiliser Cloud Shell.

Exécuter le pipeline manuellement

Dans les étapes suivantes, vous allez démarrer le pipeline en demandant à BigQuery d'extraire de la table sample_files tous les fichiers portant l'extension .go. Cette table est un sous-ensemble de [bigquery-public-data:github_repos.files]. L'utilisation du sous-ensemble de données permet d'effectuer un test plus économique.

  1. Dans Cloud Shell, exécutez les commandes suivantes pour créer un ensemble de données et une table dans BigQuery afin de stocker les résultats de la requête intermédiaire :

    export PROJECT=$(gcloud info --format='value(config.project)')
    bq mk --project_id $PROJECT spark_on_k8s_manual
    bq mk --project_id $PROJECT spark_on_k8s_manual.go_files
    
  2. Affichez un échantillon des fichiers Go de l'ensemble de données du dépôt GitHub, puis stockez-les dans une table intermédiaire avec l'option --destination_table :

    export PROJECT=$(gcloud info --format='value(config.project)')
    bq query --project_id $PROJECT --replace \
             --destination_table spark_on_k8s_manual.go_files \
        'SELECT id, repo_name, path FROM
    [bigquery-public-data:github_repos.sample_files]
         WHERE RIGHT(path, 3) = ".go"'
    

    Les chemins de fichiers répertoriés doivent s'afficher ainsi que le dépôt d'où ils proviennent. Exemple :

    Waiting on bqjob_r311c807f17003279_0000015fb8007c47_1 ... (0s) Current status: DONE
    +------------------------------------------+------------------+-------------------------+
    |                    id                    |    repo_name     |          path           |
    +------------------------------------------+------------------+-------------------------+
    | 31a4559c1e636e | mandelsoft/spiff | spiff++/spiff.go        |
    | 15f7611dd21a89 | bep/gr           | examples/router/main.go |
    | 15cbb0b0f096a2 | knq/xo           | internal/fkmode.go      |
    +------------------------------------------+------------------+-------------------------+
    

    La liste de tous les fichiers Go identifiés est maintenant stockée dans la table spark_on_k8s_manual.go_files.

  3. Exécutez la requête suivante pour afficher les 10 premiers caractères de chaque fichier :

    export PROJECT=$(gcloud info --format='value(config.project)')
    bq query --project_id $PROJECT 'SELECT sample_repo_name as
    repo_name, SUBSTR(content, 0, 10) FROM
    [bigquery-public-data:github_repos.sample_contents] WHERE id IN
    (SELECT id FROM spark_on_k8s_manual.go_files)'
    

Exécuter le pipeline avec Spark sur Kubernetes

À présent, vous devez automatiser une procédure semblable avec une application Spark qui exécute des requêtes SQL directement dans BigQuery à l'aide du connecteur spark-bigquery. L'application va ensuite manipuler les résultats et les enregistrer dans BigQuery à l'aide des API Spark SQL et DataFrames.

Créer un cluster Kubernetes Engine

Pour déployer Spark et l'exemple d'application, créez un cluster Kubernetes Engine en exécutant les commandes suivantes :

gcloud config set compute/zone us-central1-f
gcloud container clusters create spark-on-gke --machine-type n1-standard-2

Télécharger l'exemple de code

Clonez le dépôt de l'exemple d'application :

git clone https://github.com/GoogleCloudPlatform/spark-on-k8s-gcp-examples.git
cd spark-on-k8s-gcp-examples/github-insights

Configurer la gestion des identités et des accès

Vous devez créer un compte de service de gestion de l'authentification et des accès (IAM) pour accorder à Spark l'accès à BigQuery.

  1. Créez le compte de service :

    gcloud iam service-accounts create spark-bq --display-name spark-bq
    
  2. Stockez l'adresse e-mail du compte de service et votre ID de projet actuel dans des variables d'environnement en vue d'une utilisation ultérieure :

    export SA_EMAIL=$(gcloud iam service-accounts list --filter="displayName:spark-bq" --format='value(email)')
    export PROJECT=$(gcloud info --format='value(config.project)')
    
  3. L'exemple d'application doit créer et manipuler des ensembles de données et des tables BigQuery, puis supprimer des artefacts de Cloud Storage. Associez les rôles bigquery.dataOwner, bigQuery.jobUser et storage.admin au compte de service :

    gcloud projects add-iam-policy-binding $PROJECT --member serviceAccount:$SA_EMAIL --role roles/storage.admin
    gcloud projects add-iam-policy-binding $PROJECT --member serviceAccount:$SA_EMAIL --role roles/bigquery.dataOwner
    gcloud projects add-iam-policy-binding $PROJECT --member serviceAccount:$SA_EMAIL --role roles/bigquery.jobUser
    
  4. Téléchargez la clé JSON du compte de service, puis enregistrez-la dans un code secret Kubernetes. Vos pilotes et exécuteurs Spark se servent de ce code secret pour s'authentifier auprès de BigQuery :

    gcloud iam service-accounts keys create spark-sa.json --iam-account $SA_EMAIL
    kubectl create secret generic spark-sa --from-file=spark-sa.json
    
  5. Ajoutez des autorisations pour que Spark puisse lancer des tâches dans le cluster Kubernetes.

    kubectl create clusterrolebinding user-admin-binding --clusterrole=cluster-admin --user=$(gcloud config get-value account)
    kubectl create clusterrolebinding --clusterrole=cluster-admin --serviceaccount=default:default spark-admin
    

Configurer et exécuter l'application Spark

À présent, vous devez télécharger, installer et configurer Spark pour exécuter l'exemple d'application Spark dans votre cluster Kubernetes Engine.

  1. Installez Maven, grâce auquel vous gérez le processus de création de l'exemple d'application :

    sudo apt-get install -y maven
  2. Créez le fichier jar de l'exemple d'application :

    mvn clean package
  3. Créez un bucket Cloud Storage pour stocker le fichier jar de l'application et les résultats de votre pipeline Spark :

    export PROJECT=$(gcloud info --format='value(config.project)')
    gsutil mb gs://$PROJECT-spark-on-k8s
    
  4. Importez le fichier de l'application dans le bucket Cloud Storage :

    gsutil cp target/github-insights-1.0-SNAPSHOT-jar-with-dependencies.jar \
                   gs://$PROJECT-spark-on-k8s/jars/
    
  5. Créez un ensemble de données BigQuery :

    bq mk --project_id $PROJECT spark_on_k8s
  6. Téléchargez la distribution officielle Spark 2.3, puis désarchivez-la :

    wget https://archive.apache.org/dist/spark/spark-2.3.0/spark-2.3.0-bin-hadoop2.7.tgz
    tar xvf spark-2.3.0-bin-hadoop2.7.tgz
    cd spark-2.3.0-bin-hadoop2.7
    
  7. Configurez votre application Spark en créant un fichier de propriétés contenant les informations spécifiques à votre projet :

    cat > properties << EOF
    spark.app.name  github-insights
    spark.kubernetes.namespace default
    spark.kubernetes.driverEnv.GCS_PROJECT_ID $PROJECT
    spark.kubernetes.driverEnv.GOOGLE_APPLICATION_CREDENTIALS /mnt/secrets/spark-sa.json
    spark.kubernetes.container.image gcr.io/cloud-solutions-images/spark:v2.3.0-gcs
    spark.kubernetes.driver.secrets.spark-sa  /mnt/secrets
    spark.kubernetes.executor.secrets.spark-sa /mnt/secrets
    spark.driver.cores 0.1
    spark.executor.instances 3
    spark.executor.cores 1
    spark.executor.memory 512m
    spark.executorEnv.GCS_PROJECT_ID    $PROJECT
    spark.executorEnv.GOOGLE_APPLICATION_CREDENTIALS /mnt/secrets/spark-sa.json
    spark.hadoop.google.cloud.auth.service.account.enable true
    spark.hadoop.google.cloud.auth.service.account.json.keyfile /mnt/secrets/spark-sa.json
    spark.hadoop.fs.gs.project.id $PROJECT
    EOF
    
  8. Exécutez l'application Spark sur l'exemple d'ensemble de données GitHub à l'aide des commandes suivantes :

    export KUBERNETES_MASTER_IP=$(gcloud container clusters list --filter name=spark-on-gke --format='value(MASTER_IP)')
    bin/spark-submit \
    --properties-file properties \
    --deploy-mode cluster \
    --class spark.bigquery.example.github.NeedingHelpGoPackageFinder \
    --master k8s://https://$KUBERNETES_MASTER_IP:443 \
    --jars http://central.maven.org/maven2/com/databricks/spark-avro_2.11/4.0.0/spark-avro_2.11-4.0.0.jar \
    gs://$PROJECT-spark-on-k8s/jars/github-insights-1.0-SNAPSHOT-jar-with-dependencies.jar \
    $PROJECT spark_on_k8s $PROJECT-spark-on-k8s --usesample
    
  9. Ouvrez une nouvelle session Cloud Shell en cliquant sur le bouton Ajouter une session Cloud Shell :

    Bouton &quot;Ajouter une session Cloud Shell&quot;

  10. Dans la nouvelle session Cloud Shell, affichez les journaux du pod des pilotes à l'aide de la commande suivante afin de suivre la progression de l'application. Cette dernière prend environ cinq minutes pour s'exécuter.

    kubectl logs -l spark-role=driver
  11. Une fois l'exécution de l'application terminée, vérifiez les 10 packages les plus populaires en exécutant la commande suivante :

    bq query "SELECT * FROM spark_on_k8s.popular_go_packages
    ORDER BY popularity DESC LIMIT 10"
    

Vous pouvez exécuter le même pipeline sur toutes les tables de l'ensemble de données GitHub en supprimant l'option --usesample à l'étape 8. Notez que la taille de l'ensemble de données complet est beaucoup plus grande que celle de l'exemple de données. Par conséquent, vous aurez probablement besoin d'un cluster plus volumineux pour exécuter le pipeline dans un délai raisonnable.

Nettoyer

Pour éviter que les ressources utilisées lors de ce tutoriel soient facturées sur votre compte Google Cloud, supprimez le projet contenant les ressources, ou conservez le projet et supprimez les ressources individuelles.

Une fois le tutoriel terminé, vous pouvez procéder au nettoyage des ressources que vous avez créées afin qu'elles ne soient plus comptabilisées dans votre quota et qu'elles ne vous soient plus facturées. Dans les sections suivantes, nous allons voir comment supprimer ou désactiver ces ressources.

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 Cloud Console, 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.

Étape suivante

  • Découvrez un autre exemple d'utilisation de Spark avec BigQuery et Dataproc.
  • Découvrez ce tutoriel exploitant Cloud Dataproc, BigQuery et Apache Spark ML pour le machine learning.

  • Découvrez des architectures de référence, des diagrammes, des tutoriels et des bonnes pratiques concernant Google Cloud. Consultez notre Centre d'architecture cloud.