Von DynamoDB zu Spanner migrieren

In dieser Anleitung wird beschrieben, wie Sie von Amazon DynamoDB zu Spanner. Das Dokument richtet sich in erster Linie an Inhaber von Anwendungen, die von einem NoSQL-System zu Spanner wechseln möchten. Spanner ist ein vollständig relationales, fehlertolerantes, hoch skalierbares SQL-Datenbanksystem, das Unterstützung für Transaktionen bietet. Wenn Ihre Amazon DynamoDB-Tabellen in Bezug auf Typen und Layout einheitlich sind, ist die Zuordnung zu Spanner unkompliziert. Enthalten Ihre Amazon DynamoDB-Tabellen jedoch beliebige Datentypen und Werte, ist es möglicherweise einfacher, auf andere NoSQL-Dienste wie Datastore oder Firestore umzusteigen.

In dieser Anleitung wird davon ausgegangen, dass Sie mit Datenbankschemas, Datentypen, den Grundlagen von NoSQL und mit relationalen Datenbanksystemen vertraut sind. Es werden vordefinierte Aufgaben ausgeführt, um eine Beispielmigration vorzunehmen. Wenn Sie die Anleitung abgeschlossen haben, können Sie den Code und die Schritte an Ihre Umgebung anpassen.

Das folgende Architekturdiagramm enthält eine Übersicht der Komponenten, die in dieser Anleitung zur Datenmigration verwendet werden:

Diagramm: Architektur der Migrationskomponenten

Ziele

  • Daten von Amazon DynamoDB zu Spanner migrieren
  • Spanner-Datenbank und -Migrationstabelle erstellen
  • NoSQL-Schema einem relationalen Schema zuordnen
  • Beispiel-Dataset, das Amazon DynamoDB verwendet, erstellen und exportieren
  • Daten zwischen Amazon S3 und Cloud Storage übertragen
  • Mit Dataflow Daten in Spanner laden

Kosten

In dieser Anleitung werden die folgenden kostenpflichtigen Komponenten von Google Cloud verwendet:

Die Gebühren für Spanner beruhen auf der Rechenkapazität in Ihrer Instanz und der Menge an Daten, die während des monatlichen Abrechnungszyklus gespeichert werden. Im Rahmen der Anleitung verwenden Sie eine minimale Konfiguration dieser Ressourcen, die am Ende bereinigt werden. Für reale Szenarien schätzen Sie Ihre Durchsatz- und Speicheranforderungen und verwenden Sie dann Dokumentation zu Spanner-Instanzen um die benötigte Rechenkapazität zu bestimmen.

Neben Google Cloud-Ressourcen werden in dieser Anleitung die folgenden Ressourcen von Amazon Web Services (AWS) verwendet:

  • AWS Lambda
  • Amazon S3
  • Amazon DynamoDB

Diese Dienste werden nur während der Migration benötigt. Am Ende der Anleitung können Sie die Schritte zum Bereinigen aller Ressourcen ausführen, um unnötige Gebühren zu vermeiden. Verwenden Sie den AWS-Preisrechner. um diese Kosten zu schätzen.

Mit dem Preisrechner können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung vornehmen.

Hinweise

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Die Abrechnung für das Google Cloud-Projekt muss aktiviert sein.

  4. Enable the Spanner, Pub/Sub, Compute Engine, and Dataflow APIs.

    Enable the APIs

  5. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  6. Die Abrechnung für das Google Cloud-Projekt muss aktiviert sein.

  7. Enable the Spanner, Pub/Sub, Compute Engine, and Dataflow APIs.

    Enable the APIs

Nach Abschluss der in diesem Dokument beschriebenen Aufgaben können Sie weitere Kosten vermeiden, indem Sie die erstellten Ressourcen löschen. Weitere Informationen finden Sie unter Bereinigen.

Umgebung vorbereiten

In dieser Anleitung führen Sie Befehle in Cloud Shell aus. Mit Cloud Shell erhalten Sie Zugriff auf die Befehlszeile von Google Cloud. Außerdem enthält Cloud Shell das Google Cloud CLI und weitere Tools, die Sie für die Entwicklung in Google Cloud benötigen. Die Initialisierung von Cloud Shell kann mehrere Minuten dauern.

  1. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

  2. Legen Sie die Standardzone für Compute Engine fest, Beispiel: us-central1-b. gcloud config set compute/zone us-central1-b
  3. Klonen Sie das GitHub-Repository mit dem Beispielcode. https://github.com/GoogleCloudPlatform/dynamodb-spanner-migration.git
  4. Rufen Sie das geklonte Verzeichnis auf. cd dynamodb-spanner-migration
  5. Erstellen Sie eine virtuelle Python-Umgebung. pip3 install virtualenv virtualenv env
  6. Virtuelle Umgebung aktivieren: source env/bin/activate
  7. Installieren Sie die erforderlichen Python-Module. pip3 install -r requirements.txt

AWS-Zugriff konfigurieren

In dieser Anleitung erstellen und löschen Sie Amazon DynamoDB-Tabellen, Amazon S3-Buckets und andere Ressourcen. Damit Sie auf diese Ressourcen zugreifen können, müssen Sie die erforderlichen AWS IAM-Berechtigungen (Identity and Access Management) erstellen. Sie können ein Test- oder Sandbox-AWS-Konto verwenden, um eine Beeinträchtigung der Produktionsressourcen im selben Konto zu vermeiden.

AWS IAM-Rolle für AWS Lambda erstellen

In diesem Abschnitt erstellen Sie eine AWS IAM-Rolle, die in einem späteren Anleitungsschritt in AWS Lambda verwendet wird.

  1. Rufen Sie in der AWS-Konsole den Bereich IAM auf, klicken Sie auf Roles und wählen Sie Create Role aus.
  2. Prüfen Sie, ob unter Art der vertrauenswürdigen Entität die Option AWS-Dienst ausgewählt ist.
  3. Wählen Sie unter Anwendungsfall die Option Lambda aus und klicken Sie dann auf Weiter.
  4. Geben Sie im Filterfeld Berechtigungsrichtlinien AWSLambdaDynamoDBExecutionRole ein und drücken Sie Return, um die Suche zu starten.
  5. Klicken Sie auf das Kästchen AWSLambdaDynamoDBExecutionRole und dann auf Weiter.
  6. Geben Sie im Feld Role name den Wert dynamodb-spanner-lambda-role ein und klicken Sie dann auf Create role.

AWS IAM-Nutzer erstellen

In den folgenden Schritten erstellen Sie einen AWS IAM-Nutzer mit programmatischem Zugriff auf AWS-Ressourcen, die in der Anleitung verwendet werden.

  1. Klicken Sie im Bereich IAM der AWS-Konsole auf Nutzer und wählen Sie Nutzer hinzufügen aus.
  2. Geben Sie im Feld User name den Wert dynamodb-spanner-migration ein.
  3. Klicken Sie unter Zugriffstyp das Kästchen links neben Zugriffsschlüssel – programmatischer Zugriff an.

  4. Klicken Sie auf Next: Permissions.

  5. Klicken Sie auf Bestehende Richtlinien direkt anhängen, nutzen Sie das Feld Suchen zum Filtern und wählen Sie das Kästchen neben jeder der folgenden Richtlinien aus:

    • AmazonDynamoDBFullAccess
    • AmazonS3FullAccess
    • AWSLambda_FullAccess
  6. Klicken Sie auf Weiter: Tags, Weiter: Prüfen und dann auf Nutzer erstellen.

  7. Klicken Sie auf Show, um die Anmeldedaten aufzurufen. Die Zugriffsschlüssel-ID und der geheime Zugriffsschlüssel für den neu erstellten Nutzer werden angezeigt. Lassen Sie dieses Fenster vorerst geöffnet, da Sie die Anmeldedaten im nächsten Abschnitt benötigen. Sie sollten diese Anmeldedaten an einem sicheren Ort aufbewahren, da Sie damit Änderungen an Ihrem Konto vornehmen können, die sich ggf. auf die Umgebung auswirken. Am Ende dieser Anleitung können Sie den IAM-Nutzer löschen.

AWS-Befehlszeilenschnittstelle konfigurieren

  1. Konfigurieren Sie die AWS-Befehlszeilenschnittstelle in Cloud Shell.

    aws configure
    

    Die Ausgabe sieht so aus:

    AWS Access Key ID [None]: PASTE_YOUR_ACCESS_KEY_ID
    AWS Secret Access Key [None]: PASTE_YOUR_SECRET_ACCESS_KEY
    Default region name [None]: us-west-2
    Default output format [None]:
    
    • Geben Sie die ACCESS KEY ID und den SECRET ACCESS KEY des AWS IAM-Kontos ein, das Sie erstellt haben.
    • Geben Sie im Feld Default region name den Wert us-west-2 ein. Übernehmen Sie die Standardwerte der restlichen Felder.
  2. Schließen Sie das Fenster der AWS IAM-Konsole.

Informationen zum Datenmodell

Im folgenden Abschnitt sind die Ähnlichkeiten und Unterschiede zwischen Datentypen, Schlüsseln und Indexen für Amazon DynamoDB und Spanner beschrieben.

Datentypen

Spanner verwendet GoogleSQL-Datentypen. In der folgenden Tabelle wird die Zuordnung von Datentypen in Amazon DynamoDB zu Datentypen in Spanner beschrieben.

Amazon DynamoDB Spanner
Number Je nach Genauigkeit oder beabsichtigter Verwendung kann dieser Datentyp den Typen INT64, FLOAT64, TIMESTAMP oder DATE zugeordnet werden.
String String
Boolean BOOL
Null Kein expliziter Typ. Spalten können Nullwerte enthalten.
Binary Byte
Sets Array
Map und List Struct, wenn die Struktur konsistent ist und mithilfe der Tabellen-DDL-Syntax beschrieben werden kann.

Primärschlüssel

Ein Amazon DynamoDB-Primärschlüssel sorgt für Eindeutigkeit und kann entweder ein Hash-Schlüssel oder eine Kombination aus Hash-Schlüssel und Bereichsschlüssel sein. In dieser Anleitung wird zuerst die Migration einer Amazon DynamoDB-Tabelle demonstriert, deren Primärschlüssel ein Hash-Schlüssel ist. Dieser Hash-Schlüssel wird zum Primärschlüssel Ihrer Spanner-Tabelle. Im Abschnitt zu verschränkten Tabellen modellieren Sie später eine Situation, in der eine Amazon DynamoDB-Tabelle einen Primärschlüssel verwendet, der sich aus einem Hash-Schlüssel und einem Bereichsschlüssel zusammensetzt.

Sekundäre Indexe

Sowohl Amazon DynamoDB als auch Spanner unterstützen die Erstellung eines Index für ein Attribut, das kein Primärschlüssel ist. Notieren Sie sich alle sekundären Indexe in Ihrer Amazon DynamoDB-Tabelle, damit Sie sie in der Spanner-Tabelle erstellen können. Dies wird in einem späteren Abschnitt dieser Anleitung behandelt.

Beispieltabelle

Zur Vereinfachung dieser Anleitung migrieren Sie die folgende Beispieltabelle von Amazon DynamoDB zu Spanner:

Amazon DynamoDB Spanner
Tabellenname Migration Migration
Primärschlüssel "Username" : String "Username" : STRING(1024)
Schlüsseltyp Hash
Sonstige Felder Zipcode: Number Subscribed: Boolean ReminderDate: String PointsEarned: Number Zipcode: INT64 Subscribed: BOOL ReminderDate: DATE PointsEarned: INT64

Amazon DynamoDB-Tabelle vorbereiten

Im folgenden Abschnitt erstellen Sie eine Amazon DynamoDB-Quelltabelle und füllen diese mit Daten.

  1. Erstellen Sie in Cloud Shell eine Amazon DynamoDB-Tabelle mit den Attributen der Beispieltabelle.

    aws dynamodb create-table --table-name Migration \
        --attribute-definitions AttributeName=Username,AttributeType=S \
        --key-schema AttributeName=Username,KeyType=HASH \
        --provisioned-throughput ReadCapacityUnits=75,WriteCapacityUnits=75
    
  2. Prüfen Sie, ob der Tabellenstatus ACTIVE lautet.

    aws dynamodb describe-table --table-name Migration \
        --query 'Table.TableStatus'
    
  3. Füllen Sie die Tabelle mit Beispieldaten.

    python3 make-fake-data.py --table Migration --items 25000
    

Spanner-Datenbank erstellen

Sie erstellen eine Spanner-Instanz mit der kleinstmöglichen Rechenkapazität: 100 Verarbeitungseinheiten. Diese Rechenkapazität ist für den Umfang dieser Anleitung ausreichend. Informationen zum Ermitteln der nötigen Rechenkapazität für eine Produktionsbereitstellung, die den Leistungsanforderungen Ihrer Datenbank entspricht, finden Sie in der Dokumentation zu Spanner-Instanzen.

In diesem Beispiel erstellen Sie gleichzeitig mit der Datenbank ein Tabellenschema. Außerdem ist es möglich und üblich, Schemaaktualisierungen durchzuführen, nachdem Sie die Datenbank erstellt haben.

  1. Erstellen Sie eine Spanner-Instanz in derselben Region, in der Sie die Compute Engine-Standardzone festgelegt haben. z. B. us-central1

    gcloud beta spanner instances create spanner-migration \
        --config=regional-us-central1 --processing-units=100 \
        --description="Migration Demo"
    
  2. Erstellen Sie zusammen mit der Beispieltabelle eine Datenbank in der Spanner-Instanz.

    gcloud spanner databases create migrationdb \
        --instance=spanner-migration \
        --ddl "CREATE TABLE Migration ( \
                Username STRING(1024) NOT NULL, \
                PointsEarned INT64, \
                ReminderDate DATE, \
                Subscribed BOOL, \
                Zipcode INT64, \
             ) PRIMARY KEY (Username)"
    

Migration vorbereiten

In den nächsten Abschnitten erfahren Sie, wie Sie die Amazon DynamoDB-Quelltabelle exportieren und die Pub/Sub-Replikation so einstellen, dass während des Exports auftretende Änderungen an der Datenbank erfasst werden.

Änderungen an Pub/Sub streamen

Zum Streamen von Datenbankänderungen an Pub/Sub verwenden Sie eine AWS Lambda-Funktion.

  1. Aktivieren Sie Amazon DynamoDB-Streams für Ihre Quelltabelle in Cloud Shell.

    aws dynamodb update-table --table-name Migration \
        --stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES
    
  2. Richten Sie ein Pub/Sub-Thema ein, das die Änderungen empfangen soll.

    gcloud pubsub topics create spanner-migration
    

    Die Ausgabe sieht so aus:

    Created topic [projects/your-project/topics/spanner-migration].
    
  3. Erstellen Sie ein IAM-Dienstkonto, um Tabellenaktualisierungen an das Pub/Sub-Thema per Push zu übertragen.

    gcloud iam service-accounts create spanner-migration \
        --display-name="Spanner Migration"
    

    Die Ausgabe sieht so aus:

    Created service account [spanner-migration].
    
  4. Erstellen Sie eine IAM-Richtlinienbindung, damit das Dienstkonto die Berechtigung zum Veröffentlichen in Pub/Sub hat. Ersetzen Sie GOOGLE_CLOUD_PROJECT durch den Namen des Google Cloud-Projekts.

    gcloud projects add-iam-policy-binding GOOGLE_CLOUD_PROJECT \
        --role roles/pubsub.publisher \
        --member serviceAccount:spanner-migration@GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com
    

    Die Ausgabe sieht so aus:

    bindings:
    (...truncated...)
    - members:
      - serviceAccount:spanner-migration@solution-z.iam.gserviceaccount.com
      role: roles/pubsub.publisher
    
  5. Erstellen Sie Anmeldedaten für das Dienstkonto.

    gcloud iam service-accounts keys create credentials.json \
        --iam-account spanner-migration@GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com
    

    Die Ausgabe sieht so aus:

    created key [5e559d9f6bd8293da31b472d85a233a3fd9b381c] of type [json] as [credentials.json] for [spanner-migration@your-project.iam.gserviceaccount.com]
    
  6. Bereiten Sie die AWS Lambda-Funktion vor und verpacken Sie sie, um Änderungen in Amazon DynamoDB-Tabellen an Pub/Sub-Thema zu übertragen.

    pip3 install --ignore-installed --target=lambda-deps google-cloud-pubsub
    cd lambda-deps; zip -r9 ../pubsub-lambda.zip *; cd -
    zip -g pubsub-lambda.zip ddbpubsub.py
  7. Erstellen Sie eine Variable, um den Amazon Resource Name (ARN) der zuvor erstellten Lambda-Ausführungsrolle zu erfassen.

    LAMBDA_ROLE=$(aws iam list-roles \
        --query 'Roles[?RoleName==`dynamodb-spanner-lambda-role`].[Arn]' \
        --output text)
    
  8. Verwenden Sie das Paket pubsub-lambda.zip, um die AWS Lambda-Funktion zu erstellen.

    aws lambda create-function --function-name dynamodb-spanner-lambda \
        --runtime python3.9 --role ${LAMBDA_ROLE} \
        --handler ddbpubsub.lambda_handler --zip fileb://pubsub-lambda.zip \
        --environment Variables="{SVCACCT=$(base64 -w 0 credentials.json),PROJECT=GOOGLE_CLOUD_PROJECT,TOPIC=spanner-migration}"
    

    Die Ausgabe sieht so aus:

    {
        "FunctionName": "dynamodb-spanner-lambda",
        "LastModified": "2022-03-17T23:45:26.445+0000",
        "RevisionId": "e58e8408-cd3a-4155-a184-4efc0da80bfb",
        "MemorySize": 128,
    ... truncated output... "PackageType": "Zip", "Architectures": [ "x86_64" ] }

  9. Create a variable to capture the ARN of the Amazon DynamoDB stream for your table.

    STREAMARN=$(aws dynamodb describe-table \
        --table-name Migration \
        --query "Table.LatestStreamArn" \
        --output text)
    
  10. Verknüpfen Sie die Lambda-Funktion mit der Amazon DynamoDB-Tabelle.

    aws lambda create-event-source-mapping --event-source ${STREAMARN} \
        --function-name dynamodb-spanner-lambda --enabled \
        --starting-position TRIM_HORIZON
    
  11. Zum Optimieren der Reaktionszeit beim Testen fügen Sie am Ende des vorherigen Befehls --batch-size 1 hinzu. Dadurch wird die Funktion jedes Mal ausgelöst, wenn Sie ein Element erstellen, aktualisieren oder löschen.

    Es wird eine Ausgabe wie diese angezeigt:

    {
        "UUID": "44e4c2bf-493a-4ba2-9859-cde0ae5c5e92",
        "StateTransitionReason": "User action",
        "LastModified": 1530662205.549,
        "BatchSize": 100,
        "EventSourceArn": "arn:aws:dynamodb:us-west-2:accountid:table/Migration/stream/2018-07-03T15:09:57.725",
        "FunctionArn": "arn:aws:lambda:us-west-2:accountid:function:dynamodb-spanner-lambda",
        "State": "Creating",
        "LastProcessingResult": "No records processed"
    ... truncated output...
    

Amazon DynamoDB-Tabelle nach Amazon S3 exportieren

  1. Erstellen Sie in Cloud Shell eine Variable für einen Bucket-Namen, den Sie in den folgenden Abschnitten verwenden.

    BUCKET=${DEVSHELL_PROJECT_ID}-dynamodb-spanner-export
    
  2. Erstellen Sie einen Amazon S3-Bucket, in den der DynamoDB-Export kopiert werden soll.

    aws s3 mb s3://${BUCKET}
    
  3. Wechseln Sie in der AWS Management Console zu DynamoDB und klicken Sie auf Tabellen.

  4. Klicken Sie auf die Tabelle Migration.

  5. Klicken Sie auf dem Tab Exporte und Stream auf Nach S3 exportieren.

  6. Aktivieren Sie point-in-time-recovery (PITR), wenn Sie dazu aufgefordert werden.

  7. Klicken Sie auf S3 durchsuchen, um den zuvor erstellten S3-Bucket auszuwählen.

  8. Klicken Sie auf Exportieren.

  9. Klicken Sie auf das Symbol Aktualisieren, um den Status des Exportjobs zu aktualisieren. Der Export kann mehrere Minuten dauern.

    Wenn der Prozess beendet wurde, sehen Sie sich den Ausgabe-Bucket an.

    aws s3 ls --recursive s3://${BUCKET}
    

    Dieser Schritt dauert ca. fünf Minuten. Nach Abschluss des Vorgangs wird in etwa folgende Ausgabe angezeigt:

    2022-02-17 04:41:46          0 AWSDynamoDB/01645072900758-ee1232a3/_started
    2022-02-17 04:46:04     500441 AWSDynamoDB/01645072900758-ee1232a3/data/xygt7i2gje4w7jtdw5652s43pa.json.gz
    2022-02-17 04:46:17        199 AWSDynamoDB/01645072900758-ee1232a3/manifest-files.json
    2022-02-17 04:46:17         24 AWSDynamoDB/01645072900758-ee1232a3/manifest-files.md5
    2022-02-17 04:46:17        639 AWSDynamoDB/01645072900758-ee1232a3/manifest-summary.json
    2022-02-17 04:46:18         24 AWSDynamoDB/01645072900758-ee1232a3/manifest-summary.md5
    

Migration ausführen

Die Pub/Sub-Bereitstellung wurde eingerichtet und Sie können alle nach dem Export vorgenommenen Tabellenänderungen verarbeiten.

Exportierte Tabelle in Cloud Storage kopieren

  1. Erstellen Sie in Cloud Shell einen Cloud Storage-Bucket, in den die exportierten Dateien von Amazon S3 kopiert werden sollen.

    gcloud storage buckets create gs://${BUCKET}
    
  2. Synchronisieren Sie die Dateien von Amazon S3 nach Cloud Storage. Für die meisten Kopiervorgänge können Sie den Befehl rsync verwenden. Wenn Ihre Exportdateien groß (mehrere GB oder mehr), verwenden Sie Cloud Storage-Übertragungsdienst um die Übertragung im Hintergrund zu verwalten.

    gcloud storage rsync s3://${BUCKET} gs://${BUCKET} --recursive --delete-unmatched-destination-objects
    

Batch-Import der Daten

  1. Führen Sie einen Cloud Dataflow-Job mit Apache Beam-Beispielcode aus, um die Daten aus den exportierten Dateien in die Spanner-Tabelle zu schreiben.

    cd dataflow
    mvn compile
    mvn exec:java \
    -Dexec.mainClass=com.example.spanner_migration.SpannerBulkWrite \
    -Pdataflow-runner \
    -Dexec.args="--project=GOOGLE_CLOUD_PROJECT \
                 --instanceId=spanner-migration \
                 --databaseId=migrationdb \
                 --table=Migration \
                 --importBucket=$BUCKET \
                 --runner=DataflowRunner \
                 --region=us-central1"
    
    1. So beobachten Sie den Fortschritt des Importjobs in der Google Cloud Console: gehen Sie zu Dataflow.

      Zu Dataflow

    2. Während der Job ausgeführt wird, können Sie sich das Ausführungsdiagramm ansehen, um die Logs zu prüfen. Klicken Sie auf den Job mit dem Status "Wird ausgeführt".

      Bild: Importjob ausführen

  2. Klicken Sie auf die einzelnen Phasen, um zu sehen, wie viele Elemente schon verarbeitet wurden. Der Import ist abgeschlossen, wenn für alle Phasen der Status Erfolgreich angezeigt wird. In jeder Phase wird die gleiche Anzahl von Elementen angezeigt, die in Ihrer Amazon DynamoDB-Tabelle erstellt wurden.

    Bild: Erfolgsstufen des Importjobs

  3. Die Anzahl der Einträge in der Spanner-Zieltabelle muss der Anzahl der Elemente in der Amazon DynamoDB-Tabelle entsprechen.

    aws dynamodb describe-table --table-name Migration --query Table.ItemCount
    gcloud spanner databases execute-sql migrationdb \ --instance=spanner-migration --sql="select count(*) from Migration"

    Die Ausgabe sieht so aus:

    $ aws dynamodb describe-table --table-name Migration --query Table.ItemCount
    25000
    $ gcloud spanner databases execute-sql migrationdb --instance=spanner-migration --sql="select count(*) from Migration"
    25000
    
  4. Überprüfen Sie zufällig ausgewählte Einträge in jeder Tabelle auf Konsistenz.

    gcloud spanner databases execute-sql migrationdb \
        --instance=spanner-migration \
        --sql="select * from Migration limit 1"
    

    Die Ausgabe sieht so aus:

     Username: aadams4495
     PointsEarned: 5247
     ReminderDate: 2022-03-14
     Subscribed: True
     Zipcode: 58057
    
  5. Fragen Sie die Amazon DynamoDB-Tabelle mit demselben Username ab, der im vorherigen Schritt von der Spanner-Abfrage zurückgegeben wurde. Beispiel: aallen2538 Der Wert bezieht sich auf die Beispieldaten in Ihrer Datenbank.

    aws dynamodb get-item --table-name Migration \
        --key '{"Username": {"S": "aadams4495"}}'
    

    Die Werte der anderen Felder sollten den Werten der Spanner-Ausgabe entsprechen. Die Ausgabe sieht so aus:

    {
        "Item": {
            "Username": {
                "S": "aadams4495"
            },
            "ReminderDate": {
                "S": "2018-06-18"
            },
            "PointsEarned": {
                "N": "1606"
            },
            "Zipcode": {
                "N": "17303"
            },
            "Subscribed": {
                "BOOL": false
            }
        }
    }
    

Neue Änderungen replizieren

Wenn der Batch-Importjob abgeschlossen ist, richten Sie einen Streamingjob ein, um aktive Aktualisierungen aus der Quelltabelle in Spanner zu schreiben. Ich abonnieren aus Pub/Sub zu den Ereignissen und schreibt sie in Spanner

Die von Ihnen erstellte Lambda-Funktion ist dazu konfiguriert, Änderungen in der Amazon DynamoDB-Quelltabelle zu erfassen und in Pub/Sub zu veröffentlichen.

  1. Erstellen Sie ein Abo für das Pub/Sub-Thema, an das AWS Lambda Ereignisse sendet.

    gcloud pubsub subscriptions create spanner-migration \
        --topic spanner-migration
    

    Die Ausgabe sieht so aus:

    Created subscription [projects/your-project/subscriptions/spanner-migration].
    
  2. Führen Sie den Dataflow-Job in Cloud Shell aus, um die an Pub/Sub gesendeten Änderungen in die Spanner-Tabelle zu schreiben.

    mvn exec:java \
    -Dexec.mainClass=com.example.spanner_migration.SpannerStreamingWrite \
    -Pdataflow-runner \
    -Dexec.args="--project=GOOGLE_CLOUD_PROJECT \
                 --instanceId=spanner-migration \
                 --databaseId=migrationdb \
                 --table=Migration \
                 --experiments=allow_non_updatable_job \
    --subscription=projects/GOOGLE_CLOUD_PROJECT/subscriptions/spanner-migration \
    --runner=DataflowRunner \
    --region=us-central1"
    
    1. Ähnlich wie das Laden im Batch den Fortschritt des Jobs in der Google Cloud Console gehen Sie zu Dataflow.

      Zu Dataflow

    2. Klicken Sie auf den Job mit dem Status Wird ausgeführt.

      Bild: Job ausführen

      Im Verarbeitungsdiagramm wird eine ähnliche Ausgabe wie vorher angezeigt, aber jedes verarbeitete Element wird im Statusfenster gezählt. Die Systemverzögerungszeit ist eine grobe Schätzung der voraussichtlichen Verzögerung, bis Änderungen in der Spanner-Tabelle angezeigt werden.

      Bild: Prozesse werden aufgrund von Verzögerungszeiten ausgeführt

Der Dataflow-Job, den Sie in der Batch-Ladephase ausgeführt haben, bestand aus einem endlichen Eingabe-Dataset. Dies wird auch als begrenztes Dataset bezeichnet. Dieser Dataflow-Job verwendet Pub/Sub als Streamingquelle und gilt als unbegrenzt. Weitere Informationen zu diesen beiden Quelltypen finden Sie im Programmierleitfaden für Apache Beam im Abschnitt zu PCollections. Der Dataflow-Job in diesem Schritt soll aktiv bleiben, damit er beim Abschluss nicht beendet wird. Der Dataflow-Streamingjob behält den Status Wird ausgeführt bei, statt zu Erfolgreich zu wechseln.

Replikation prüfen

Wenn Sie ein paar Änderungen an der Quelltabelle vornehmen, können Sie verifizieren, ob die Änderungen in die Spanner-Tabelle repliziert werden.

  1. Führen Sie eine Abfrage für eine nicht vorhandene Zeile in Spanner durch.

    gcloud spanner databases execute-sql migrationdb \
        --instance=spanner-migration \
        --sql="SELECT * FROM Migration WHERE Username='my-test-username'"
    

    Der Vorgang gibt keine Ergebnisse zurück.

  2. Erstellen Sie in Amazon DynamoDB einen Eintrag mit demselben Schlüssel, den Sie in der Spanner-Abfrage verwendet haben. Wenn der Befehl erfolgreich ausgeführt wird, erfolgt keine Ausgabe.

    aws dynamodb put-item \
        --table-name Migration \
        --item '{"Username" : {"S" : "my-test-username"}, "Subscribed" : {"BOOL" : false}}'
    
  3. Führen Sie dieselbe Abfrage noch einmal aus, um zu prüfen, ob sich die Zeile jetzt in Spanner befindet.

    gcloud spanner databases execute-sql migrationdb \
        --instance=spanner-migration \
        --sql="SELECT * FROM Migration WHERE Username='my-test-username'"
    

    In der Ausgabe wird die eingefügte Zeile angezeigt:

    Username: my-test-username
    PointsEarned: None
    ReminderDate: None
    Subscribed: False
    Zipcode:
    
  4. Ändern Sie ein paar Attribute im ursprünglichen Element und aktualisieren Sie die Amazon DynamoDB-Tabelle.

    aws dynamodb update-item \
        --table-name Migration \
        --key '{"Username": {"S":"my-test-username"}}' \
        --update-expression "SET PointsEarned = :pts, Subscribed = :sub" \
        --expression-attribute-values '{":pts": {"N":"4500"}, ":sub": {"BOOL":true}}'\
        --return-values ALL_NEW
    

    Es wird eine Ausgabe wie diese angezeigt:

    {
        "Attributes": {
            "Username": {
                "S": "my-test-username"
            },
            "PointsEarned": {
                "N": "4500"
            },
            "Subscribed": {
                "BOOL": true
            }
        }
    }
    
  5. Prüfen Sie, ob die Änderungen in die Spanner-Tabelle übernommen wurden.

    gcloud spanner databases execute-sql migrationdb \
        --instance=spanner-migration \
        --sql="SELECT * FROM Migration WHERE Username='my-test-username'"
    

    Die Ausgabe sieht so aus:

    Username          PointsEarned  ReminderDate  Subscribed  Zipcode
    my-test-username  4500          None          True
    
  6. Löschen Sie das Testelement aus der Amazon DynamoDB-Quelltabelle.

    aws dynamodb delete-item \
        --table-name Migration \
        --key '{"Username": {"S":"my-test-username"}}'
    
  7. Prüfen Sie, ob die entsprechende Zeile aus der Spanner-Tabelle gelöscht wurde. Wenn die Änderung übernommen wurde, gibt der folgende Befehl keine Zeilen zurück:

    gcloud spanner databases execute-sql migrationdb \
        --instance=spanner-migration \
        --sql="SELECT * FROM Migration WHERE Username='my-test-username'"
    

Verschränkte Tabellen verwenden

Spanner unterstützt das Konzept der verschränkten Tabellen. Dies ist ein Entwurfsmodell, bei dem ein Element der obersten Ebene mehrere verschachtelte Elemente enthält, die sich auf das Element der obersten Ebene beziehen. Beispiel: Ein Kunde und seine Bestellungen oder ein Spieler und seine Spielergebnisse. Wenn Ihre Amazon DynamoDB-Quelltabelle einen Primärschlüssel verwendet, der sich aus einem Hash-Schlüssel und einem Bereichsschlüssel zusammensetzt, können Sie ein verschränktes Tabellenschema modellieren, wie im folgenden Diagramm dargestellt. Mit dieser Struktur können Sie für die verschränkte Tabelle effiziente Abfragen durchführen, während Sie Felder in der übergeordneten Tabelle zusammenführen.

Bild: Nutzertabelle verglichen mit Bestellungstabelle

Sekundäre Indexe anwenden

Als Best Practice wird empfohlen, sekundäre Indexe auf Spanner-Tabellen anzuwenden, nachdem die Daten geladen wurden. Da die Replikation jetzt funktioniert, richten Sie ein sekundärer Index um Abfragen zu beschleunigen. Wie Spanner-Tabellen sind sekundäre Spanner-Indexe vollständig konsistent. Sie sind nicht letztendlich konsistent, wie es in vielen NoSQL-Datenbanken üblich ist. Diese Funktion kann die Entwicklung Ihrer Anwendung vereinfachen.

Führen Sie eine Abfrage aus, die keine Indexe verwendet. Dabei suchen Sie nach den obersten n Treffern für einen bestimmten Spaltenwert. Dies ist eine gängige Abfrage zur Verbesserung der Datenbankeffizienz in Amazon DynamoDB.

  1. Rufen Sie Spanner auf.

    Spanner aufrufen

  2. Klicken Sie auf Spanner Studio.

    Bild: Schaltfläche "Query" (Abfrage)

  3. Geben Sie in das Feld Abfrage den folgenden Wert ein und klicken Sie auf Abfrage ausführen.

    SELECT Username,PointsEarned
      FROM Migration
     WHERE Subscribed=true
       AND ReminderDate > DATE_SUB(DATE(current_timestamp()), INTERVAL 14 DAY)
     ORDER BY ReminderDate DESC
     LIMIT 10
    

    Nachdem die Abfrage ausgeführt wurde, klicken Sie auf Erklärung und vergleichen Gescannte Zeilen mit Zurückgegebene Zeilen. Ohne Index scannt Spanner die gesamte Tabelle, um eine kleine Teilmenge von Daten zurückzugeben, die der Abfrage entsprechen.

    Bild: Gescannte Zeilen verglichen mit zurückgegebenen Zeilen

  4. Wenn diese Abfrage regelmäßig ausgeführt wird, sollten Sie einen zusammengesetzten Index für die Spalten "Subscribed" und "ReminderDate" erstellen. Wählen Sie in der Spanner-Konsole im linken Navigationsbereich Indexe aus und klicken Sie auf Index erstellen.

  5. Geben Sie in das Textfeld die Indexdefinition ein.

    CREATE INDEX SubscribedDateDesc
    ON Migration (
      Subscribed,
      ReminderDate DESC
    )
    
  6. Klicken Sie auf Erstellen, um den Erstellvorgang der Datenbank im Hintergrund zu starten.

    Bild: Schemaaktualisierung wird durchgeführt

  7. Nachdem der Index erstellt wurde, führen Sie die Abfrage noch einmal aus und fügen den Index hinzu.

    SELECT Username,PointsEarned
      FROM Migration@{FORCE_INDEX=SubscribedDateDesc}
     WHERE Subscribed=true
       AND ReminderDate > DATE_SUB(DATE(current_timestamp()), INTERVAL 14 DAY)
     ORDER BY ReminderDate DESC
     LIMIT 10
    

    Untersuchen Sie noch einmal die Erklärung der Abfrage. Die Anzahl der gescannten Zeilen (Rows scanned) ist weniger geworden. Die Anzahl der in jedem Schritt zurückgegebenen Zeilen (Rows returned) entspricht dem von der Abfrage zurückgegebenen Wert.

    Bild: Erklärung der Abfrage

Verschränkte Indexe

Sie können in Spanner verschränkte Indexe einrichten. Die im vorherigen Abschnitt beschriebenen sekundären Indexe befinden sich auf der Stammebene der Datenbankhierarchie und nutzen Indexe genauso wie eine herkömmliche Datenbank. Ein verschränkter Index befindet sich im Kontext seiner verschränkten Zeile. Weitere Informationen finden Sie unter Indexoptionen finden Sie weitere Informationen dazu, wo verschränkte Indexe angewendet werden können.

An Ihr Datenmodell anpassen

Wenn Sie den Migrationsteil dieser Anleitung auf Ihre eigene Situation anwenden möchten, müssen Sie die Apache Beam-Quelldateien anpassen. Das Quellschema sollte jedoch nicht während des eigentlichen Migrationsfensters geändert werden, da sonst möglicherweise Daten verloren gehen.

  1. Verwenden Sie GSON, um eingehende JSON-Dateien zu parsen und Mutationen zu erstellen. Passen Sie die JSON-Definition an Ihre Daten an.

    public static class Record implements Serializable {
    
      private Item Item;
    
    }
    
    public static class Item implements Serializable {
    
      private Username Username;
      private PointsEarned PointsEarned;
      private Subscribed Subscribed;
      private ReminderDate ReminderDate;
      private Zipcode Zipcode;
    
    }
    
    public static class Username implements Serializable {
    
      private String S;
    
    }
    
    public static class PointsEarned implements Serializable {
    
      private String N;
    
    }
    
    public static class Subscribed implements Serializable {
    
      private String BOOL;
    
    }
    
    public static class ReminderDate implements Serializable {
    
      private String S;
    
    }
    
    public static class Zipcode implements Serializable {
    
      private String N;
    
    }
  2. Passen Sie die entsprechende JSON-Zuordnung an.

    mutation.set("Username").to(record.Item.Username.S);
    
    Optional.ofNullable(record.Item.Zipcode).ifPresent(x -> {
      mutation.set("Zipcode").to(Integer.parseInt(x.N));
    });
    
    Optional.ofNullable(record.Item.Subscribed).ifPresent(x -> {
      mutation.set("Subscribed").to(Boolean.parseBoolean(x.BOOL));
    });
    
    Optional.ofNullable(record.Item.ReminderDate).ifPresent(x -> {
      mutation.set("ReminderDate").to(Date.parseDate(x.S));
    });
    
    Optional.ofNullable(record.Item.PointsEarned).ifPresent(x -> {
      mutation.set("PointsEarned").to(Integer.parseInt(x.N));
    });

In den vorherigen Schritten haben Sie den Apache Beam-Quellcode für den Bulk-Import geändert. Der Quellcode für den Streamingteil der Pipeline muss auf ähnliche Weise geändert werden. Abschließend müssen Sie die Tabellenerstellungsskripts, -schemas und -indexe Ihrer Spanner-Zieldatenbank anpassen.

Bereinigen

Damit Ihrem Google Cloud-Konto die in dieser Anleitung verwendeten Ressourcen nicht in Rechnung gestellt werden, können Sie entweder das Projekt löschen, das die Ressourcen enthält, oder das Projekt beibehalten und die einzelnen Ressourcen löschen.

Projekt löschen

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

AWS-Ressourcen löschen

Wenn das AWS-Konto nicht nur für diese Anleitung verwendet wird, sollten Sie beim Löschen der folgenden Ressourcen vorsichtig vorgehen:

  1. Löschen Sie die DynamoDB-Tabelle namens Migration.
  2. Löschen Sie den Amazon S3-Bucket und die Lambda-Funktion, die Sie bei den Migrationsschritten erstellt haben.
  3. Löschen Sie zuletzt den für diese Anleitung erstellten AWS IAM-Nutzer.

Nächste Schritte