מעבר מ-App Engine Memcache ל-Cloud Memorystore (מודול 13)

1. סקירה כללית

סדרת הServerless Migration Station של Codelabs (מדריכים מעשיים בקצב עצמי) וסרטונים קשורים נועדו לעזור להעביר מפתחים ללא שרת (serverless) של Google Cloud, באמצעות העברת אפליקציות מדור קודם באמצעות שירותי Google Cloud. כך האפליקציות שלכם יהיו יותר ניידות ויהיו לכם יותר אפשרויות וגמישות, כך שתוכלו להשתלב עם מגוון רחב יותר של מוצרי Cloud ולגשת אליהם בקלות, ולהשדרג בקלות רבה יותר לגרסאות חדשות יותר של שפות. הסדרה מתמקדת בהתחלה במשתמשי Cloud הראשונים, ובעיקר מפתחי App Engine (בסביבה סטנדרטית), אבל היא רחבה מספיק כדי לכלול פלטפורמות אחרות ללא שרת (serverless), כמו Cloud Functions ו-Cloud Run, או במקומות אחרים, אם רלוונטי.

המטרה של ה-Codelab הזה היא להראות למפתחי App Engine של Python 2 איך לעבור מ-App Engine Memcache אל Cloud Memorystore (בשביל Redis). יש גם העברה משתמעת מ-App Engine ndb אל Cloud NDB, אבל הנושא הזה מכסה בעיקר את Codelab של מודול 2; אפשר להיכנס אליו כדי לקבל הוראות מפורטות.

כאן אפשר להבין איך

  • הגדרת מכונת Cloud Memorystore (ממסוף Cloud או מהכלי gcloud)
  • הגדרת מחבר Cloud Serverless VPC Access (ממסוף Cloud או מהכלי gcloud)
  • מעבר מ-App Engine Memcache ל-Cloud Memorystore
  • הטמעת שמירה במטמון באמצעות Cloud Memorystore באפליקציה לדוגמה
  • מעבר מ-App Engine ndb ל-Cloud NDB

למה תזדקק?

סקר

איך תשתמשו במדריך הזה?

לקריאה בלבד לקרוא אותו ולבצע את התרגילים

איזה דירוג מגיע לדעתך לחוויה שלך עם Python?

מתחילים בינונית בקיאים

איזה דירוג מגיע לדעתך לחוויית השימוש שלך בשירותי Google Cloud?

מתחילים בינונית בקיאים

2. רקע

ה-Codelab הזה מדגים איך להעביר אפליקציה לדוגמה מ-App Engine Memcache (ו-NDB) ל-Cloud Memorystore (ול-Cloud NDB). התהליך הזה כרוך בהחלפת יחסי התלות בשירותים בחבילה של App Engine, כדי שהאפליקציות שלך יהיו ניידות יותר. ניתן לבחור אם להישאר ב-App Engine או לעבור לכל אחת מהחלופות שמתוארות למעלה.

ההעברה הזו דורשת יותר מאמץ בהשוואה לאחרים בסדרה הזו. ההחלפה המומלצת של App Engine Memcache היא Cloud Memorystore, שירות מנוהל לשמירה במטמון מבוסס-ענן. ב-Memorystore יש תמיכה בשני מנועים פופולריים לשמירה במטמון בקוד פתוח: Redis ו-Memcached. מודול ההעברה הזה משתמש ב-Cloud Memorystore for Redis. מידע נוסף זמין בסקירה הכללית של Memorystore ו-Redis.

כדי להשתמש ב-Memorystore נדרש שרת פועל, יש צורך גם ב-Cloud VPC. באופן ספציפי, צריך ליצור מחבר גישה ל-VPC ללא שרת (serverless) כדי שהאפליקציה App Engine תוכל להתחבר למכונת Memorystore באמצעות כתובת ה-IP הפרטית שלה. בסיום התרגיל הזה מעדכנים את האפליקציה, כך שבזמן שהיא תפעל כמו קודם, Cloud Memorystore יהיה שירות השמירה במטמון ויחליף את שירות Memcache של App Engine.

המדריך הזה מתחיל באפליקציה לדוגמה של מודול 12 ב-Python 2 ולאחר מכן מתבצע שדרוג משני נוסף ואופציונלי ל-Python 3. אם אתם מכירים כבר את הגישה לשירותים בחבילה של App Engine מ-Python 3 באמצעות ה-SDK של Python 3 App Engine, תוכלו להתחיל עם גרסת Python 3 של האפליקציה לדוגמה של מודול 12. פעולה כזו כרוכה בהסרת השימוש ב-SDK כי Memorystore לא שירות בחבילה של App Engine. המדריך הזה לא כולל מידע על שימוש ב-Python 3 App Engine SDK.

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

  1. הגדרה או הכנה מראש
  2. הגדרה של שירותי שמירה במטמון
  3. עדכון קובצי תצורה
  4. עדכון האפליקציה הראשית

3. הגדרה או הכנה מראש

הכנת הפרויקט ב-Cloud

מומלץ להשתמש שוב באותו פרויקט ששימש להשלמת הקוד של יחידת לימוד 12. לחלופין, אפשר ליצור פרויקט חדש לגמרי או להשתמש שוב בפרויקט קיים. לכל Codelab בסדרה הזו יש "START" (קוד הבסיס שממנו יש להתחיל) ו-"FINISH" (האפליקציה שהועברה). קוד FINISH סופק כדי לאפשר לך להשוות בין הפתרונות שלך לשלנו במקרה שיהיו בעיות. תמיד אפשר לחזור אל START במקרה שמשהו משתבש. נקודות הביקורת האלה נועדו לעזור לכם ללמוד איך לבצע את ההעברות.

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

אחזור של אפליקציה בסיסית לדוגמה

מקוד המודול הבסיסי 12 שאנחנו מתחילים ממנו, ה-Codelab הזה ידריך אותך שלב אחרי שלב בתהליך ההעברה. בסיום, תגיעו לאפליקציית מודול 13 פעילה שדומה לקוד שבאחת מתיקיות FINISH. הנה מקורות המידע:

התיקייה START צריכה להכיל את הקבצים הבאים:

$ ls
README.md               app.yaml                main.py                 requirements.txt        templates                

אם אתם מתחילים מגרסה Python 2, יהיה גם קובץ appengine_config.py ואולי גם תיקיית lib אם השלמתם את קוד ה-Codelab של Module 12.

(מחדש) פריסה של אפליקציית מודול 12

השלבים שנותרו לביצוע השלבים המקדימים:

  1. להכיר מחדש את כלי שורת הפקודה gcloud (אם יש צורך)
  2. (אם יש צורך, פורסים מחדש את הקוד של מודול 12 ב-App Engine).

משתמשי Python 2 צריכים למחוק את התיקייה lib ולהתקין אותה מחדש באמצעות הפקודות האלה:

rm -rf ./lib; pip install -t lib -r requirements.txt                

עכשיו כל המשתמשים (משתמשי Python 2 ו-3) צריכים להעלות את הקוד ל-App Engine באמצעות הפקודה הבאה:

gcloud app deploy                

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

dfe56a02ae59ddd8.png

מאחר שהביקורים האחרונים נשמרים במטמון, רענון הדף אמור להיטען די מהר.

4. הגדרה של שירותי שמירה במטמון

Cloud Memorystore לא ללא שרת (serverless). צריך לציין מופע; במקרה הזה, מפעיל את Redis. בניגוד ל-Memcache, Memorystore הוא מוצר נפרד בענן ואין לו מינוי ללא תשלום. לכן, חשוב לבדוק את נתוני התמחור של Memorystore for Redis לפני שממשיכים. כדי לצמצם את העלויות של תרגיל הזה, אנחנו ממליצים על שימוש במשאבים המינימליים ביותר: רמת שירות בסיסית וקיבולת של 1GB.

מכונת Memorystore נמצאת ברשת שונה מאפליקציית App Engine (מכונות), ולכן צריך ליצור מחבר גישה ל-VPC ללא שרת (serverless) כדי ש-App Engine יוכל לגשת למשאבים של Memorystore. כדי לצמצם את העלויות של VPC, כדאי לבחור את סוג המכונה (f1-micro) ואת מספר המכונות הקטן ביותר שצריך לבקש (מומלץ לבחור 2 לפחות, 3 לכל היותר). חשוב לעיין גם בדף המידע על התמחור של VPC.

אנחנו חוזרים על ההמלצות האלה כדי להפחית את העלויות, בזמן שאנחנו מובילים אתכם ליצירת כל אחד מהמשאבים הנדרשים. בנוסף, כשיוצרים משאבי Memorystore ו-VPC במסוף Cloud, בפינה השמאלית העליונה מופיע מחשבון התמחור של כל מוצר. אומדן של העלות החודשית (ראו איור בהמשך). הערכים האלה משתנים באופן אוטומטי אם משנים את האפשרויות. זה בערך מה שצפוי לראות:

7eb35ebf7248c010.png

שני המשאבים נדרשים, ולא משנה איזה מהם אתם יוצרים קודם. אם קודם תיצרו את המכונה של Memorystore, אפליקציית App Engine לא תוכל להגיע אליה ללא מחבר ה-VPC. באופן דומה, אם בוחרים קודם ליצור את מחבר ה-VPC, האפליקציה של App Engine לא יכולה לדבר ברשת ה-VPC הזו. במדריך הזה תלמדו ליצור קודם את מכונת Memorystore ואז את מחבר ה-VPC.

אחרי ששני המשאבים יהיו אונליין, יהיה עליך להוסיף את המידע הרלוונטי אל app.yaml כדי שהאפליקציה תוכל לגשת למטמון. תוכלו גם לעיין במדריכים של Python 2 או Python 3 במסמכי התיעוד הרשמיים. כדאי גם לעיין במדריך לשמירת הנתונים במטמון בדף ההעברה של Cloud NDB ( Python 2 או Python 3).

יצירת מכונה של Cloud Memorystore

מכיוון שאין ב-Cloud Memorystore אין תוכנית ללא תשלום, אנחנו ממליצים להקצות את כמות המשאבים המינימלית להשלמת ה-Codelab. תוכלו לצמצם את העלויות באמצעות ההגדרות הבאות:

  • בוחרים את רמת השירות הנמוכה ביותר: בסיסי (ברירת המחדל במסוף: 'רגילה', ברירת המחדל של gcloud: 'בסיסי').
  • צריך לבחור את נפח האחסון הקטן ביותר: 1GB (ברירת המחדל במסוף: 16GB, ברירת המחדל של gcloud היא 1GB).
  • בדרך כלל, בגרסאות החדשות ביותר של תוכנה כלשהי צורכים את כמות המשאבים הגדולה ביותר, אבל סביר להניח שלא מומלץ לבחור בגרסה הישנה ביותר. הגרסה השנייה האחרונה היא כרגע גרסת Redis 5.0 (ברירת המחדל של המסוף: 6.x)

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

ממסוף Cloud

נכנסים אל הדף של Cloud Memorystore במסוף Cloud (יכול להיות שתתבקשו להזין נתוני חיוב). אם עדיין לא הפעלתם את Memorystore, תתבקשו לעשות זאת:

68318997e3105db6.png

לאחר הפעלת התכונה (ואולי גם לצד החיוב), תגיעו למרכז הבקרה של Memorystore. כאן תוכלו לראות את כל המופעים שנוצרו בפרויקט שלכם. לפרויקט שמוצג למטה אין שורות, לכן מוצגת ההודעה 'אין שורות להצגה'. כדי ליצור מכונת Memorystore, לוחצים על Create instance בחלק העליון:

63547aa575838a36.png

בדף הזה מופיע טופס למילוי ההגדרות הרצויות ליצירת מכונת Memorystore:

b77d927287fdf4c7.png

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

משורת הפקודה

יצירת מכונות Memorystore מ-Cloud Console היא מידע חזותי אינפורמטיבי, אבל יש משתמשים שמעדיפים את שורת הפקודה. לפני שממשיכים, חשוב להתקין ולהפעיל את gcloud.

בדומה למסוף Cloud, צריך להפעיל את Cloud Memorystore for Redis. שולחים את הפקודה gcloud services enable redis.googleapis.com וממתינים להשלמתה, כמו בדוגמה הבאה:

$ gcloud services enable redis.googleapis.com
Operation "operations/acat.p2-aaa-bbb-ccc-ddd-eee-ffffff" finished successfully.

אם השירות כבר הופעל, להרצת הפקודה (שוב) אין תופעות לוואי (שליליות). כשהשירות מופעל, ניצור מכונת Memorystore. הפקודה נראית כך:

gcloud redis instances create NAME --redis-version VERSION \
    --region REGION --project PROJECT_ID

בוחרים שם למכונת Memorystore שלכם. בשיעור ה-Lab הזה נעשה שימוש ב-"demo-ms" בתור השם ומזהה הפרויקט "my-project". האזור של האפליקציה לדוגמה הוא us-central1 (כמו us-central), אבל אם יש בעיה בזמן האחזור, כדאי להשתמש באזור קרוב יותר. עליך לבחור את אותו האזור שבחרת באפליקציית App Engine. אפשר לבחור כל גרסה של Redis שמעדיפים, אבל אנחנו משתמשים בגרסה 5 כפי שהומלץ קודם. בהתאם להגדרות האלה, זו הפקודה שתנפיק (יחד עם הפלט המשויך):

$ gcloud redis instances create demo-ms --region us-central1 \
    --redis-version redis_5_0 --project my-project

Create request issued for: [demo-ms]
Waiting for operation [projects/my-project/locations/us-central1/operations/operation-xxxx] to complete...done.
Created instance [demo-ms].

בשונה מברירת המחדל של מסוף Cloud, כברירת מחדל ב-gcloud משאבים מינימליים. התוצאה היא שלא היה צורך ברמת השירות או בנפח האחסון בפקודה הזו. יצירה של מכונת Memorystore לוקחת כמה דקות. בסיום, חשוב לשים לב לכתובת ה-IP ומספר היציאה של המכונה, כי הם יתווספו אל app.yaml בקרוב.

אישור שהמכונה נוצרה

ממסוף Cloud או משורת הפקודה

לא משנה אם יצרתם את המכונה מ-Cloud Console או משורת הפקודה, אפשר לוודא שהיא זמינה ומוכן לשימוש באמצעות הפקודה הבאה: gcloud redis instances list --region REGION

זו הפקודה לבדיקת המכונות באזור us-central1 והפלט הצפוי שמציג את המכונה שיצרנו:

$ gcloud redis instances list --region us-central1
INSTANCE_NAME  VERSION    REGION       TIER   SIZE_GB  HOST         PORT  NETWORK  RESERVED_IP     STATUS  CREATE_TIME
demo-ms        REDIS_5_0  us-central1  BASIC  1        10.aa.bb.cc  6379  default  10.aa.bb.dd/29  READY   2022-01-28T09:24:45

כשמופיעה בקשה לספק את פרטי המכונה או להגדיר את האפליקציה, מקפידים להשתמש ב-HOST וב-PORT (ולא ב-RESERVED_IP). עכשיו, בלוח הבקרה של Cloud Memorystore שבמסוף Cloud אמור להופיע המכונה:

c5a6948ec1c056ed.png

באמצעות מכונה וירטואלית ב-Compute Engine

אם יש לכם מכונה וירטואלית (VM), תוכלו גם לשלוח פקודות ישירות מ-VM עם מכונת Memorystore כדי לוודא שהיא פועלת. שימו לב שהשימוש במכונה וירטואלית עשוי להיות כרוך בעלויות, ללא קשר למשאבים שבהם אתם כבר משתמשים.

יצירת מחבר גישה ל-VPC ללא שרת (serverless)

כמו ב-Cloud Memorystore, אתם יכולים ליצור מחבר Cloud VPC ללא שרת (serverless) במסוף Cloud או בשורת הפקודה. באופן דומה, ב-Cloud VPC אין תוכנית ללא תשלום, ולכן מומלץ להקצות את כמות המשאבים המינימלית להשלמת ה-Codelab כדי לשמור על עלויות מינימליות, ואפשר להשיג אותן באמצעות ההגדרות הבאות:

  • צריך לבחור את מספר המופעים המקסימלי הנמוך ביותר: 3 (ברירת המחדל של המסוף ושל gcloud: 10)
  • צריך לבחור את סוג המכונה הזול ביותר: f1-micro (ברירת המחדל במסוף: e2-micro, ללא ברירת מחדל של gcloud)

בחלק הבא מוסבר איך ליצור את המחבר ממסוף Cloud באמצעות ההגדרות של Cloud VPC שלמעלה. אם אתם מעדיפים לעשות את זה משורת הפקודה, דלגו לקטע הבא.

ממסוף Cloud

נכנסים לדף Cloud Networking VPC accessless VPC access". במסוף Cloud (יכול להיות שתתבקשו להזין נתוני חיוב). אם עדיין לא הפעלתם את ה-API, תתבקשו לעשות זאת:

e3b9c0651de25e97.png

לאחר הפעלת ה-API (ויכול להיות שביחד עם החיוב), תגיעו למרכז הבקרה שבו יוצגו כל מחברי ה-VPC שנוצרו. לפרויקט שנעשה בו שימוש בצילום המסך שלמטה אין שורות, לכן כתוב 'אין שורות להצגה'. במסוף, לוחצים על יצירת מחבר בחלק העליון:

b74b49b9d73b7dcf.png

ממלאים את הטופס עם ההגדרות הרצויות:

6b26b2aafa719f73.png

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

משורת הפקודה

לפני שיוצרים מחבר VPC, קודם צריך להפעיל את Serverless VPC Access API. פלט דומה אמור להופיע לאחר הרצת הפקודה הבאה:

$ gcloud services enable vpcaccess.googleapis.com
Operation "operations/acf.p2-aaa-bbb-ccc-ddd-eee-ffffff" finished successfully.

כשה-API מופעל, נוצר מחבר VPC באמצעות פקודה שנראית כך:

gcloud compute networks vpc-access connectors create CONNECTOR_NAME \
    --range 10.8.0.0/28 --region REGION --project PROJECT_ID

צריך לבחור שם למחבר וגם כתובת IP התחלתית לבלוק CIDR של /28 שלא נמצא בשימוש. המדריך הזה מניח את ההנחות הבאות:

  • מזהה פרויקט: my-project
  • שם המחבר של VPC: demo-vpc
  • מספר מכונות: 2 (ברירת מחדל) ו-מספר המופעים: 3
  • סוג המופע: f1-micro
  • אזור: us-central1
  • חסימת CIDR של IPv4: 10.8.0.0/28 (כמו המומלץ במסוף Cloud)

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

$ gcloud compute networks vpc-access connectors create demo-vpc \
    --max-instances 3 --range 10.8.0.0/28 --machine-type f1-micro \
    --region us-central1  --project my-project

Create request issued for: [demo-vpc]
Waiting for operation [projects/my-project/locations/us-central1/operations/xxx] to complete...done.
Created connector [demo-vpc].

הפקודה שלמעלה משמטת את ערכי ברירת המחדל, כמו מינימום מופעים של 2 ורשת בשם default. תהליך היצירה של מחבר VPC נמשך כמה דקות.

אישור שהמחבר נוצר

לאחר השלמת התהליך, צריך לבצע את הפקודה הבאה של gcloud, בהנחה שהאזור הוא us-central1, כדי לאשר שהוא נוצר ומוכן לשימוש:

$ gcloud compute networks vpc-access connectors list --region us-central1
CONNECTOR_ID  REGION       NETWORK  IP_CIDR_RANGE  SUBNET  SUBNET_PROJECT  MIN_THROUGHPUT  MAX_THROUGHPUT  STATE
demo-vpc      us-central1  default  10.8.0.0/28                            200             300             READY

באופן דומה, לוח הבקרה אמור להציג את המחבר שיצרתם:

e03db2c8140ed014.png

חשוב לציין את מזהה הפרויקט ב-Cloud, את שם מחבר ה-VPC ואת האזור.

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

5. עדכון קובצי תצורה

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

requirements.txt

בקטע הזה אנחנו מוסיפים חבילות לתמיכה ב-Cloud Memorystore וב-Cloud NDB. ב-Cloud Memorystore ל-Redis, מספיק להשתמש בלקוח Redis הרגיל ל-Python (redis), כי אין ספריית לקוח של Cloud Memorystore לבדו. מוסיפים את redis וגם google-cloud-ndb אל requirements.txt, ומצטרפים ל-flask ממודול 12:

flask
redis
google-cloud-ndb

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

app.yaml

סעיפים חדשים להוספה

בזמן הריצה של Python 2 App Engine נדרשות חבילות ספציפיות של צד שלישי כשמשתמשים בממשקי Cloud API כמו Cloud NDB, כלומר grpcio ו-setuptools. משתמשי Python 2 חייבים להציג ספריות מובנות כמו אלה, יחד עם גרסה זמינה ב-app.yaml. אם עדיין אין לך קטע ב-libraries, צריך ליצור אותו ולהוסיף את שתי הספריות באופן הבא:

libraries:
- name: grpcio
  version: latest
- name: setuptools
  version: latest

כשמעבירים את האפליקציה שלך, ייתכן שכבר יש לה קטע בשם libraries. אם כן, וחסרים grpcio ו-setuptools, פשוט צריך להוסיף אותם לקטע libraries הקיים.

לאחר מכן, לאפליקציה לדוגמה שלנו נדרשים פרטי מכונת Cloud Memorystore ומידע על מחבר ה-VPC. לכן, מוסיפים את שני הקטעים החדשים הבאים אל app.yaml, ללא קשר לזמן הריצה של Python שבו אתם משתמשים:

env_variables:
    REDIS_HOST: 'YOUR_REDIS_HOST'
    REDIS_PORT: 'YOUR_REDIS_PORT'

vpc_access_connector:
    name: projects/PROJECT_ID/locations/REGION/connectors/CONNECTOR

עד כאן העדכונים הנדרשים. עכשיו הנתונים של app.yaml המעודכנים אמורים להיראות כך:

runtime: python27
threadsafe: yes
api_version: 1

handlers:
- url: /.*
  script: main.app

libraries:
- name: grpcio
  version: 1.0.0
- name: setuptools
  version: 36.6.0

env_variables:
    REDIS_HOST: 'YOUR_REDIS_HOST'
    REDIS_PORT: 'YOUR_REDIS_PORT'

vpc_access_connector:
    name: projects/PROJECT_ID/locations/REGION/connectors/CONNECTOR

בהמשך מופיע הכיתוב 'לפני ואחרי' המחשה של העדכונים שיש להחיל על app.yaml:

ec2bb027a67debb6.png

*הבדלים ב-Python 3

הקטע הזה הוא אופציונלי ורק אם אתם ניידים ל-Python 3. כדי לעשות זאת, צריך לבצע כמה שינויים בהגדרות האישיות של Python 2. אם אתם לא משדרגים כרגע, אתם יכולים לדלג על הקטע הזה.

לא נעשה שימוש ב-threadsafe וב-api_version בסביבת זמן הריצה של Python 3, לכן צריך למחוק את שתי ההגדרות האלה. זמן הריצה העדכני של App Engine לא תומך בספריות מובנות של צד שלישי או בהעתקה של ספריות לא מובנות. הדרישה היחידה לחבילות של צד שלישי היא להציג אותן ב-requirements.txt. כתוצאה מכך, ניתן למחוק את כל הקטע libraries של app.yaml.

בשלב הבא, סביבת זמן הריצה של Python 3 דורשת שימוש ב-frameworks של אינטרנט שעושות ניתוב משלהן, לכן הדגמנו למפתחים איך לעבור מ-webp2 ל-Flask במודול 1. לכן צריך לשנות את כל רכיבי ה-handler של הסקריפטים ל-auto. מאחר שהאפליקציה הזו לא מציגה קבצים סטטיים, היא "חסרת טעם" כדי לכלול handlers רשומים (כי כולם auto), כך שאפשר גם להסיר את הקטע handlers כולו. כתוצאה מכך, עליך לקצר את הערך החדש של app.yaml המקוצר עבור Python 3 כך שייראה כך:

runtime: python39

env_variables:
    REDIS_HOST: 'YOUR_REDIS_HOST'
    REDIS_PORT: 'YOUR_REDIS_PORT'

vpc_access_connector:
    name: projects/PROJECT_ID/locations/REGION/connectors/CONNECTOR

סיכום ההבדלים ב-app.yaml כשיוצאים ל-Python 3:

  • מחיקת ההגדרות של threadsafe ושל api_version
  • מחיקת הקטע libraries
  • מחיקת הקטע handlers (או רק script handlers אם האפליקציה מציגה קבצים סטטיים)

החלפת הערכים

הערכים בקטעים החדשים של Memorystore ומחבר ה-VPC הם רק placeholders. צריך להחליף את הערכים באותיות רישיות (YOUR_REDIS_HOST, YOUR_REDIS_PORT, PROJECT_ID, REGION, CONNECTOR_NAME) בערכים שנשמרו כשיצרתם את המשאבים האלה קודם. בנוגע למופע של Memorystore, צריך להקפיד להשתמש ב-HOST (לא ב-RESERVED_IP) וב-PORT. זוהי דרך מהירה לקבל את HOST ואת PORT בהנחה ששם המכונה הוא demo-ms וה-REGION הוא us-central1:

$ gcloud redis instances describe demo-ms --region us-central1 \
    --format "value(host,port)"
10.251.161.51   6379

אם כתובת ה-IP לדוגמה של מכונת Redis הייתה 10.10.10.10 שמשתמשת ביציאה 6379 בפרויקט my-project שנמצא באזור us-central1 עם שם מחבר ה-VPC בשם demo-vpc, הקטעים הבאים ב-app.yaml ייראו כך:

env_variables:
    REDIS_HOST: '10.10.10.10'
    REDIS_PORT: '6379'

vpc_access_connector:
    name: projects/my-project/locations/us-central1/connectors/demo-vpc

יצירה או עדכון של appengine_config.py

הוספת תמיכה בספריות מובנות של צד שלישי

בדיוק כמו שעשינו עם app.yaml קודם, הוספנו את השימוש בספריות grpcio ו-setuptools. יש לשנות את appengine_config.py כדי לתמוך בספריות מובנות של צד שלישי. אם זה נראה לך מוכר, הסיבה לכך היא שהדבר נדרש גם במודול 2 במהלך המעבר מ-App Engine ndb ל-Cloud NDB. השינוי המדויק שנדרש הוא להוסיף את התיקייה lib לקבוצת העבודה setuptools.pkg_resources:

4140b3800694f77e.png

*הבדלים ב-Python 3

הקטע הזה הוא אופציונלי ורק אם אתם ניידים ל-Python 3. אחד מהשינויים המוקדמים בדור השני של App Engine הוא שכבר אין צורך בהעתקה (שנקראת לפעמים 'ספק') של חבילות צד שלישי (לא מובנות) והפניה לחבילות מובנות של צד שלישי ב-app.yaml. המשמעות היא שניתן למחוק את הקובץ appengine_config.py במלואו.

6. עדכון קובצי אפליקציה

יש רק קובץ אפליקציה אחד, main.py, כך שכל השינויים בקטע הזה ישפיעו רק על הקובץ הזה. סיפקנו ייצוג גרפי של השינויים שנבצע כדי להעביר את האפליקציה הזו ל-Cloud Memorystore. הוא נועד למטרות המחשה בלבד, ולא מיועד לניתוח קפדני. כל העבודה היא בשינויים שאנחנו מבצעים בקוד.

5d043768ba7be742.png

בואו נתמקד בקטעים אלה בכל פעם, מההתחלה.

עדכון ייבוא

בקטע הייבוא ב-main.py של יחידת לימוד 12 נעשה שימוש ב-Cloud NDB וב-Cloud Tasks. הנה הייבוא שלהם:

לפני:

from flask import Flask, render_template, request
from google.appengine.api import memcache
from google.appengine.ext import ndb

כדי לעבור ל-Memorystore צריך לקרוא את משתני הסביבה. כלומר, אנחנו צריכים את מודול os של Python וגם את redis, לקוח Python Redis. מכיוון ש-Redis לא יכול לשמור אובייקטים של Python במטמון, כדאי לערוך את רשימת הביקורים האחרונים באמצעות pickle, אז צריך לייבא גם את זה. אחד היתרונות של Memcache הוא שהעיבוד ברצף של אובייקטים מתבצע באופן אוטומטי, ואילו Memorystore הוא קצת יותר "עשה זאת בעצמך". לסיום, כדי לשדרג מ-App Engine ndb ל-Cloud NDB, מחליפים את google.appengine.ext.ndb ב-google.cloud.ndb. אחרי השינויים האלה, הייבוא אמור להיראות כך:

אחרי:

import os
import pickle
from flask import Flask, render_template, request
from google.cloud import ndb
import redis

אתחול העדכון

אתחול מודול 12 כולל יצירה של אובייקט אפליקציית Flask app והגדרת קבוע לשמירה במטמון של שעה:

לפני:

app = Flask(__name__)
HOUR = 3600

השימוש ב-Cloud APIs מחייב לקוח, לכן יצירת לקוח Cloud NDB מיד אחרי Flask. בשלב הבא, מוצאים את כתובת ה-IP ואת מספר היציאה של מכונת Memorystore ממשתני הסביבה שהגדרתם ב-app.yaml. כשהם חמושים במידע הזה, יוצרים לקוח Redis. כך הקוד נראה אחרי העדכונים:

אחרי:

app = Flask(__name__)
ds_client = ndb.Client()
HOUR = 3600
REDIS_HOST = os.environ.get('REDIS_HOST', 'localhost')
REDIS_PORT = os.environ.get('REDIS_PORT', '6379')
REDIS = redis.Redis(host=REDIS_HOST, port=REDIS_PORT)

*העברה ל-Python 3

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

ראשית, מכיוון ש-Memcache הוא שירות בחבילה של App Engine, כדי להשתמש בו באפליקציית Python 3 נדרש ה-SDK של App Engine, באופן ספציפי שעוטף את אפליקציית WSGI (וגם את ההגדרות הנדרשות):

לפני:

from flask import Flask, render_template, request
from google.appengine.api import memcache, wrap_wsgi_app
from google.appengine.ext import ndb

app = Flask(__name__)
app.wsgi_app = wrap_wsgi_app(app.wsgi_app)
HOUR = 3600

מכיוון שאנחנו עוברים ל-Cloud Memorystore (ולא שירות בחבילה של App Engine כמו Memcache), צריך להסיר את השימוש ב-SDK. התהליך הזה פשוט כי צריך למחוק את כל השורה שמייבאת גם את memcache וגם את wrap_wsgi_app. צריך למחוק גם את הקו שמתקשר אל wrap_wsgi_app(). העדכונים האלה משאירים את החלק הזה באפליקציה (למעשה, כל האפליקציה) זהה לגרסת Python 2.

אחרי:

import os
import pickle
from flask import Flask, render_template, request
from google.cloud import ndb
import redis

app = Flask(__name__)
ds_client = ndb.Client()
HOUR = 3600
REDIS_HOST = os.environ.get('REDIS_HOST', 'localhost')
REDIS_PORT = os.environ.get('REDIS_PORT', '6379')
REDIS = redis.Redis(host=REDIS_HOST, port=REDIS_PORT)

לסיום, צריך להסיר את השימוש ב-SDK מה-app.yaml (מחיקת השורה: app_engine_apis: true) ומ-requirements.txt (מחיקת השורה: appengine-python-standard).

העברה ל-Cloud Memorystore (ול-Cloud NDB)

מודל הנתונים של Cloud NDB נועד להיות תואם למודל ndb של App Engine. כלומר, ההגדרה של אובייקטים מסוג Visit לא תשתנה. בעקבות חיקוי ההעברה של מודול 2 ל-Cloud NDB, כל הקריאות ל-Datastore ב-store_visit() וב-fetch_visits() נוספות ומוטמעות בבלוק with חדש (כפי שנדרש להשתמש במנהל ההקשר של Cloud NDB). אלו הן השיחות לפני השינוי:

לפני:

def store_visit(remote_addr, user_agent):
    'create new Visit entity in Datastore'
    Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()

def fetch_visits(limit):
    'get most recent visits'
    return Visit.query().order(-Visit.timestamp).fetch(limit)

מוסיפים בלוק with ds_client.context() לשתי הפונקציות, ומכניסים את הקריאות של Datastore פנימה (ומוסיפים כניסת פסקה). במקרה כזה, לא נדרשים שינויים עבור השיחות עצמן:

אחרי:

def store_visit(remote_addr, user_agent):
    'create new Visit entity in Datastore'
    with ds_client.context():
        Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()

def fetch_visits(limit):
    'get most recent visits'
    with ds_client.context():
        return Visit.query().order(-Visit.timestamp).fetch(limit)

עכשיו נסתכל על השינויים שקשורים לשמירה במטמון. זוהי הפונקציה main() ממודול 12:

לפני:

@app.route('/')
def root():
    'main application (GET) handler'
    # check for (hour-)cached visits
    ip_addr, usr_agt = request.remote_addr, request.user_agent
    visitor = '{}: {}'.format(ip_addr, usr_agt)
    visits = memcache.get('visits')

    # register visit & run DB query if cache empty or new visitor
    if not visits or visits[0].visitor != visitor:
        store_visit(ip_addr, usr_agt)
        visits = list(fetch_visits(10))
        memcache.set('visits', visits, HOUR)  # set() not add()

    return render_template('index.html', visits=visits)

ב-Redis יש "get" ו'להגדיר' שיחות, בדיוק כמו Memcache. אנחנו רק מחליפים את ספריות הלקוח המתאימות, נכון? כמעט. כפי שציינו קודם, אי אפשר לשמור במטמון רשימת Python עם Redis (בגלל שקודם צריך ליצור רשימה טורית, משהו ש-Memcache מטפל בו אוטומטית). לכן, בקריאה set(), " Pickle" הביקורים במחרוזת עם pickle.dumps(). באופן דומה, בעת אחזור ביקורים מהמטמון, צריך לבטל את הבחירה בו עם pickle.loads() מיד אחרי get(). זה ה-handler העיקרי אחרי הטמעת השינויים האלה:

אחרי:

@app.route('/')
def root():
    'main application (GET) handler'
    # check for (hour-)cached visits
    ip_addr, usr_agt = request.remote_addr, request.user_agent
    visitor = '{}: {}'.format(ip_addr, usr_agt)
    rsp = REDIS.get('visits')
    visits = pickle.loads(rsp) if rsp else None

    # register visit & run DB query if cache empty or new visitor
    if not visits or visits[0].visitor != visitor:
        store_visit(ip_addr, usr_agt)
        visits = list(fetch_visits(10))
        REDIS.set('visits', pickle.dumps(visits), ex=HOUR)

    return render_template('index.html', visits=visits)

מסיימים את השינויים שנדרשים ב-main.py בהמרת השימוש של אפליקציה לדוגמה ב-Memcache ל-Cloud Memorystore. מה לגבי תבנית ה-HTML וניוד שלה ל-Python 3?

לעדכן את הקובץ של תבנית ה-HTML ואת היציאה ל-Python 3?

הפתעה! לא צריך לעשות כאן שום דבר כי האפליקציה תוכננה לפעול גם ב-Python 2 וגם ב-3 בלי שינויי קוד וספריות תאימות. יוצג לכם main.py. זהה ב-mod13a (2.x) וב-mod13b (3.x) 'FINISH' תיקיות. הדבר נכון גם לגבי requirements.txt , מלבד ההבדלים במספרי הגרסאות (אם נעשה שימוש). מכיוון שממשק המשתמש נשאר ללא שינוי, גם אין עדכונים ל-templates/index.html.

כל מה שנדרש להפעלת האפליקציה הזו ב-Python 3 App Engine הושלם בשלב מוקדם יותר של ההגדרה: הוראות מיותרות הוסרו מ-app.yaml וגם התיקייה appengine_config.py וגם התיקייה lib נמחקו כי לא נעשה בהן שימוש ב-Python 3.

7. סיכום/ניקוי

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

פריסה ואימות של אפליקציה

הבדיקה האחרונה היא תמיד לפרוס את האפליקציה לדוגמה. מפתחי Python 2: מוחקים ומתקינים מחדש את lib באמצעות הפקודות הבאות. (אם מותקנת במערכת גם Python 2 וגם 3, יכול להיות שצריך להריץ את pip2 באופן מפורש.)

rm -rf ./lib
pip install -t lib -r requirements.txt

עכשיו מפתחי Python 2 ו-3 צריכים לפרוס את האפליקציות שלהם עם:

gcloud app deploy

רק חיווט מחדש פחות או יותר לשירות שמירה במטמון אחר לגמרי, ולכן האפליקציה עצמה אמורה לפעול באופן זהה לאפליקציית מודול 12:

אפליקציית ביקורים של מודול 7

השלב הזה מסתיים ב-Codelab. אנחנו מזמינים אותך להשוות את האפליקציה לדוגמה המעודכנת שלך לאחת מהתיקיות של מודול 13, mod13a (Python 2) או mod13b (Python 3).

הסרת המשאבים

כללי

אם סיימתם בינתיים, מומלץ להשבית את אפליקציית App Engine כדי להימנע מצבירת חיובים. עם זאת, אם אתם רוצים להתנסות בפיצ'רים נוספים או להתנסות בהם, בפלטפורמת App Engine יש מכסה בחינם, וכל עוד אתם לא חורגים ממכסת השימוש הזו, לא נחייב אתכם. הבקשה נועדה למחשוב, אבל ייתכן שיחולו חיובים גם על שירותים רלוונטיים של App Engine. למידע נוסף, יש לעיין בדף התמחור של האפליקציה. אם ההעברה הזו כוללת שירותי ענן אחרים, הם מחויבים בנפרד. בכל מקרה, אם רלוונטי, ראו "ספציפי ל-Codelab זה" שבהמשך.

גילוי נאות מלא, פריסה בפלטפורמת מחשוב ללא שרת (serverless) של Google Cloud, כמו App Engine, כרוכה בעלויות נמוכות של build ואחסון. ל-Cloud Build יש מכסה משלה בחינם, כמו גם ל-Cloud Storage. נפח האחסון של התמונה הזו תופס חלק מהמכסה. עם זאת, ייתכן שאתם גרים באזור שאין בו תוכנית ללא תשלום כזה, לכן כדאי שתהיו מודעים לשימוש שלכם בנפח האחסון כדי למזער את העלויות הפוטנציאליות. 'תיקיות' ספציפיות של Cloud Storage כדאי לבדוק:

  • console.cloud.google.com/storage/browser/LOC.artifacts.PROJECT_ID.appspot.com/containers/images
  • console.cloud.google.com/storage/browser/staging.PROJECT_ID.appspot.com
  • הקישורים לנפח האחסון שלמעלה תלויים במאפיין PROJECT_ID ובמאפיין *LOC*שלך, לדוגמה, "us" אם האפליקציה מתארחת בארה"ב.

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

ספציפי ל-Codelab הזה

השירותים שמפורטים בהמשך הם ייחודיים ל-Codelab הזה. אפשר לקרוא מידע נוסף במסמכי התיעוד של כל מוצר:

המדריך הזה כלל שימוש בארבעה מוצרי Cloud:

  • App Engine
  • Cloud Datastore
  • Cloud Memorystore
  • Cloud VPC

בהמשך מפורטות הנחיות לשחרור המשאבים האלה ולצמצום או לצמצום החיובים בחיוב.

כיבוי של מכונת Memorystore ומחבר VPC

אלה המוצרים ללא מינוי ללא תשלום, ולכן כרגע יש לכם חיוב. אם לא תכבו את הפרויקט ב-Cloud (עיינו בקטע הבא), תצטרכו למחוק את מכונת Memorystore ואת מחבר ה-VPC כדי להפסיק את החיוב. בדומה למועד שבו יצרתם את המשאבים האלו, אפשר גם לשחרר אותם ממסוף Cloud או משורת הפקודה.

ממסוף Cloud

כדי למחוק את מכונת Memorystore, חוזרים ללוח הבקרה של Memorystore ולוחצים על מזהה המכונה:

2b09baf1aa2e0a25.png

בדף הפרטים של המופע, לחצו על 'מחיקה'. ועליך לאשר:

f9d9eb1c1d4c6107.png

כדי למחוק את מחבר ה-VPC, נכנסים למרכז הבקרה שלו, מסמנים את התיבה לצד המחבר שרוצים למחוק ולוחצים על 'מחיקה'. ועליך לאשר:

ca5fbd9f4c7c9b60.png

משורת הפקודה

צמד הפקודות הבאות של gcloud מוחק גם את מכונת Memorystore וגם את מחבר ה-VPC, בהתאמה:

  • gcloud redis instances delete INSTANCE --region REGION
  • gcloud compute networks vpc-access connectors delete CONNECTOR --region REGION

אם לא הגדרתם את מזהה הפרויקט gcloud config set project, יכול להיות שתצטרכו לספק את המזהה --project PROJECT_ID. אם מכונת Memorystore נקראת demo-ms ומחבר VPC בשם demo-vpc ושניהם נמצאים באזור us-central1, צריך לשלוח את זוג הפקודות הבאות ולאשר:

$ gcloud redis instances delete demo-ms --region us-central1
You are about to delete instance [demo-ms] in [us-central1].
Any associated data will be lost.

Do you want to continue (Y/n)?

Delete request issued for: [demo-ms]
Waiting for operation [projects/PROJECT/locations/REGION/operations/operation-aaaaa-bbbbb-ccccc-ddddd] to complete...done.
Deleted instance [demo-ms].
$
$ gcloud compute networks vpc-access connectors delete demo-vpc --region us-central1
You are about to delete connector [demo-vpc] in [us-central1].
Any associated data will be lost.

Do you want to continue (Y/n)?

Delete request issued for: [demo-vpc]
Waiting for operation [projects/PROJECT/locations/REGION/operations/aaaaa-bbbb-cccc-dddd-eeeee] to complete...done.
Deleted connector [demo-vpc].

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

השלבים הבאים

מעבר למדריך הזה, יש מודולים אחרים להעברה שמתמקדים בהפסקת השימוש בשירותים בחבילה מהדור הקודם:

App Engine היא כבר לא הפלטפורמה היחידה ללא שרת (serverless) ב-Google Cloud. אם יש לכם אפליקציה קטנה של App Engine או אפליקציה שיש לה פונקציונליות מוגבלת ואתם רוצים להפוך אותה למיקרו-שירות (microservice) עצמאי, או שאתם רוצים לפצל אפליקציה מונוליתית למספר רכיבים לשימוש חוזר, כדאי לשקול לעבור ל-Cloud Functions. אם יצירת קונטיינרים הפכה לחלק מתהליך פיתוח האפליקציות שלכם, במיוחד אם היא מורכבת מצינור עיבוד נתונים של CI/CD (אינטגרציה רציפה (CI/CD)/פיתוח רציף (continuous delivery) או פריסה), מומלץ לעבור ל-Cloud Run. התרחישים האלה מתוארים במודולים הבאים:

  • מעבר מ-App Engine ל-Cloud Functions: ראו מודול 11
  • מעבר מ-App Engine ל-Cloud Run: אפשר לעיין במודול 4 ליצירת קונטיינרים לאפליקציה באמצעות Docker, או במודול 5 כדי לבצע אותו ללא קונטיינרים, ידע ב-Docker או Dockerfile

המעבר לפלטפורמה אחרת ללא שרת הוא אופציונלי, ומומלץ לבדוק את האפשרויות הטובות ביותר לאפליקציות ולתרחישים לדוגמה לפני שמבצעים שינויים.

בלי קשר למודול ההעברה הרצוי, כל התוכן של תחנת המיגרציה ללא שרת (serverless) (codelabs, סרטונים, קוד מקור [אם הוא זמין]) יהיה זמין במאגר הקוד הפתוח שלו. README של המאגר גם מספק הדרכה לגבי ההעברות שכדאי לשקול ו"הזמנה" רלוונטית של מודולי העברה.

8. מקורות מידע נוספים

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

בעיות/משוב על Codelabs

אם נתקלתם בבעיות ב-Codelab הזה, צריך קודם לחפש את הבעיה לפני השליחה. קישורים לחיפוש וליצירת בעיות חדשות:

משאבים להעברה

בטבלה שלמטה מופיעים הקישורים לתיקיות המאגר של מודול 12 (START) ומודול 13 (FINISH). אפשר לגשת אליהן גם דרך המאגר לכל העברות Codelab ב-App Engine, שאותו ניתן לשכפל או להוריד בקובץ ZIP.

Codelab

ֶPython 2

ֶPython 3

יחידת לימוד 12

קוד

קוד

יחידת לימוד 13 (Codelab זה)

קוד

קוד

הפניות אונליין

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

App Engine

App Engine NDB ו-Cloud NDB

Memcache ב-App Engine ו-Cloud Memorystore

Cloud VPC

מידע אחר בענן

רישיון

היצירה הזו בשימוש ברישיון Creative Commons Attribution 2.0 גנרי.