העברה מ-DynamoDB ל-Spanner

במדריך הזה נסביר איך להעביר נתונים מ-Amazon DynamoDB אל Spanner. הוא מיועד בעיקר לבעלי אפליקציות שרוצים לעבור ממערכת NoSQL ל-Spanner, מערכת מסד נתונים SQL רלציונית לחלוטין, סובלנית לתקלות וניתנת להרחבה רבה, שתומכת בטרנזקציות. אם אתם משתמשים בטבלאות Amazon DynamoDB באופן עקבי, מבחינת הסוגים והפריסה, המיפוי ל-Spanner הוא פשוט. אם הטבלאות שלכם ב-Amazon DynamoDB מכילות סוגים וערכים שרירותיים של נתונים, יכול להיות שיהיה לכם פשוט יותר לעבור לשירותי NoSQL אחרים, כמו Datastore או Firestore.

במדריך הזה אנחנו מניחים שאתם מכירים סכימות של מסדי נתונים, סוגי נתונים, את היסודות של NoSQL ומערכות של מסדי נתונים רלציוניים. המדריך מתבסס על הרצת משימות מוגדרות מראש כדי לבצע העברה לדוגמה. אחרי שתסיימו את ההדרכה, תוכלו לשנות את הקוד והשלבים שסופקו כדי להתאים לסביבה שלכם.

בתרשים הארכיטקטורה הבא מפורטים הרכיבים שבהם נעשה שימוש במדריך להעברת נתונים:

תרשים ארכיטקטורה של רכיבי ההעברה

מטרות

  • העברת נתונים מ-Amazon DynamoDB ל-Spanner.
  • יוצרים מסד נתונים של Spanner וטבלת מיגרציה.
  • מיפוי סכימת NoSQL לסכימה רלציונית.
  • יוצרים ומייצאים מערך נתונים לדוגמה שמשתמש ב-Amazon DynamoDB.
  • העברת נתונים בין Amazon S3 לבין Cloud Storage.
  • שימוש ב-Dataflow כדי לטעון נתונים ל-Spanner.

עלויות

במדריך הזה השתמשנו ברכיבים הבאים של Google Cloud, והשימוש בהם כרוך בתשלום:

החיובים ב-Spanner מבוססים על כמות קיבולת המחשוב במופע ועל כמות הנתונים שאוחסנו במהלך מחזור החיוב החודשי. במהלך המדריך, תשתמשו בהגדרה מינימלית של המשאבים האלה, שיימחקו בסוף. כדי להעריך את נפח התפוקה ואת דרישות האחסון שלכם בתרחישים מהעולם האמיתי, תוכלו להיעזר במסמכי המידע על מופעי Spanner כדי לקבוע את כמות קיבולת המחשוב שאתם צריכים.

בנוסף Google Cloud למשאבים, במדריך הזה נעשה שימוש במשאבים הבאים של Amazon Web Services‏ (AWS):

  • AWS Lambda
  • Amazon S3
  • Amazon DynamoDB

השירותים האלה נדרשים רק במהלך תהליך ההעברה. בסיום המדריך, פועלים לפי ההוראות כדי למחוק את כל המשאבים, וכך למנוע חיובים מיותרים. כדי להעריך את העלויות האלה, אפשר להשתמש במחשבון התמחור של AWS.

כדי ליצור הערכת עלויות על סמך השימוש החזוי, אתם יכולים להשתמש במחשבון התמחור.

לפני שמתחילים

  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 Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. 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 Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. 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

    בחלק התחתון של Google Cloud המסוף יתחיל סשן של Cloud Shell ותופיע הודעה של שורת הפקודה. Cloud Shell היא סביבת מעטפת שבה ה-CLI של Google Cloud מותקן ומוגדרים ערכים לפרויקט הקיים. הסשן יופעל תוך כמה שניות.

  2. מגדירים את ברירת המחדל לתחום (zone) של 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 install virtualenv virtualenv env
  6. מפעילים את הסביבה הווירטואלית. source env/bin/activate
  7. מתקינים את מודולי Python הנדרשים. pip3 install -r requirements.txt

הגדרת גישה ל-AWS

במדריך הזה תלמדו איך ליצור ולמחוק טבלאות של Amazon DynamoDB, דליים של Amazon S3 ומשאבים אחרים. כדי לגשת למשאבים האלה, קודם צריך ליצור את ההרשאות הנדרשות ב-AWS Identity and Access Management (IAM). כדי להימנע מהשפעה על משאבי הייצור באותו חשבון, אפשר להשתמש בחשבון בדיקה או בחשבון ארגז חול של AWS.

יצירת תפקיד AWS IAM עבור AWS Lambda

בקטע הזה יוצרים תפקיד AWS IAM ש-AWS Lambda משתמש בו בשלב מאוחר יותר במדריך.

  1. במסוף AWS, עוברים לקטע IAM, לוחצים על Roles ואז על Create role.
  2. בקטע Trusted entity type (סוג ישות מהימנה), מוודאים שהאפשרות AWS service (שירות AWS) נבחרה.
  3. בקטע תרחיש לדוגמה, בוחרים באפשרות Lambda ולוחצים על הבא.
  4. בתיבת הסינון Permission policies (מדיניות הרשאות), מזינים AWSLambdaDynamoDBExecutionRole ומקישים על Return כדי לחפש.
  5. מסמנים את התיבה AWSLambdaDynamoDBExecutionRole ולוחצים על הבא.
  6. בתיבה שם התפקיד מזינים dynamodb-spanner-lambda-role ולוחצים על יצירת תפקיד.

יצירת משתמש AWS IAM

כדי ליצור משתמש AWS IAM עם גישה פרוגרמטית למשאבי AWS, שנעשה בהם שימוש לאורך המדריך, פועלים לפי השלבים הבאים.

  1. בקטע IAM במסוף AWS, לוחצים על Users ואז על Add users.
  2. בתיבה שם משתמש, מזינים dynamodb-spanner-migration.
  3. בקטע סוג הגישה, מסמנים את תיבת הסימון שמימין לאפשרות מפתח גישה – גישה באמצעות תוכנה.

  4. לוחצים על הבא: הרשאות.

  5. לוחצים על Attach existing policies directly (צירוף מדיניות קיימת באופן ישיר), משתמשים בתיבת Search (חיפוש) כדי לסנן, ומסמנים את תיבת הסימון לצד כל אחת משלוש המדיניות הבאות:

    • AmazonDynamoDBFullAccess
    • AmazonS3FullAccess
    • AWSLambda_FullAccess
  6. לוחצים על הבא: תגים ואז על הבא: בדיקה, ואז על יצירת משתמש.

  7. לוחצים על הצגה כדי לראות את פרטי הכניסה. מזהה מפתח הגישה ומפתח הגישה הסודי מוצגים עבור המשתמש החדש שנוצר. בינתיים משאירים את החלון הזה פתוח כי פרטי הכניסה נחוצים בקטע הבא. חשוב לאחסן את פרטי הכניסה האלה בצורה מאובטחת, כי בעזרתם אפשר לבצע שינויים בחשבון ולהשפיע על הסביבה. בסוף המדריך הזה, תוכלו למחוק את משתמש ה-IAM.

הגדרת ממשק שורת הפקודה של AWS

  1. ב-Cloud Shell, מגדירים את ממשק שורת הפקודה (CLI) של AWS.

    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]:
    
    • מזינים את ACCESS KEY ID ו-SECRET ACCESS KEY מחשבון AWS IAM שיצרתם.
    • בשדה שם אזור ברירת המחדל, מזינים us-west-2. משאירים את ערכי ברירת המחדל בשאר השדות.
  2. סוגרים את חלון מסוף AWS IAM.

הסבר על מודל הנתונים

בקטע הבא מפורטים קווי הדמיון וההבדלים בין סוגי נתונים, מפתחות ואינדקסים ב-Amazon DynamoDB וב-Spanner.

סוגי הנתונים

ב-Spanner נעשה שימוש בסוגי נתונים של GoogleSQL. בטבלה הבאה מוסבר איך סוגי הנתונים של Amazon DynamoDB ממופים לסוגי הנתונים של Spanner.

Amazon DynamoDB Spanner
מספר בהתאם לרמת הדיוק או לשימוש המיועד, יכול להיות שהמיפוי יהיה ל-INT64,‏ FLOAT64,‏ TIMESTAMP או DATE.
String String
בוליאני BOOL
Null אין סוג מפורש. העמודות יכולות להכיל ערכי null.
בינארי בייטים
ערכות מערך
מפה ורשימה ‫Struct אם המבנה עקבי ואפשר לתאר אותו באמצעות תחביר DDL של טבלה.

מפתח ראשי

מפתח ראשי ב-Amazon DynamoDB מבטיח ייחודיות, ויכול להיות מפתח Hash או שילוב של מפתח Hash ומפתח טווח. ההדרכה הזו מתחילה בהדגמה של העברה של טבלת Amazon DynamoDB שהמפתח הראשי שלה הוא מפתח hash. מפתח הגיבוב הזה הופך למפתח הראשי של טבלת Spanner. בהמשך, בקטע על טבלאות משולבות, מוצג מודל של מצב שבו טבלה של Amazon DynamoDB משתמשת במפתח ראשי שמורכב ממפתח hash וממפתח טווח.

אינדקסים משניים

גם Amazon DynamoDB וגם Spanner תומכים ביצירת אינדקס במאפיין שהוא לא מפתח ראשי. חשוב לשים לב לכל האינדקסים המשניים בטבלת Amazon DynamoDB, כדי שתוכלו ליצור אותם בטבלת Spanner, כפי שמוסבר בקטע בהמשך המדריך הזה.

טבלה לדוגמה

כדי להקל על ההדרכה הזו, מעבירים את טבלת הדוגמה הבאה מ-Amazon DynamoDB ל-Spanner:

Amazon DynamoDB Spanner
שם טבלה Migration Migration
מפתח ראשי "Username" : String "Username" : STRING(1024)
סוג מפתח גיבוב (hash) לא רלוונטי
שדות אחרים 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. יוצרים מופע Spanner באותו אזור שבו הגדרתם את ברירת המחדל לתחום (zone) של Compute Engine. לדוגמה, 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. יוצרים משתנה כדי לתעד את שם משאב Amazon‏ (ARN) של תפקיד ההרצה של Lambda שיצרתם קודם.

    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. יוצרים משתנה כדי לתעד את ה-ARN של הזרם ב-Amazon DynamoDB עבור הטבלה.

    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. בכרטיסייה ייצוא ושידור, לוחצים על ייצוא ל-S3.

  6. אם מופיעה בקשה, מפעילים את point-in-time-recovery (שחזור לנקודת זמן).

  7. לוחצים על Browse 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 יעילה. אם קובצי הייצוא גדולים (כמה גיגה-בייט או יותר), כדאי להשתמש בשירות ההעברה של Cloud Storage כדי לנהל את ההעברה ברקע.

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

ייבוא הנתונים באצווה

  1. כדי לכתוב את הנתונים מהקבצים המיוצאים לטבלת Spanner, מריצים משימת Dataflow עם קוד לדוגמה של Apache Beam.

    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. כדי לעקוב אחרי התקדמות משימת הייבוא, עוברים אל Dataflow במסוף Google Cloud .

      מעבר אל Dataflow

    2. בזמן שהעבודה פועלת, אפשר לצפות בתרשים הביצוע כדי לבדוק את היומנים. לוחצים על העבודה שמוצג לגביה הסטטוס פועל.

      הפעלת עבודת ייבוא

  2. אפשר ללחוץ על כל שלב כדי לראות כמה רכיבים עברו עיבוד. הייבוא מסתיים כשבכל השלבים מופיע הכיתוב הצלחה. בכל שלב מוצג אותו מספר של רכיבים שנוצרו בטבלת 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. מריצים שאילתה בטבלת Amazon DynamoDB עם אותו Username שהוחזר מהשאילתה ב-Spanner בשלב הקודם. לדוגמה, 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. יוצרים מינוי לנושא Pub/Sub שאליו AWS Lambda שולח אירועים.

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

    הפלט הבא מופיע:

    Created subscription [projects/your-project/subscriptions/spanner-migration].
    
  2. כדי להזרים את השינויים שמגיעים ל-Pub/Sub לכתיבה בטבלת Spanner, מריצים את משימת Dataflow מ-Cloud Shell.

    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.

      מעבר אל Dataflow

    2. לוחצים על העבודה שהסטטוס שלה הוא פועל.

      משימה שפועלת

      תרשים העיבוד מציג פלט דומה לזה שראינו קודם, אבל כל פריט שעבר עיבוד נספר בחלון הסטטוס. זמן ההשהיה של המערכת הוא אומדן גס של משך העיכוב הצפוי עד שהשינויים יופיעו בטבלת Spanner.

      תהליכים שפועלים בגלל זמן השהיה

משימת Dataflow שהפעלתם בשלב טעינת האצווה הייתה קבוצה סופית של קלט, שנקראת גם מערך נתונים מוגבל. משימת Dataflow הזו משתמשת ב-Pub/Sub כמקור סטרימינג ונחשבת בלתי מוגבלת. מידע נוסף על שני סוגי המקורות האלה זמין בקטע בנושא PCollections במדריך התכנות של Apache Beam. העבודה של Dataflow בשלב הזה אמורה להישאר פעילה, ולכן היא לא מסתיימת כשהיא מסתיימת. עבודת הסטרימינג של 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. יוצרים רשומה ב-Amazon DynamoDB עם אותו מפתח שבו השתמשתם בשאילתת Spanner. אם הפקודה פועלת בהצלחה, לא מוצג פלט.

    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 משתמשת במפתח ראשי שמורכב ממפתח hash וממפתח טווח, אתם יכולים ליצור מודל של סכימת טבלה משולבת כמו שמוצג בתרשים הבא. המבנה הזה מאפשר לכם לבצע שאילתות ביעילות בטבלה המשלבת, תוך צירוף שדות בטבלת ההורה.

השוואה בין טבלת המשתמשים לטבלת ההזמנות

החלת אינדקסים משניים

מומלץ להחיל אינדקסים משניים על טבלאות 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
    

    אחרי הפעלת השאילתה, לוחצים על הסבר ורושמים את הערכים של שורות שנסרקו לעומת שורות שהוחזרו. בלי אינדקס, 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 returned בכל שלב זהה למספר שמוחזר על ידי השאילתה.

    הסבר על השאילתה

אינדקסים משולבים

אפשר להגדיר אינדקסים משולבים ב-Spanner. האינדקסים המשניים שמוסברים בקטע הקודם נמצאים ברמה העליונה בהיררכיית מסד הנתונים, והם משתמשים באינדקסים באותו אופן כמו מסד נתונים רגיל. אינדקס משולב נמצא בהקשר של השורה המשולבת שלו. מידע נוסף על המקומות שבהם כדאי להשתמש באינדקסים משולבים זמין במאמר בנושא אפשרויות אינדקס.

התאמה למודל הנתונים

כדי להתאים את חלק ההעברה במדריך הזה למצב שלכם, צריך לשנות את קובצי המקור של Apache Beam. חשוב לא לשנות את סכימת המקור במהלך חלון ההעברה בפועל, אחרת עלולים לאבד נתונים.

  1. כדי לנתח נתוני JSON נכנסים וליצור מוטציות, משתמשים ב-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. כדי למחוק את הפרויקט, כותבים את מזהה הפרויקט בתיבת הדו-שיח ולוחצים על Shut down.

מחיקת משאבים ב-AWS

אם משתמשים בחשבון AWS שלכם מחוץ למדריך הזה, חשוב לנקוט משנה זהירות כשמוחקים את המשאבים הבאים:

  1. תמחק את הטבלה של DynamoDB שנקראת Migration.
  2. מוחקים את קטגוריית Amazon S3 ואת פונקציית Lambda שיצרתם במהלך שלבי ההעברה.
  3. לבסוף, מוחקים את המשתמש ב-AWS IAM שיצרתם במהלך המדריך הזה.

המאמרים הבאים