從 DynamoDB 遷移至 Spanner

本教學介紹如何從 Amazon DynamoDB 遷移到 Spanner。 它主要針對希望從 NoSQL 系統遷移到 Spanner 的應用程式擁有者,Spanner 是一個完全關係型、容錯性強、高度可擴展的 SQL 資料庫系統,支援事務。如果您的 Amazon DynamoDB 資料表在類型和佈局方面使用一致,則對應到 Spanner 非常簡單。如果您的 Amazon DynamoDB 資料表包含任何資料類型和值,遷移到其他 NoSQL 服務(例如 DatastoreFirestore)可能會更簡單。

本教學課程假設您已熟悉資料庫結構定義、資料類型、NoSQL 的基本概念,以及關聯式資料庫系統。此外,本教學課程會執行預先定義的工作來示範遷移作業。完成教學課程後,您可以根據您的環境修改課程中提供的程式碼和步驟。

以下架構圖概略呈現本教學課程中用來遷移資料的元件:

遷移元件的架構圖

目標

  • 將資料從 Amazon DynamoDB 移轉到 Spanner。
  • 建立 Spanner 資料庫和遷移表。
  • 將 NoSQL 結構定義對應至關聯式結構定義。
  • 建立及匯出使用 Amazon DynamoDB 的範例資料集。
  • 在 Amazon S3 和 Cloud Storage 之間轉移資料。
  • 使用資料流將資料載入到 Spanner 中。

費用

本教學課程使用下列 Google Cloud計費元件:

Spanner 的收費是根據您的執行個體中的運算能力以及每月帳單週期內儲存的資料量。在教程中,您將使用這些資源的最小配置,這些資源將在最後被清理。對於實際場景,請估算您的處理量和儲存需求,然後使用 Spanner 執行個體文件 來確定您需要的運算容量。

除了 Google Cloud 資源外,本教學還使用了以下亞馬遜網路服務(AWS)資源:

  • AWS Lambda
  • Amazon S3
  • Amazon DynamoDB

這些服務只有在遷移期間需要用到。完成本教學課程後,請按照相關操作說明清除所有資源,以避免產生不必要的費用。使用AWS 定價計算器估算這些成本。

您可以使用 Pricing Calculator 根據預測用量估算費用。

事前準備

  1. 登入 Google Cloud 帳戶。如果您是 Google Cloud新手,歡迎 建立帳戶,親自評估產品在實際工作環境中的成效。新客戶還能獲得價值 $300 美元的免費抵免額,可用於執行、測試及部署工作負載。
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

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

    Roles required to enable APIs

    To enable APIs, you need the serviceusage.services.enable permission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.

    Enable the APIs

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

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  6. Verify that billing is enabled for your Google Cloud project.

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

    Roles required to enable APIs

    To enable APIs, you need the serviceusage.services.enable permission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.

    Enable the APIs

完成本文所述工作後,您可以刪除建立的資源,避免繼續計費,詳情請參閱「清除所用資源」一節。

準備環境

在本教學課程中,您將使用 Cloud Shell 執行指令。Cloud Shell 允許您存取指令列。 Google Cloud並且包含了 Google Cloud CLI 以及您需要的其他工具 Google Cloud 開發。Cloud Shell 初始化可能需要幾分鐘。

  1. 在 Google Cloud 控制台中啟用 Cloud Shell。

    啟用 Cloud Shell

    控制台底部會開啟 Cloud Shell 工作階段,並顯示指令列提示。 Google Cloud Cloud Shell 是已安裝 Google Cloud CLI 的殼層環境,並已針對您目前的專案設定好相關值。工作階段可能要幾秒鐘的時間才能初始化。

  2. 設定預設 Compute Engine 區域,例如:us-central1-b。gcloud config set compute/zone us-central1-b
  3. 複製包含程式碼範例的 GitHub 存放區。git clone https://github.com/GoogleCloudPlatform/dynamodb-spanner-migration.git
  4. 進入克隆的目錄。 cd dynamodb-spanner-migration
  5. 建立一個 Python 虛擬環境。 使用 pip3 安裝 virtualenv virtualenv env
  6. 激活虛擬環境。 source env/bin/activate
  7. 安裝必要的 Python 模組。 使用 pip3 安裝 -r requirements.txt

設定 AWS 存取權

在本教學課程中,您將建立及刪除 Amazon DynamoDB 資料表、Amazon S3 值區和其他資源。如要存取這些資源,您必須先建立必要的 AWS 身分與存取權管理 (IAM) 權限。您可以使用測試或沙箱 AWS 帳戶,避免影響相同帳戶中的實際工作環境資源。

為 AWS Lambda 建立 AWS IAM 角色

在本節中,您將建立 AWS IAM 角色,在本教學課程後面的步驟中供 AWS Lambda 使用。

  1. 在 AWS 主控台中,前往「IAM」專區按一下 [Roles],然後選取 [Create role]
  2. 在「Trusted entity type」(信任的實體類型) 下方,確認已選取「AWS service」(AWS 服務)
  3. 用例 下,選擇 Lambda,然後按一下 下一步
  4. 權限策略 篩選框中,輸入 AWSLambdaDynamoDBExecutionRole 並按 Return 進行搜尋。
  5. 選取 AWSLambdaDynamoDBExecutionRole 複選框,然後按一下 下一步
  6. 角色名稱 方塊中,輸入 dynamodb-spanner-lambda-role,然後按 建立角色

建立 AWS IAM 使用者

按照下列步驟建立可透過程式存取 AWS 資源的 AWS IAM 使用者;這些資源在整個教學課程中都會用到。

  1. 當您仍在 AWS 控制台的 IAM 部分時,按一下 使用者,然後選擇 新增使用者
  2. 使用者名稱 框中,輸入 dynamodb-spanner-migration
  3. 存取類型 下,選取 存取金鑰 - 程式化存取 左側的核取方塊。

  4. 點選 [Next: Permissions] (下一步:權限)。

  5. 按一下「Attach existing policies directly」,然後使用「Search」方塊篩選,並勾選下列三項政策旁的核取方塊:

    • AmazonDynamoDBFullAccess
    • AmazonS3FullAccess
    • AWSLambda_FullAccess
  6. 點選 下一步:標籤下一步:評論,然後點選 建立使用者

  7. 按一下 [Show] 查看憑證。系統會顯示新建立使用者的存取金鑰 ID 和存取密鑰。您需要在下一節使用憑證,因此請暫時將這個視窗保持開啟。這些憑證可用來變更您的帳戶和影響您的環境,因此請妥善儲存。在本教學結束時,您可以刪除 IAM 用戶

設定 AWS 指令列介面

  1. 在 Cloud Shell 中設定 AWS 指令列介面 (CLI)。

    aws configure
    

    畫面會出現以下輸出結果:

    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]:
    
    • 輸入您建立的 AWS IAM 帳戶中的 ACCESS KEY IDSECRET ACCESS KEY
    • 預設區域名稱 欄位中,輸入 us-west-2。並保留其他欄位的預設值。
  2. 關閉 AWS IAM 主控台視窗。

瞭解資料模型

以下部分概述了 Amazon DynamoDB 和 Spanner 的資料類型、鍵和索引之間的異同。

資料類型

Spanner 使用 GoogleSQL 資料類型。下表描述了 Amazon DynamoDB 資料類型 如何對應到 Spanner 資料類型

Amazon DynamoDB Spanner
數字 視精確度或預定用途而定,可對應至 INT64、FLOAT64、TIMESTAMP 或 DATE。
字串 字串
布林值 BOOL
空值 沒有明確的類型。資料欄可包含空值。
二進位檔 位元組
集合 陣列
對應和清單 如果結構一致並可使用資料表 DDL 語法描述,則為 Struct。

主鍵

Amazon DynamoDB 主鍵會產生唯一性,並可為雜湊鍵或是範圍鍵和雜湊鍵的組合。本教學首先示範如何移轉主鍵為雜湊鍵的 Amazon DynamoDB 表。這個雜湊鍵將成為 Spanner 表的主鍵。在下方的交錯式資料表一節中,您將模擬 Amazon DynamoDB 資料表使用的主鍵是由雜湊鍵和範圍鍵組成的情形。

次要索引

Amazon DynamoDB 和 Spanner 都支援針對非主鍵屬性建立索引。請記下 Amazon DynamoDB 表中的任何二級索引,以便您可以在 Spanner 表中建立它們,這將在本教學的 後續章節 中介紹。

範例資料表

為了方便本教學的講解,您需要將以下範例表格從 Amazon DynamoDB 移轉到 Spanner:

Amazon DynamoDB Spanner
資料表名稱 Migration Migration
主鍵 "Username" : String "Username" : STRING(1024)
鍵類型 雜湊 不適用
其他欄位 Zipcode: Number Subscribed: Boolean ReminderDate: String PointsEarned: Number Zipcode: INT64 Subscribed: BOOL ReminderDate: DATE PointsEarned: INT64

準備 Amazon DynamoDB 表

在本節中,您將建立 Amazon DynamoDB 來源資料表並填入資料。

  1. 在 Cloud Shell 中,建立使用範例資料表屬性的 Amazon DynamoDB 資料表。

    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. 確認資料表的狀態為 ACTIVE

    aws dynamodb describe-table --table-name Migration \
        --query 'Table.TableStatus'
    
  3. 在資料表中填入範例資料。

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

可建立 Spanner 資料庫

您建立了一個運算能力最小的 Spanner 實例:100 個處理單元。此運算能力足以滿足本教程的範圍。對於生產環境部署,請參閱 Spanner 實例 的文檔,以確定滿足資料庫效能要求的適當運算容量。

在本例中,您將在建立資料庫的同時建立資料庫結構定義。您也可以在建立資料庫後更新結構定義,這種做法很常見。

  1. 在設定預設 Compute Engine 區域的相同區域中建立 Spanner 實例。例如 us-central1

    gcloud beta spanner instances create spanner-migration \
        --config=regional-us-central1 --processing-units=100 \
        --description="Migration Demo"
    
  2. 在 Spanner 實例中建立一個資料庫,並新增範例表。

    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)"
    

準備遷移

接下來的章節將向您展示如何匯出 Amazon DynamoDB 來源資料表,並設定 Pub/Sub 複製以捕獲匯出過程中資料庫發生的任何變更。

將變更串流至 Pub/Sub

您必須使用 AWS Lambda 函式,將資料庫變更串流傳入 Pub/Sub。

  1. 在 Cloud Shell 中,針對來源資料表啟用 Amazon DynamoDB 串流。

    aws dynamodb update-table --table-name Migration \
        --stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES
    
  2. 設定 Pub/Sub 主題來接收變更。

    gcloud pubsub topics create spanner-migration
    

    畫面會出現以下輸出結果:

    Created topic [projects/your-project/topics/spanner-migration].
    
  3. 建立一個 IAM 服務帳戶,將表格更新推送到 Pub/Sub 主題。

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

    畫面會出現以下輸出結果:

    Created service account [spanner-migration].
    
  4. 建立 IAM 政策綁定,以便服務帳戶有權發布到 Pub/Sub。將 GOOGLE_CLOUD_PROJECT 替換為您的 Google Cloud 項目名稱。

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

    畫面會出現以下輸出結果:

    bindings:
    (...truncated...)
    - members:
      - serviceAccount:spanner-migration@solution-z.iam.gserviceaccount.com
      role: roles/pubsub.publisher
    
  5. 建立服務帳戶的憑證。

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

    畫面會出現以下輸出結果:

    created key [5e559d9f6bd8293da31b472d85a233a3fd9b381c] of type [json] as [credentials.json] for [spanner-migration@your-project.iam.gserviceaccount.com]
    
  6. 準備及包裝 AWS Lambda 函式,以將 Amazon DynamoDB 資料表變更推送至 Pub/Sub 主題。

    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. 建立變數,以針對您先前建立的 Lambda 執行角色擷取其 Amazon Resource Name (ARN)。

    LAMBDA_ROLE=$(aws iam list-roles \
        --query 'Roles[?RoleName==`dynamodb-spanner-lambda-role`].[Arn]' \
        --output text)
    
  8. 使用 pubsub-lambda.zip 套件建立 AWS Lambda 函數。

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

    畫面會出現以下輸出結果:

    {
        "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. 建立變數,以針對您的資料表擷取 Amazon DynamoDB 串流的 ARN。

    STREAMARN=$(aws dynamodb describe-table \
        --table-name Migration \
        --query "Table.LatestStreamArn" \
        --output text)
    
  10. 將 Lambda 函式附加至 Amazon DynamoDB 資料表。

    aws lambda create-event-source-mapping --event-source ${STREAMARN} \
        --function-name dynamodb-spanner-lambda --enabled \
        --starting-position TRIM_HORIZON
    
  11. 如要最佳化測試期間的回應速度,請在上述指令的結尾加上 --batch-size 1,這樣每當您建立、更新或刪除項目時就會觸發函式。

    您會看到類似下方的輸出內容:

    {
        "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 資料表匯出至 Amazon S3

  1. 在 Cloud Shell 中,針對您要在下方幾節中使用的值區名稱建立變數。

    BUCKET=${DEVSHELL_PROJECT_ID}-dynamodb-spanner-export
    
  2. 建立一個 Amazon S3 儲存桶來接收 DynamoDB 匯出資料。

    aws s3 mb s3://${BUCKET}
    
  3. 在 AWS 管理主控台中,前往 DynamoDB,然後點選「Tables」

  4. 按一下「Migration」資料表。

  5. 出口和串流媒體點擊 Tab 鍵匯出到 S3

  6. 如果提示,請啟用 point-in-time-recovery (PITR)。

  7. 點擊 瀏覽 S3 選擇您先前建立的 S3 儲存桶。

  8. 按一下 [匯出]

  9. 點選刷新 圖示更新匯出作業的狀態。匯出任務需要幾分鐘才能完成。

    流程結束後,查看輸出桶。

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

    預計此步驟大約需要 5 分鐘。完成後,您會看到類似如下的輸出:

    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
    

執行遷移作業

現在 Pub/Sub 交付已經就緒,您可以推送導出後發生的任何表格變更。

將匯出的資料表複製到 Cloud Storage

  1. 在 Cloud Shell 中,建立一個 Cloud Storage 儲存桶來接收從 Amazon S3 匯出的檔案。

    gcloud storage buckets create gs://${BUCKET}
    
  2. 將 Amazon S3 中的檔案同步至 Cloud Storage。對於大多數複製操作,rsync 指令是有效的。如果您的匯出檔案很大(幾 GB 或更多),請使用 雲端儲存傳輸服務 在背景管理傳輸。

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

批次匯入資料

  1. 若要將匯出檔案中的資料寫入 Spanner 表,請執行帶有範例 Apache Beam 程式碼的 Dataflow 作業。

    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. 若要查看匯入作業的進度,請在 Google Cloud 控制台中前往資料流。

      前往 Dataflow

    2. 當工作正在執行時,您可以查看執行圖來檢查記錄。請按一下「Status」(狀態) 為「Running」(執行中) 的工作。

      執行匯入工作

  2. 按一下各個階段可查看已處理完畢的元素數量。如果所有階段都顯示「Succeeded」(成功),表示已匯入完成。在各個階段中顯示為處理完畢的元素數量,與在 Amazon DynamoDB 資料表中建立的元素數量相同。

    匯入工作的各個成功階段

  3. 確認目標 Spanner 資料表中的記錄數量與 Amazon DynamoDB 資料表中的項目數量一致。

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

    畫面會出現以下輸出結果:

    $ 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. 在每個資料表中取樣隨機項目,確保資料皆一致。

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

    畫面會出現以下輸出結果:

     Username: aadams4495
     PointsEarned: 5247
     ReminderDate: 2022-03-14
     Subscribed: True
     Zipcode: 58057
    
  5. 使用與上一個步驟 Spanner 查詢傳回的相同的 Username 查詢 Amazon DynamoDB 表。例如:aallen2538。該值僅適用於資料庫中的範例資料。

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

    其他欄位的值應與 Spanner 輸出內容一致。畫面會出現以下輸出結果:

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

複製新的變更

批次匯入工作完成後,請設定串流工作,將來源資料表中持續發生的更新寫入 Spanner。您 訂閱 Pub/Sub 的活動並將其寫入 Spanner

您建立的 Lambda 函式已經過設定,可擷取來源 Amazon DynamoDB 資料表的變更,並將其發布至 Pub/Sub。

  1. 建立對 AWS Lambda 發送事件的 Pub/Sub 主題的訂閱。

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

    畫面會出現以下輸出結果:

    Created subscription [projects/your-project/subscriptions/spanner-migration].
    
  2. 若要將 Pub/Sub 中的變更串流傳輸到 Spanner 表並寫入其中,請從 Cloud Shell 執行 Dataflow 作業。

    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. 批次載入 步驟類似,若要查看作業進度,請在 Google Cloud 控制台中前往資料流。

      前往 Dataflow

    2. 按一下「Status」(狀態) 為「Running」(執行中) 的工作。

      執行工作

      處理圖會顯示和之前類似的輸出內容,但每個已處理完畢的項目會計入狀態視窗中顯示的數量。系統延遲時間是 Spanner 資料表反映變更前的概略預期延遲時間。

      因延遲時間而執行流程

您在批次載入階段執行的 Dataflow 作業是一個有限的輸入集,也稱為 有界 資料集。這個 Dataflow 工作會使用 Pub/Sub 做為串流來源,並視為「不受限」。有關這兩種類型的資料來源的更多信息,請參閱 Apache Beam 程式設計指南 中的 PCollections 部分。 此步驟中的資料流作業旨在保持活動狀態,因此完成後不會終止。串流 Dataflow 工作會繼續處於「Running」(執行中) 狀態,而非「Succeeded」(成功) 狀態。

確認複製設定

您對來源表進行了一些更改,以驗證這些更改是否已複製到 Spanner 表。

  1. 在 Spanner 中查詢不存在的行。

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

    該操作不會傳回任何結果。

  2. 透過您在 Spanner 查詢中使用的鍵,在 Amazon DynamoDB 中建立記錄。如果指令執行成功,則不會有任何輸出結果。

    aws dynamodb put-item \
        --table-name Migration \
        --item '{"Username" : {"S" : "my-test-username"}, "Subscribed" : {"BOOL" : false}}'
    
  3. 再次執行相同的查詢,確認該資料列現已在 Spanner 中。

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

    輸出結果會顯示插入的資料列:

    Username: my-test-username
    PointsEarned: None
    ReminderDate: None
    Subscribed: False
    Zipcode:
    
  4. 變更原始項目的部分屬性,並更新 Amazon DynamoDB 資料表。

    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
    

    您會看到類似下方的輸出內容:

    {
        "Attributes": {
            "Username": {
                "S": "my-test-username"
            },
            "PointsEarned": {
                "N": "4500"
            },
            "Subscribed": {
                "BOOL": true
            }
        }
    }
    
  5. 確認變更已推送到 Spanner 資料表。

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

    畫面會出現以下輸出結果:

    Username          PointsEarned  ReminderDate  Subscribed  Zipcode
    my-test-username  4500          None          True
    
  6. 刪除 Amazon DynamoDB 來源資料表中的測試項目。

    aws dynamodb delete-item \
        --table-name Migration \
        --key '{"Username": {"S":"my-test-username"}}'
    
  7. 確認 Spanner 表中對應的行已被刪除。如果變更已推送完畢,以下指令不會傳回任何資料列:

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

使用交錯式資料表

Spanner 支援交錯式資料表的概念。這是一個設計模型,其中頂級項目有多個與該頂級項目相關的嵌套項目,例如客戶及其訂單,或玩家及其遊戲得分。如果您的 Amazon DynamoDB 來源資料表使用由雜湊鍵和範圍鍵組成的主鍵,您可以使用交錯式資料表結構定義做為模型,如下圖所示。這個結構可讓您有效率地查詢交錯式資料表,同時彙整父項資料表中的欄位。

使用者資料表與訂單資料表的比較

套用次要索引

這是一個最佳實踐將二級索引套用至 Spanner 表你載入數據。現在複製功能正常,您可以設定一個 輔助索引 來加快查詢速度。與 Spanner 資料表相同,Spanner 次要索引完全一致。而「不」具有許多 NoSQL 資料庫中常見的最終一致性。這個特性有助於簡化應用程式設計。

執行一個不使用任何索引的查詢。您正在尋找給定特定列值的前 N 次出現。這可提高資料庫效率,因此在 Amazon DynamoDB 中是常見的查詢。

  1. 去 Spanner。

    前往 Spanner

  2. 點選 Spanner Studio

    查詢按鈕

  3. 在「Query」(查詢) 欄位中輸入以下查詢,然後按一下 [Run query] (執行查詢)

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

    查詢執行完畢後,按一下 [Explanation] (說明) 並記下「Rows scanned」(掃描的資料列) 數量和「Rows returned」(傳回的資料列) 數量。如果沒有索引,Spanner 會掃描整個資料表,傳回與查詢相符的一小部分資料。

    掃描的資料列數量與傳回的資料列數量的比較

  4. 如果這是常用查詢,請針對 Subscribed 和 ReminderDate 資料欄建立複合式索引。在 Spanner 控制台上,選擇左側導覽窗格中的 Indexes,然後按一下 Create Index

  5. 在文字方塊中輸入索引定義。

    CREATE INDEX SubscribedDateDesc
    ON Migration (
      Subscribed,
      ReminderDate DESC
    )
    
  6. 如要開始在背景建構資料庫,請按一下 [Create] (建立)

    正在更新結構定義

  7. 索引建立完畢後,請再次執行查詢並新增索引。

    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
    

    再次查看查詢說明。您會發現「Rows scanned」(掃描的資料列) 數量減少了,每一步傳回的 與查詢傳回的行數一致。

    查詢說明

交錯式索引

您可以在 Spanner 中設定交錯索引。本文討論的二級指標上一節它們位於資料庫層次結構的根部,並且它們使用索引的方式與傳統資料庫相同。交錯式索引則與其交錯式資料列相關。請參閱索引選項進一步瞭解如何套用交錯式索引。

針對資料模型進行調整

如要根據您自己的情況調整本教學課程的遷移設定,請修改您的 Apache Beam 來源檔案。在實際進行遷移的期間,請不要變更來源結構定義,否則可能會遺失資料。

  1. 要解析傳入的 JSON 並建立 mutation,請使用 GSON。 調整 JSON 定義以符合您的資料。

    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. 調整相對的 JSON 對應。

    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));
    });

在前面的步驟中,您修改了 Apache Beam 的原始程式碼以進行批次匯入。 以類似的方式修改管道流處理部分的原始碼。最後,調整 Spanner 目標資料庫的表格建立腳本、架構和索引。

清除所用資源

如要避免系統向您的 Google Cloud 帳戶收取本教學課程所用資源的費用,請刪除含有相關資源的專案,或者保留專案但刪除個別資源。

刪除專案

  1. 前往 Google Cloud 控制台的「Manage resources」(管理資源) 頁面。

    前往「Manage resources」(管理資源)

  2. 在專案清單中選取要刪除的專案,然後點選「Delete」(刪除)
  3. 在對話方塊中輸入專案 ID,然後按一下 [Shut down] (關閉) 以刪除專案。

刪除 AWS 資源

如果您會在本教學課程以外的地方使用您的 AWS 帳戶,刪除下列資源時請務必小心:

  1. 刪除名為 MigrationDynamoDB 表
  2. 刪除您在遷移步驟中建立的 Amazon S3 儲存桶Lambda 函數
  3. 最後,刪除您在本教學課程中建立的 AWS IAM 使用者。

後續步驟