Migration de bout en bout : base de données Cloud SQL vers Cloud Spanner (GoogleSQL)

1. Avant de commencer

Cet atelier de programmation vous guide dans la migration d'une base de données MySQL unique sur Cloud SQL vers une base de données Cloud Spanner avec le dialecte GoogleSQL. L'accent est mis sur le flux de migration de bout en bout fondamental, qui illustre les étapes de base. Vous utiliserez les services Google Cloud, y compris Spanner Migration Tool (SMT), Dataflow, Datastream, PubSub et Google Cloud Storage.

Vous y découvrirez :

  • Comment configurer des exemples d'instances Cloud SQL et Cloud Spanner.
  • Découvrez comment convertir un schéma Cloud SQL MySQL en schéma compatible avec Spanner à l'aide de l'outil de migration Spanner (SMT).
  • Découvrez comment effectuer la migration de données en masse de Cloud SQL vers Cloud Spanner à l'aide de Dataflow.
  • Configurer la réplication continue (CDC) de Cloud SQL vers Cloud Spanner à l'aide de Datastream et Dataflow
  • Configurer la réplication inversée de Cloud Spanner vers Cloud SQL

Ce que cet atelier de programmation ne couvre PAS :

  • Migrations à partir d'instances partitionnées.
  • Transformations complexes des données pendant la migration
  • Gestion avancée des erreurs ou files d'attente de lettres mortes (DLQ).
  • Réglage des performances de la migration.
  • Migration d'application : cet atelier de programmation se concentre sur la couche de base de données (schéma et données). Il ne couvre pas le processus opérationnel de redéploiement ou de migration de vos services d'application.

Prérequis

  • Un projet Google Cloud avec facturation activée.
  • Des autorisations IAM suffisantes pour activer les API et créer/gérer les ressources Cloud SQL, Spanner, Dataflow, Datastream et GCS. Bien que le rôle Owner du projet soit le plus simple pour un atelier de programmation, des rôles plus spécifiques seront abordés dans la section "Configuration de l'environnement".
  • Un navigateur Web, tel que Google Chrome.
  • Connaissances de base de la console Google Cloud et des outils de ligne de commande tels que gcloud.
  • Accès à un environnement shell. Nous vous recommandons d'utiliser Cloud Shell, car il inclut gcloud.

Pour en savoir plus sur la configuration ci-dessus, consultez la section "Configuration de l'environnement".

2. Comprendre le processus de migration

La migration d'une base de données implique la migration des données de votre instance de base de données Cloud SQL source vers une instance Spanner. Cette section décrit l'architecture et les principaux outils utilisés pour la migration.

Architecture du flux de migration

Le processus de migration comporte les étapes suivantes :

1. Conversion de schéma :

  • Objectif : convertir le schéma de la base de données source en un schéma Cloud Spanner compatible.
  • Outil : outil de migration Spanner (SMT, Spanner Migration Tool)
  • Processus : SMT analyse le schéma de la base de données source et génère le langage de définition de données (DDL) Spanner équivalent. Dans l'instance Spanner cible, une base de données est créée et le DDL est ensuite appliqué automatiquement.

2. Migration groupée des données :

  • Objectif : effectuer un chargement complet initial des données existantes de la base de données source vers les tables Spanner provisionnées.
  • Outil : Dataflow, à l'aide du modèle Sourcedb to Spanner fourni par Google.
  • Processus : ce job Dataflow lit toutes les données des tables sources spécifiées et les écrit dans les tables Spanner correspondantes. Cette opération est effectuée après la création du schéma Spanner.

3. Migration à chaud (CDC) :

  • Objectif : capturer et appliquer les modifications en cours de la base de données source à Cloud Spanner en temps quasi réel, en minimisant les temps d'arrêt pendant la migration.
  • Outils :
  • Datastream : capture les modifications (insertions, mises à jour, suppressions) de la base de données source et les écrit dans Cloud Storage (GCS).
  • Dataflow : utilise le modèle Datastream to Spanner pour lire les événements de modification depuis GCS et les appliquer à Cloud Spanner.

4. Réplication inverse :

  • Objectif : répliquer les modifications de données de Cloud Spanner vers la base de données source. Cela peut être utile pour les stratégies de secours, les migrations par étapes ou le maintien d'une réplique dans la source pour des cas d'utilisation spécifiques.
  • Outil : Dataflow, à l'aide du modèle Spanner to SourceDb.
  • Processus : cette tâche utilise les flux de modification Spanner pour capturer les modifications apportées à Spanner et les réécrire dans l'instance de base de données source.

Le schéma suivant illustre les composants et le flux de données :

b9e12d4151bf3bb7.png

Terminologie clé :

  • Outil de migration Spanner (SMT) : outil utilisé pour évaluer les schémas MySQL, suggérer des schémas Spanner équivalents et générer le langage de définition de données (LDD) Spanner.
  • Langage de définition de données (LDD) : instructions utilisées pour définir et modifier la structure de la base de données, telles que les instructions CREATE TABLE. SMT génère le LDD Spanner en fonction du schéma Cloud SQL.
  • Dataflow : service de traitement de données sans serveur et entièrement géré. Dans cet atelier de programmation, il est utilisé pour exécuter des modèles fournis par Google pour le transfert de données en masse, l'application des modifications Datastream et la réplication inversée.
  • Datastream : service de capture et de réplication de données modifiées (CDC) sans serveur. Dans cet atelier de programmation, il est utilisé pour diffuser les modifications de Cloud SQL dans Cloud Storage.
  • Flux de modifications Spanner : fonctionnalité Spanner qui permet de diffuser en temps réel les modifications apportées aux données (insertions, mises à jour, suppressions). Elle est utilisée comme source pour la réplication inversée.
  • Pub/Sub : service de messagerie utilisé pour dissocier les services qui produisent des événements de ceux qui les traitent. Dans cet atelier de programmation, il déclenche Dataflow pour traiter les mises à jour chaque fois que Datastream importe de nouveaux fichiers de modifications dans Cloud Storage.

3. Configuration de l'environnement

Avant de pouvoir commencer la migration, vous devez configurer votre projet Google Cloud et activer les services nécessaires.

1. Sélectionner ou créer un projet Google Cloud

Pour utiliser les services de cet atelier de programmation, vous devez disposer d'un projet Google Cloud pour lequel la facturation est activée.

  1. Dans la console Google Cloud, accédez à la page de sélection du projet : Accéder au sélecteur de projet
  2. Sélectionnez ou créez un projet Google Cloud.
  3. Assurez-vous que la facturation est activée pour votre projet. Découvrez comment vérifier que la facturation est activée pour votre projet.

2. Ouvrir Cloud Shell

Cloud Shell est un environnement de ligne de commande exécuté dans Google Cloud. Il est préchargé avec la CLI gcloud et d'autres outils dont vous avez besoin.

  • Cliquez sur le bouton Activer Cloud Shell en haut à droite de la console Google Cloud.
  • Une session Cloud Shell s'ouvre dans un nouveau cadre en bas de la console et affiche une invite de ligne de commande.

22d57633bc12106d.png

3. Définir les variables de projet et d'environnement

Dans Cloud Shell, configurez des variables d'environnement pour l'ID de votre projet et la région que vous utiliserez.

export PROJECT_ID=$(gcloud config get-value project)
export REGION="us-central1" # Or your preferred region
export ZONE="us-central1-a" # Or a zone within your selected region

gcloud config set project $PROJECT_ID
gcloud config set compute/region $REGION
gcloud config set compute/zone $ZONE

echo "Project ID: $PROJECT_ID"
echo "Region: $REGION"
echo "Zone: $ZONE"

4. Activer les API Google Cloud requises

Activez les API nécessaires pour Cloud Spanner, Dataflow, Datastream et d'autres services associés.

gcloud services enable \
  spanner.googleapis.com \
  dataflow.googleapis.com \
  datastream.googleapis.com \
  pubsub.googleapis.com \
  storage.googleapis.com \
  compute.googleapis.com \
  sqladmin.googleapis.com \
  servicenetworking.googleapis.com \
  cloudresourcemanager.googleapis.com

L'exécution de cette commande peut prendre quelques minutes.

5. Configurer les autorisations du compte de service

Les jobs Dataflow et Datastream nécessitent des autorisations spécifiques pour interagir avec d'autres services Google Cloud. Les jobs Dataflow de cet atelier de programmation utiliseront le compte de service Compute Engine par défaut.

Tout d'abord, obtenez votre numéro de projet :

export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")
export SA_EMAIL="${PROJECT_NUMBER}-compute@developer.gserviceaccount.com"

Attribuez maintenant les rôles IAM requis au compte de service Compute Engine par défaut :

# Role for Dataflow to run jobs
gcloud projects add-iam-policy-binding $PROJECT_ID \
    --member="serviceAccount:${SA_EMAIL}" \
    --role="roles/dataflow.admin" \
    --condition=None

# Roles for Dataflow workers
gcloud projects add-iam-policy-binding $PROJECT_ID \
    --member="serviceAccount:${SA_EMAIL}" \
    --role="roles/dataflow.worker" \
    --condition=None

# Role to connect to Cloud SQL instance
gcloud projects add-iam-policy-binding $PROJECT_ID \
    --member="serviceAccount:${SA_EMAIL}" \
    --role="roles/cloudsql.client" \
    --condition=None

# Role to read/write from Cloud Spanner
gcloud projects add-iam-policy-binding $PROJECT_ID \
    --member="serviceAccount:${SA_EMAIL}" \
    --role="roles/spanner.databaseUser" \
    --condition=None

# Role to access GCS buckets (Datastream output, Dataflow temp, JDBC driver)
gcloud projects add-iam-policy-binding $PROJECT_ID \
    --member="serviceAccount:${SA_EMAIL}" \
    --role="roles/storage.objectAdmin" \
    --condition=None

# Roles for Datastream and Pub/Sub (for CDC)
gcloud projects add-iam-policy-binding $PROJECT_ID \
    --member="serviceAccount:${SA_EMAIL}" \
    --role="roles/datastream.viewer"

gcloud projects add-iam-policy-binding $PROJECT_ID \
    --member="serviceAccount:${SA_EMAIL}" \
    --role="roles/pubsub.subscriber"

6. Créer un bucket Cloud Storage

Créez un bucket GCS dans la même région que vos autres ressources. Ce bucket stockera le pilote JDBC et la sortie Datastream, et sera utilisé par Dataflow pour les fichiers temporaires.

export BUCKET_NAME="migration-${PROJECT_ID}-bucket"
gcloud storage buckets create gs://$BUCKET_NAME --location=$REGION
echo "Created bucket: gs://$BUCKET_NAME"

7. Installer l'outil de migration Spanner (SMT)

Assurez-vous que l'outil de migration Spanner (SMT) est installé dans votre environnement Cloud Shell.

sudo apt-get update && sudo apt-get install google-cloud-cli-spanner-migration-tool

# Verify installation 
gcloud alpha spanner migrate web --help

Cette commande doit afficher des informations d'aide pour l'interface Web SMT, ce qui confirme que le composant gcloud est installé. Cet atelier de programmation utilisera les fonctionnalités de CLI de SMT, qui font partie du même composant.

4. Configurer la base de données Cloud SQL source

Dans cette section, vous allez créer et configurer une instance Cloud SQL pour MySQL avec une adresse IP publique qui servira de base de données source.

1. Créer une instance Cloud SQL pour MySQL

Exécutez la commande gcloud suivante dans Cloud Shell pour créer une instance MySQL 8.0. La journalisation binaire est activée (obligatoire pour Datastream) et l'instance est configurée avec une adresse IP publique.

export SQL_INSTANCE_NAME="source-mysql-instance"
export DB_ROOT_PASSWORD="Welcome@1" # Replace with a strong password if you prefer

gcloud sql instances create $SQL_INSTANCE_NAME \
  --database-version=MYSQL_8_0 \
  --tier=db-n1-standard-2 \
  --region=$REGION \
  --root-password=$DB_ROOT_PASSWORD \
  --enable-bin-log \
  --assign-ip
  • --enable-bin-log : obligatoire pour que Datastream capture les modifications.
  • --assign-ip : garantit que l'instance reçoit une adresse IP publique.

La création de l'instance prend quelques minutes. Vous pouvez vérifier si votre instance a été créée sur la page "Instances Cloud SQL".

2. Configurer les réseaux autorisés

Pour vous connecter à l'instance via une adresse IP publique, vous devez ajouter des adresses IP à la liste "Réseaux autorisés".

Obtenez l'adresse IP de Cloud Shell :

export CLOUD_SHELL_IP=$(curl -s ipinfo.io/ip)
echo "Your Cloud Shell IP: $CLOUD_SHELL_IP"

Autoriser l'adresse IP Cloud Shell et l'accès ouvert

La commande suivante ajoute votre adresse IP Cloud Shell. Il ajoute également 0.0.0.0/0, qui autorise l'accès depuis n'importe quelle adresse IP. Cela est nécessaire pour simplifier les connexions à partir des nœuds de calcul Dataflow sans configurations réseau complexes.

gcloud sql instances patch $SQL_INSTANCE_NAME \
  --authorized-networks="${CLOUD_SHELL_IP}/32,0.0.0.0/0"

3. Se connecter à l'instance Cloud SQL depuis Cloud Shell

Récupérer l'adresse IP publique attribuée

export SQL_INSTANCE_IP=$(gcloud sql instances list --filter="name=$SQL_INSTANCE_NAME" --format="value(PRIMARY_ADDRESS)") 
echo "Cloud SQL Public IP: $SQL_INSTANCE_IP"

Cette adresse IP sera utilisée pour la connexion.

Se connecter à l'instance Cloud SQL depuis Cloud Shell

Utilisez le client mysql standard pour vous connecter à l'aide de l'adresse IP publique obtenue :

mysql -h $SQL_INSTANCE_IP -u root -p

Lorsque vous y êtes invité, saisissez le mot de passe racine que vous avez défini (Welcome@1). Vous devriez maintenant voir une invite mysql>.

4. Créer une base de données et des exemples de données

Exécutez les commandes SQL suivantes dans l'invite mysql> :

CREATE DATABASE music_db;
USE music_db;

CREATE TABLE Singers (
    SingerId   BIGINT NOT NULL,
    FirstName  VARCHAR(1024),
    LastName   VARCHAR(1024),
    BirthDate  DATE,
    AlbumCount BIGINT,
    PRIMARY KEY (SingerId)
);

CREATE TABLE Albums (
    SingerId     BIGINT NOT NULL,
    AlbumId      BIGINT NOT NULL,
    AlbumTitle   VARCHAR(1024),
    ReleaseDate  DATE,
    PRIMARY KEY (SingerId, AlbumId),
    CONSTRAINT FK_Albums_Singers FOREIGN KEY (SingerId) REFERENCES Singers (SingerId)
);

INSERT INTO Singers (SingerId, FirstName, LastName, BirthDate, AlbumCount) VALUES
(1, 'Marc', 'Richards', '1970-09-03', 2),
(2, 'Catalina', 'Smith', '1990-08-17', 1),
(3, 'Alice', 'Trentor', '1991-10-02', 3);

INSERT INTO Albums (SingerId, AlbumId, AlbumTitle, ReleaseDate) VALUES
(1, 1, 'Total Junk', '2014-03-15'),
(1, 2, 'Go Go Go', '2016-11-01'),
(2, 1, 'Green', '2018-02-28'),
(3, 1, 'Blue', '2019-01-10'),
(3, 2, 'Red', '2020-05-22'),
(3, 3, 'Purple', '2022-11-11');

Le fichier de vidage pour le schéma ci-dessus est disponible sur cette page.

5. Vérifier les données

Vérifiez rapidement que les données sont présentes :

SELECT 'Singers music_db' as tbl, COUNT(*) FROM music_db.Singers
UNION ALL
SELECT 'Albums music_db', COUNT(*) FROM music_db.Albums;

EXIT;

Vous devriez voir le nombre d'entrées pour chaque table.

+------------------+----------+
| tbl              | COUNT(*) |
+------------------+----------+
| Singers music_db |        3 |
| Albums music_db  |        6 |
+------------------+----------+

5. Configurer Cloud Spanner

Vous allez maintenant configurer l'instance Cloud Spanner cible vers laquelle les données seront migrées.

1. Créer une instance Cloud Spanner

Créez une instance Cloud Spanner dans la même région que votre instance Cloud SQL. Cette commande crée une petite instance adaptée à cet atelier de programmation, en utilisant 100 unités de traitement.

export SPANNER_INSTANCE_NAME="target-spanner-instance"
export SPANNER_DATABASE_NAME="music-db-migrated"
export SPANNER_CONFIG="regional-${REGION}"

gcloud spanner instances create $SPANNER_INSTANCE_NAME \
  --config=$SPANNER_CONFIG \
  --description="Target Spanner Instance" \
  --processing-units=100

La création d'une instance peut prendre une ou deux minutes.

6. Convertir le schéma à l'aide de l'outil de migration Spanner (SMT)

Utilisez l'interface de ligne de commande SMT pour analyser la base de données MySQL (music_db) et générer le langage de définition de schéma Spanner (DDL). Étant donné que l'instance Cloud SQL est configurée avec une adresse IP publique et les réseaux autorisés appropriés, SMT peut se connecter directement.

1. Préparer l'environnement pour SMT

Vérifiez que les variables d'environnement nécessaires sont définies à partir des étapes précédentes :

echo "Cloud SQL Instance Public IP: $SQL_INSTANCE_IP" 
echo "Cloud SQL Root Password: $DB_ROOT_PASSWORD" 
echo "Spanner Instance: $SPANNER_INSTANCE_NAME" 
echo "Spanner Database: $SPANNER_DATABASE_NAME" 
echo "Project ID: $PROJECT_ID"

2. Exécuter la conversion de schéma pour music_db

Exécutez la commande SMT schema en vous connectant directement à l'adresse IP publique Cloud SQL :

gcloud alpha spanner migrate schema \
--source=mysql \
--source-profile="host=${SQL_INSTANCE_IP},port=3306,user=root,password=${DB_ROOT_PASSWORD},dbName=music_db" \
--target-profile="project=${PROJECT_ID},instance=${SPANNER_INSTANCE_NAME},dbName=${SPANNER_DATABASE_NAME}" \
--prefix="music-db"

Cette commande se connecte à l'instance Cloud SQL via le proxy et génère des fichiers de schéma préfixés par music-db.

3. Examiner les fichiers générés

SMT crée quelques fichiers dans votre répertoire actuel. Voici les principaux :

  • music-db.schema.ddl.txt : instructions LDD Spanner générées.
  • music-db-.overrides.json : fichier de remplacement du schéma contenant les modifications manuelles du mappage.
  • music-db.session.json : fichier de session de la migration du schéma.
  • music-db.report.txt : rapport d'évaluation de la conversion du schéma.

Vous pouvez les lister à l'aide de ls music-db-*.

4. Vérifier le schéma dans Cloud Spanner

Vérifiez que les tables ont été créées dans la base de données Spanner.

gcloud spanner databases execute-sql $SPANNER_DATABASE_NAME \
  --instance=$SPANNER_INSTANCE_NAME \
  --sql="SELECT table_name FROM information_schema.tables WHERE table_schema = '' ORDER BY table_name"

Vous devriez obtenir le résultat suivant :

table_name: Albums
table_name: Singers

Facultatif : Si vous souhaitez vérifier le DDL Spanner, exécutez la commande suivante :

gcloud spanner databases ddl describe $SPANNER_DATABASE_NAME \
  --instance=$SPANNER_INSTANCE_NAME

7. Initialiser la capture de données modifiées (CDC)

Dans cette section, vous allez configurer l'enregistreur pour votre migration. En configurant Datastream et Pub/Sub avant le début du chargement groupé des données, vous vous assurez que chaque modification apportée à la base de données source est capturée et mise en file d'attente, ce qui évite toute perte de données pendant la transition. Cette configuration est requise pour la migration en direct.

1. Créer des profils de connexion Datastream

Profil source (Cloud SQL)

Ce profil se connecte à l'adresse IP publique de l'instance Cloud SQL. Datastream utilisera une liste d'autorisation d'adresses IP pour la connectivité.

export SQL_CP_NAME="mysql-src-cp"
gcloud datastream connection-profiles create $SQL_CP_NAME \
  --location=$REGION \
  --type=mysql \
  --mysql-hostname=$SQL_INSTANCE_IP \
  --mysql-port=3306 \
  --mysql-username=root \
  --mysql-password=$DB_ROOT_PASSWORD \
  --display-name="Cloud SQL Source - Public IP"

Remarque : Cette connexion repose sur les réseaux autorisés de l'instance Cloud SQL qui permettent l'accès. Comme configuré précédemment avec 0.0.0.0/0, les adresses IP publiques de Datastream peuvent se connecter. Dans un environnement de production, vous devez remplacer 0.0.0.0/0 par les plages d'adresses IP spécifiques à votre région listées dans Listes d'autorisation d'adresses IP et régions Datastream.

Profil de destination (Cloud Storage)

Pointe vers la racine de votre bucket.

export GCS_CP_NAME="gcs-dest-cp"
gcloud datastream connection-profiles create $GCS_CP_NAME \
  --location=$REGION \
  --type=google-cloud-storage \
  --bucket=$BUCKET_NAME \
  --root-path=/ \
  --display-name="GCS Destination" --force

2. Créer un flux Datastream

Créez le flux à répliquer à partir de music_db.

export STREAM_NAME="mysql-to-spanner-stream"
export GCS_STREAM_PATH="data/${STREAM_NAME}"

gcloud datastream streams create $STREAM_NAME \
  --location=$REGION \
  --display-name="MySQL to Spanner CDC Stream" \
  --source=$SQL_CP_NAME \
  --destination=$GCS_CP_NAME \
  --mysql-source-config=<(echo "
includeObjects:
  mysqlDatabases:
  - database: 'music_db'
") \
  --gcs-destination-config=<(echo "
path: ${GCS_STREAM_PATH}
fileRotationMb: 5
fileRotationInterval: 15s
avroFileFormat: {}
") \
  --backfill-none
  • Datastream écrira les fichiers sous gs://${BUCKET_NAME}/${GCS_STREAM_PREFIX}/
  • Datastream écrira les fichiers au format Avro. Lors de l'exécution de la commande de migration en direct, nous spécifierons que inputFileFormat doit être défini sur "avro" afin que le pipeline puisse traiter correctement le fichier.
  • L'utilisation de paramètres de rotation de fichiers plus petits permet de voir les modifications plus rapidement dans l'atelier de programmation.

L'exécution de cette commande peut prendre un certain temps. Vérifiez l'état : gcloud datastream streams describe $STREAM_NAME --location=$REGION.

3. Démarrer le flux Datastream

gcloud datastream streams update $STREAM_NAME \
  --location=$REGION \
  --state=RUNNING

Vérifiez l'état : gcloud datastream streams describe $STREAM_NAME --location=$REGION.. L'état sera d'abord STARTING, puis deviendra RUNNING au bout de quelques temps. Ne passez à l'étape suivante qu'après avoir vérifié qu'il est à l'état RUNNING.

4. Configurer Pub/Sub pour les notifications GCS

Créez un sujet Pub/Sub :

export PUBSUB_TOPIC="datastream-gcs-updates"
gcloud pubsub topics create $PUBSUB_TOPIC

Créer une notification GCS

Notification lors de la création d'un objet sous le préfixe data/.

gcloud storage buckets notifications create gs://${BUCKET_NAME} --topic=projects/$PROJECT_ID/topics/$PUBSUB_TOPIC --payload-format=json --object-prefix=data/

Créer un abonnement Pub/Sub

Incluez le délai de confirmation recommandé.

export PUBSUB_SUBSCRIPTION="datastream-gcs-sub"
gcloud pubsub subscriptions create $PUBSUB_SUBSCRIPTION \
  --topic=$PUBSUB_TOPIC \
  --ack-deadline=600

8. Migrer des données de Cloud SQL vers Spanner de manière groupée

Maintenant que le schéma Spanner est en place, vous allez copier les données existantes de votre base de données music_db Cloud SQL vers Cloud Spanner. Vous allez utiliser le modèle Flex Dataflow Sourcedb to Spanner, conçu pour copier des données en masse depuis des bases de données accessibles via JDBC vers Spanner.

1. Exécuter le job Dataflow de migration groupée pour music_db

Exécutez la commande suivante dans Cloud Shell pour démarrer le job Dataflow. Cette commande utilise la commande gcloud dataflow flex-template run, qui fait référence au modèle fourni par Google pour les migrations JDBC vers Spanner par lot.

export JOB_NAME_MUSIC="mysql-music-db-to-spanner-bulk-$(date +%Y%m%d-%H%M%S)"
export MUSIC_DB_JDBC_URL="jdbc:mysql://${SQL_INSTANCE_IP}:3306/music_db"
export OUTPUT_DIR="gs://${BUCKET_NAME}/bulk-migration-output"

gcloud dataflow flex-template run $JOB_NAME_MUSIC \
  --project=$PROJECT_ID \
  --region=$REGION \
--template-file-gcs-location="gs://dataflow-templates-${REGION}/latest/flex/Sourcedb_to_Spanner_Flex" \
--max-workers=2 \
--num-workers=1 \
--worker-machine-type=n2-highmem-8 \
  --parameters \
sourceConfigURL="$MUSIC_DB_JDBC_URL",\
instanceId="$SPANNER_INSTANCE_NAME",\
databaseId="$SPANNER_DATABASE_NAME",\
projectId="$PROJECT_ID",\
outputDirectory="$OUTPUT_DIR/music_db",\
username="root",\
password="$DB_ROOT_PASSWORD",\
jdbcDriverClassName="com.mysql.cj.jdbc.Driver",\
jdbcDriverJars="gs://${BUCKET_NAME}/lib/mysql-connector-j-8.0.33.jar",\
spannerHost="https://batch-spanner.googleapis.com"

Explication des paramètres clés :

  • sourceConfigURL : chaîne de connexion JDBC pour la source music_db.
  • instanceId, databaseId, projectId : spécifie l'instance et la base de données Cloud Spanner cibles.
  • outputDirectory : chemin d'accès Cloud Storage où Dataflow écrira des informations sur les enregistrements qui n'ont pas pu être migrés.
  • jdbcDriverClassName : spécifie le pilote MySQL JDBC.
  • jdbcDriverJars : chemin d'accès GCS au fichier JAR du pilote JDBC intermédiaire.
  • spannerHost : utilise le point de terminaison optimisé par lot pour les écritures Spanner.
  • maxWorkers, numWorkers : contrôle la mise à l'échelle du job Dataflow. Faible pour ce petit ensemble de données.

Remarque sur le réseau : Ce job se connecte à l'instance Cloud SQL via son adresse IP publique. Cela est possible, car vous avez précédemment ajouté 0.0.0.0/0 aux réseaux autorisés de l'instance. Cela permet aux VM de nœud de calcul Dataflow, qui disposent d'adresses IP externes, d'accéder à la base de données.

2. Surveiller le job Dataflow

Vous pouvez suivre la progression du job dans la console Google Cloud :

  1. Accédez à la page "Jobs Dataflow" : Accéder à la page "Jobs Dataflow"
  2. Localisez le job nommé mysql-music-db-to-spanner-bulk-... et cliquez dessus.
  3. Observez le graphique et les métriques du job. Attendez que l'état du job passe à Réussi. Cette opération devrait prendre environ 5 à 15 minutes.

ebbb94c0db535809.png

  • Si le job rencontre des problèmes, consultez l'onglet Journaux sur la page des détails du job Dataflow pour obtenir des messages d'erreur.
  • Les métriques de job fournissent plus d'informations sur la progression du job et la consommation de ressources, comme le débit et l'utilisation du processeur.

3. Vérifier les données dans Cloud Spanner

Une fois le job Dataflow terminé, vérifiez que les données ont été copiées dans les tables Spanner. Utilisez gcloud pour interroger la base de données Spanner :

# Verify row counts
gcloud spanner databases execute-sql $SPANNER_DATABASE_NAME --instance=$SPANNER_INSTANCE_NAME --sql="SELECT COUNT(*) as row_count FROM Singers" 
# Expected output: 3

gcloud spanner databases execute-sql $SPANNER_DATABASE_NAME --instance=$SPANNER_INSTANCE_NAME --sql="SELECT COUNT(*) as row_count FROM Albums" 
# Expected output: 6 

# Inspect some data 
gcloud spanner databases execute-sql $SPANNER_DATABASE_NAME --instance=$SPANNER_INSTANCE_NAME --sql="SELECT SingerId, FirstName, LastName FROM Singers ORDER BY SingerId"

Résultat attendu :

row_count: 3
row_count: 6
SingerId: 1
FirstName: Marc
LastName: Richards

SingerId: 2
FirstName: Catalina
LastName: Smith

SingerId: 3
FirstName: Alice
LastName: Trentor

Le chargement groupé initial des données de Cloud SQL vers Cloud Spanner est maintenant terminé. L'étape suivante consiste à configurer la réplication en direct pour capturer les modifications en cours.

9. Démarrer la migration à chaud (CDC)

Maintenant que le chargement des données en masse est terminé, vous allez configurer un flux de réplication continue à l'aide de Datastream pour capturer les événements de capture des données modifiées (CDC, Change Data Capture) à partir de Cloud SQL, ainsi qu'un job de flux de données Dataflow pour appliquer ces modifications à Cloud Spanner en temps quasi réel.

1. Exécuter le job Dataflow de migration à chaud

Lancez le job Dataflow de streaming pour lire les données depuis GCS et les écrire dans Spanner. Ce modèle utilise les notifications GCS Pub/Sub pour traiter instantanément les nouveaux fichiers.

export JOB_NAME_CDC="datastream-to-spanner-cdc-$(date +%Y%m%d-%H%M%S)"
export DLQ_DIR="gs://${BUCKET_NAME}/dlq"

gcloud dataflow flex-template run $JOB_NAME_CDC \
  --project=$PROJECT_ID \
  --region=$REGION \
--worker-machine-type=n2-highmem-8 \
--template-file-gcs-location="gs://dataflow-templates-${REGION}/latest/flex/Cloud_Datastream_to_Spanner" \
  --parameters \
gcsPubSubSubscription="projects/${PROJECT_ID}/subscriptions/${PUBSUB_SUBSCRIPTION}",\
instanceId="$SPANNER_INSTANCE_NAME",\
databaseId="$SPANNER_DATABASE_NAME",\
projectId="$PROJECT_ID",\
inputFileFormat="avro",\
deadLetterQueueDirectory="$DLQ_DIR",\
streamName="projects/${PROJECT_ID}/locations/${REGION}/streams/${STREAM_NAME}"

Paramètres clés

  • gcsPubSubSubscription : abonnement Pub/Sub qui écoute les notifications de nouveaux fichiers provenant de GCS. Cela permet au job de traiter les modifications instantanément à mesure que Datastream les écrit.
  • inputFileFormat="avro" : indique à Dataflow qu'il doit s'attendre à recevoir des fichiers Avro de Datastream. Elle doit correspondre à la configuration de la destination Datastream (par exemple, avroFileFormat ou jsonFileFormat).
  • deadLetterQueueDirectory : chemin d'accès GCS où le job stocke les enregistrements qui n'ont pas pu être traités (par exemple, en raison d'incompatibilités de schéma) pour un examen manuel ultérieur.
  • streamName : chemin d'accès complet à la ressource du flux Datastream, qui permet au job Dataflow de suivre l'état de la réplication et les métadonnées.

Surveillez le démarrage du job dans la console des jobs Dataflow.

2. Tester la migration à chaud

Appliquez des modifications à la source Cloud SQL music_db pour tester le pipeline CDC.

Connectez-vous à Cloud SQL :

mysql -h $SQL_INSTANCE_IP -u root -p

Saisissez le mot de passe (Welcome@1), puis sélectionnez la base de données :

USE music_db;

-- INSERT
INSERT INTO Singers (SingerId, FirstName, LastName, BirthDate, AlbumCount) VALUES (4, 'Elena', 'Nadal', '1985-05-30', 0);
SELECT * FROM Singers WHERE SingerId = 4;

-- UPDATE
UPDATE Singers SET LastName = 'Richards-Smith' WHERE SingerId = 1;
SELECT * FROM Singers WHERE SingerId = 1;

-- DELETE
DELETE FROM Albums WHERE SingerId = 2; 
DELETE FROM Singers WHERE SingerId = 2;
SELECT * FROM Singers WHERE SingerId = 2;

EXIT;

Validation dans Spanner (après quelques instants) :

# Verify INSERT: This should return the new row for Elena Nadal.
gcloud spanner databases execute-sql $SPANNER_DATABASE_NAME \
  --instance=$SPANNER_INSTANCE_NAME \
  --sql="SELECT * FROM Singers WHERE SingerId = 4"

# Verify UPDATE: This should show LastName as Richards-Smith.
gcloud spanner databases execute-sql $SPANNER_DATABASE_NAME \
  --instance=$SPANNER_INSTANCE_NAME \
  --sql="SELECT SingerId, FirstName, LastName FROM Singers WHERE SingerId = 1"

# Verify DELETE: This should now return 0 rows.
gcloud spanner databases execute-sql $SPANNER_DATABASE_NAME \
  --instance=$SPANNER_INSTANCE_NAME \
  --sql="SELECT * FROM Albums WHERE SingerId = 2"

gcloud spanner databases execute-sql $SPANNER_DATABASE_NAME \
  --instance=$SPANNER_INSTANCE_NAME \
  --sql="SELECT * FROM Singers WHERE SingerId = 2"

Résultat attendu :

SingerId: 4
FirstName: Elena
LastName: Nadal
BirthDate: 1985-05-30
AlbumCount: 0

SingerId: 1
FirstName: Marc
LastName: Richards-Smith

3. Validation finale dans Spanner

Vérifiez l'état général de la table Singers dans Spanner :

gcloud spanner databases execute-sql $SPANNER_DATABASE_NAME \
  --instance=$SPANNER_INSTANCE_NAME \
  --sql="SELECT SingerId, FirstName, LastName, AlbumCount FROM Singers ORDER BY SingerId"

Résultat attendu :

SingerId: 1
FirstName: Marc
LastName: Richards-Smith
AlbumCount: 2

SingerId: 3
FirstName: Alice
LastName: Trentor
AlbumCount: 3

SingerId: 4
FirstName: Elena
LastName: Nadal
AlbumCount: 0

10. Configurer la réplication inversée (Spanner vers Cloud SQL)

Pour gérer les scénarios dans lesquels vous pourriez avoir besoin d'annuler ou de synchroniser la base de données Cloud SQL avec Spanner pendant une période donnée, vous pouvez configurer la réplication inversée. Ce pipeline utilise les flux de modification Spanner pour capturer les modifications dans Spanner et les réécrire dans le music_db Cloud SQL.

1. Créer un flux de modifications Spanner

Tout d'abord, vous devez créer un flux de modifications dans votre base de données Spanner pour suivre les modifications apportées aux tables Singers et Albums.

export CHANGE_STREAM_NAME="MusicDBChangeStream"

gcloud spanner databases ddl update $SPANNER_DATABASE_NAME \
  --instance=$SPANNER_INSTANCE_NAME \
  --ddl="CREATE CHANGE STREAM $CHANGE_STREAM_NAME FOR Singers, Albums"

Ce flux de modifications enregistre désormais toutes les modifications apportées aux données des tables spécifiées.

2. Créer une base de données Spanner pour les métadonnées Dataflow

Le modèle Dataflow Spanner to SourceDB nécessite une base de données Spanner distincte pour stocker les métadonnées permettant de gérer la consommation du flux de modification.

export SPANNER_METADATA_DB_NAME="reverse-replication-metadata"

gcloud spanner databases create $SPANNER_METADATA_DB_NAME \
  --instance=$SPANNER_INSTANCE_NAME

3. Préparer la configuration de la connexion Cloud SQL pour Dataflow

Le modèle Dataflow a besoin d'un fichier JSON dans Cloud Storage contenant les informations de connexion à la base de données Cloud SQL cible.

Créez un fichier local nommé shard_config.json :

cat << EOF > shard_config.json
[
  {
    "logicalShardId": "mysql_shard",
    "host": "${SQL_INSTANCE_IP}",
    "port": "3306",
    "user": "root",
    "password": "${DB_ROOT_PASSWORD}",
    "dbName": "music_db"
  }
]
EOF

Importez ce fichier dans votre bucket GCS :

export SHARD_CONFIG_FILE="gs://${BUCKET_NAME}/shard_config.json"
gcloud storage cp shard_config.json $SHARD_CONFIG_FILE

4. Exécuter le job Dataflow de réplication inversée

Lancez le job Dataflow à l'aide du modèle Flex Spanner_to_SourceDb.

export JOB_NAME_REVERSE="spanner-to-mysql-reverse-$(date +%Y%m%d-%H%M%S)"
export REVERSE_DLQ_DIR="gs://${BUCKET_NAME}/reverse-dlq"

gcloud dataflow flex-template run $JOB_NAME_REVERSE \
  --project=$PROJECT_ID \
  --region=$REGION \
--worker-machine-type=n2-highmem-8 \
--max-workers=2 \
--num-workers=1 \
--additional-experiments=use_runner_v2 \
--template-file-gcs-location="gs://dataflow-templates-${REGION}/latest/flex/Spanner_to_SourceDb" \
  --parameters \
changeStreamName="$CHANGE_STREAM_NAME",\
instanceId="$SPANNER_INSTANCE_NAME",\
databaseId="$SPANNER_DATABASE_NAME",\
spannerProjectId="$PROJECT_ID",\
metadataInstance="$SPANNER_INSTANCE_NAME",\
metadataDatabase="$SPANNER_METADATA_DB_NAME",\
sourceShardsFilePath="$SHARD_CONFIG_FILE",\
deadLetterQueueDirectory="$REVERSE_DLQ_DIR"

Paramètres clés

  • changeStreamName : nom du flux de modifications Spanner à lire.
  • metadataInstance, metadataDatabase : instance/base de données Spanner permettant de stocker les métadonnées utilisées par le connecteur pour contrôler la consommation des données de l'API Change Streams.
  • sourceShardsFilePath : chemin d'accès GCS à votre shard_config.json.
  • filtrationMode : spécifie comment supprimer certains enregistrements en fonction d'un critère. La valeur par défaut est forward_migration (filtrer les enregistrements écrits à l'aide du pipeline de migration directe).

Remarque sur le réseau : Les nœuds de calcul Dataflow se connecteront à l'instance Cloud SQL à l'aide de l'adresse IP publique spécifiée dans shard_config.json. Cette connexion est autorisée en raison de l'entrée 0.0.0.0/0 dans les réseaux autorisés de l'instance Cloud SQL.

Surveillez le démarrage du job dans la console des jobs Dataflow.

5. Tester la réplication inverse

Maintenant, apportez des modifications directement dans Cloud Spanner et vérifiez qu'elles sont reflétées dans Cloud SQL. Ne le faites qu'une fois que le job Dataflow a démarré et est en cours de traitement.

Tester INSERT, UPDATE et DELETE

# INSERT: Insert a new singer (SingerId 5) into Spanner
gcloud spanner databases execute-sql $SPANNER_DATABASE_NAME \
  --instance=$SPANNER_INSTANCE_NAME \
  --sql="INSERT INTO Singers (SingerId, FirstName, LastName, BirthDate, AlbumCount) VALUES (5, 'David', 'Chen', '1995-02-18', 0)"

# UPDATE: Update SingerId 3's AlbumCount in Spanner
gcloud spanner databases execute-sql $SPANNER_DATABASE_NAME \
  --instance=$SPANNER_INSTANCE_NAME \
  --sql="UPDATE Singers SET AlbumCount = 5 WHERE SingerId = 3"

# DELETE: Delete SingerId 1 from Spanner
gcloud spanner databases execute-sql $SPANNER_DATABASE_NAME \
--instance=$SPANNER_INSTANCE_NAME \
--sql="DELETE FROM Albums WHERE SingerId = 1"

gcloud spanner databases execute-sql $SPANNER_DATABASE_NAME \
  --instance=$SPANNER_INSTANCE_NAME \
  --sql="DELETE FROM Singers WHERE SingerId = 1"

Vérification dans Cloud SQL (après quelques instants) :

Connectez-vous à Cloud SQL :

mysql -h $SQL_INSTANCE_IP -u root -p

Saisissez le mot de passe (Welcome@1) lorsque vous y êtes invité, puis exécutez les commandes SQL suivantes à l'invite mysql>.

USE music_db; 
-- Verify INSERT: This should show the new row for David Chen
SELECT * FROM Singers WHERE SingerId = 5;

-- Verify UPDATE: This should show AlbumCount as 5.
SELECT SingerId, FirstName, AlbumCount FROM Singers WHERE SingerId = 3;

-- Verify DELETE: This should return an empty set.
SELECT * FROM Albums WHERE SingerId = 1; 
SELECT * FROM Singers WHERE SingerId = 1; 

-- Final Verification
SELECT SingerId, FirstName, LastName, AlbumCount FROM Singers ORDER BY SingerId;
EXIT;

La sortie attendue dans Cloud SQL doit refléter les modifications apportées dans Spanner.

+----------+-----------+----------------+------------+
| SingerId | FirstName | LastName       | AlbumCount |
+----------+-----------+----------------+------------+
|        3 | Alice     | Trentor        |          5 |
|        4 | Elena     | Nadal          |          0 |
|        5 | David     | Chen           |          0 |
+----------+-----------+----------------+------------+

Cela confirme que le pipeline de réplication inversée fonctionne et synchronise les modifications de Spanner vers Cloud SQL.

11. Nettoyer les ressources

Pour éviter que des frais supplémentaires ne soient facturés sur votre compte Google Cloud, supprimez les ressources créées lors de cet atelier de programmation.

Définir des variables d'environnement (si nécessaire)

Vérifiez si les variables d'environnement sont correctement définies :

echo "PROJECT_ID: $PROJECT_ID"
echo "REGION: $REGION"
echo "SQL_INSTANCE_NAME: $SQL_INSTANCE_NAME"
echo "SPANNER_INSTANCE_NAME: $SPANNER_INSTANCE_NAME"
echo "BUCKET_NAME: $BUCKET_NAME"
echo "STREAM_NAME: $STREAM_NAME"
echo "SQL_CP_NAME: $SQL_CP_NAME"
echo "GCS_CP_NAME: $GCS_CP_NAME"
echo "PUBSUB_SUBSCRIPTION: $PUBSUB_SUBSCRIPTION"
echo "PUBSUB_TOPIC: $PUBSUB_TOPIC"
echo "CHANGE_STREAM_NAME: $CHANGE_STREAM_NAME"

Listez vos jobs pour trouver les ID des jobs Dataflow en cours d'exécution. Exportez JOB_ID_CDC et JOB_ID_REVERSE en conséquence.

gcloud dataflow jobs list --region=$REGION --filter="state=Running"
export JOB_ID_CDC=<PASTE_JOB_ID_HERE>
export JOB_ID_REVERSE=<PASTE_JOB_ID_HERE>

Si vous êtes dans une nouvelle session Cloud Shell, réexportez les variables d'environnement clés :

export PROJECT_ID=$(gcloud config get-value project)
export REGION="us-central1" # Or the region you used
export SQL_INSTANCE_NAME="source-mysql-instance"
export SPANNER_INSTANCE_NAME="target-spanner-instance"
export BUCKET_NAME="migration-${PROJECT_ID}-bucket"
export STREAM_NAME="mysql-to-spanner-stream"
export SQL_CP_NAME="mysql-src-cp"
export GCS_CP_NAME="gcs-dest-cp"
export PUBSUB_TOPIC="datastream-gcs-updates"
export PUBSUB_SUBSCRIPTION="datastream-gcs-sub"
export CHANGE_STREAM_NAME="MusicDBChangeStream"

Arrêter les tâches de traitement par flux Dataflow

Annulez le job Datastream to Spanner (migration à chaud) :

gcloud dataflow jobs cancel $JOB_ID_CDC --region=$REGION --project=$PROJECT_ID

Annulez le job Spanner to Cloud SQL (réplication inversée) :

gcloud dataflow jobs cancel $JOB_ID_REVERSE --region=$REGION --project=$PROJECT_ID

Supprimer les ressources Datastream

Arrêter et supprimer le flux :

gcloud datastream streams update $STREAM_NAME \
  --location=$REGION --state=PAUSED --project=$PROJECT_ID
# Wait a moment for the stream to pause
gcloud datastream streams delete $STREAM_NAME \
  --location=$REGION --project=$PROJECT_ID --quiet

Supprimer des profils de connexion

gcloud datastream connection-profiles delete $SQL_CP_NAME \
  --location=$REGION --project=$PROJECT_ID --quiet
gcloud datastream connection-profiles delete $GCS_CP_NAME \
  --location=$REGION --project=$PROJECT_ID --quiet

Supprimer les ressources Pub/Sub

Supprimer un abonnement :

gcloud pubsub subscriptions delete $PUBSUB_SUBSCRIPTION \
  --project=$PROJECT_ID --quiet

Supprimer un thème :

gcloud pubsub topics delete $PUBSUB_TOPIC \
  --project=$PROJECT_ID --quiet

Supprimer une instance Cloud SQL

Les bases de données (music_db) qu'elle contient seront alors automatiquement supprimées.

gcloud sql instances delete $SQL_INSTANCE_NAME \
  --project=$PROJECT_ID --quiet

Supprimer une instance Cloud Spanner

Les bases de données (music-db-migrated et reverse-replication-metadata) qu'il contient seront également supprimées.

gcloud spanner instances delete $SPANNER_INSTANCE_NAME \
  --project=$PROJECT_ID --quiet

Supprimer le bucket GCS et son contenu

gcloud storage rm --recursive gs://${BUCKET_NAME}

Supprimer des fichiers locaux

Supprimez tous les fichiers générés dans votre répertoire d'accueil Cloud Shell :

rm -f music-db* shard_config.json

Vous avez maintenant nettoyé les ressources créées pour cet atelier de programmation.