‫Memcache API לשירותים קודמים בחבילה

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

מתי כדאי להשתמש במטמון זיכרון

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

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

רמות שירות

‫App Engine תומך בשתי רמות של שירות memcache:

  • Shared memcache היא ברירת המחדל בחינם לאפליקציות App Engine. השירות מספק קיבולת מטמון על בסיס המאמץ המרבי, והיא תלויה בביקוש הכולל של כל האפליקציות של App Engine שמשתמשות בשירות המשותף של memcache.

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

שתי רמות השירות של memcache משתמשות באותו API. הוראות להגדרת שירות memcache לאפליקציה זמינות במאמר שימוש ב-Memcache.

בטבלה הבאה מפורטים ההבדלים בין שני הסוגים של שירות memcache:

תכונה ‫Memcache ייעודי Shared Memcache
מחיר ‫0.06$‎ לכל GB לשעה חינם
קיבולת
us-central
1 עד 100GB
‫asia-northeast1,‏ europe-west,‏ europe-west3 ו-us-east1:
1 עד 20GB
אזורים אחרים:
1 עד 2GB
אין קיבולת מובטחת
ביצועים עד 10,000 קריאות או 5,000 כתיבות (בלעדי) בשנייה לכל GB (פריטים < 1KB). פרטים נוספים מופיעים במאמר בנושא נתונים סטטיסטיים של מטמון. לא מובטח
חנות עמידה לא לא
SLA ללא ללא

החיוב על memcache ייעודי מתבצע במרווחי זמן של 15 דקות. אם אתם משלמים במטבע שאינו דולר ארה"ב, יחולו המחירים הרשומים במטבע שלכם במק"טים של Cloud Platform.

אם האפליקציה שלכם צריכה קיבולת גדולה יותר של memcache, אתם יכולים לפנות לצוות המכירות.

מגבלות

המגבלות הבאות חלות על השימוש בשירות memcache:

  • הגודל המקסימלי של ערך נתונים במטמון הוא 1MB ‏ (10^6 בייטים).
  • גודל המפתח לא יכול להיות גדול מ-250 בייט. בזמן הריצה של Python, מפתחות שהם מחרוזות באורך של יותר מ-250 בייט יעברו גיבוב.
  • פעולות באצווה מסוג 'multi' יכולות לכלול כל מספר של אלמנטים. הגודל הכולל של הקריאה והגודל הכולל של הנתונים שאוחזרו לא יכולים לחרוג מ-32 מגה-בייט.
  • מפתח memcache לא יכול להכיל בית null.
  • השימוש ב-Memcache API ברמה המשותפת כפוף למגבלות שמוגדרות ביחידות חישוב משותפות של Centi Memcache לכל אזור ולכל דקה.

המלצות ושיטות מומלצות

כשמשתמשים ב-Memcache, מומלץ לתכנן את האפליקציות כך:

  • טיפול במקרים שבהם ערך שמאוחסן במטמון לא תמיד זמין.

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

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

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

      לדוגמה, אפשר לפצל מונה שמתעדכן לעיתים קרובות בין כמה מפתחות, לקרוא אותם ולסכם רק כשצריך את הסכום הכולל. באופן דומה, אפשר לפצל נתונים בגודל 500K שצריך לקרוא בכל בקשת HTTP לכמה מפתחות, ולקרוא אותם בחזרה באמצעות קריאה אחת ל-Batch API. (עוד יותר טוב יהיה לשמור את הערך במטמון בזיכרון המופע). ב-memcache ייעודי, קצב הגישה בשיא לכל מפתח צריך להיות נמוך ב-1-2 סדרי גודל מהדירוג לכל GB.

  • שומרים את המפתחות שלכם כדי לאחזר ערכים מהמטמון.

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

איך נתונים שנשמרו במטמון פוקעים

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

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

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

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

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

אפשר למחוק את כל המטמון של אפליקציה דרך ה-API או בקטע memcache של Google Cloud console.

נתונים סטטיסטיים של המטמון

פעולות לשנייה לפי גודל פריט

הדירוג של memcache ייעודי הוא לפי פעולות לשנייה לכל GB, כאשר פעולה מוגדרת כגישה לפריט מטמון בודד, כמו get,‏ set או delete. תעריף הפעולה משתנה בהתאם לגודל הפריט, בערך לפי הטבלה הבאה. חריגה מהדירוגים האלה עלולה להוביל לעלייה בזמן האחזור של ה-API או לשגיאות.

בטבלאות הבאות מפורט המספר המקסימלי של פעולות get-hit או set בלעדיות ומתמשכות לכל GB של מטמון. שימו לב שפעולת get-hit היא קריאה לפונקציה get שמוצאת ערך שמאוחסן עם המפתח שצוין ומחזירה את הערך הזה.

גודל הפריט (KB) מקסימום get-hit פעולות בשנייה מקסימום set פעולות בשנייה
‫≤1 10,000 ‫5,000
100 2,000 1,000
512 500 250

באופן תיאורטי, אפליקציה שהוגדרה לשימוש במטמון של כמה גיגה-בייט יכולה להשיג שיעור פעולות מצטבר שמחושב כמספר הגיגה-בייט כפול השיעור לכל גיגה-בייט. לדוגמה, אפליקציה שהוגדר לה מטמון של 5GB יכולה להגיע ל-50,000 פעולות memcache בשנייה על פריטים של 1KB. כדי להגיע לרמה הזו, צריך לפזר את העומס בצורה טובה על פני מרחב המפתחות של memcache.

לכל תבנית קלט/פלט, המגבלות שמופיעות למעלה הן לקריאות או לכתיבות. במקרה של קריאות וכתיבות בו-זמניות, המגבלות משתנות בהתאם. ככל שמבצעים יותר קריאות, אפשר לבצע פחות כתיבות, ולהיפך. הדוגמאות הבאות הן מגבלות IOPs לקריאות וכתיבות בו-זמניות של ערכים בגודל 1KB לכל 1GB של מטמון:

פעולות קלט/פלט לקריאה פעולות קלט/פלט בשנייה (Write IOPs)
10000 0
8000 1000
5,000 2500
1000 4500
0 5,000

יחידות מחשוב של Memcache‏ (MCU)

התפוקה של Memcache יכולה להשתנות בהתאם לגודל הפריט שאליו ניגשים ולפעולה שרוצים לבצע בפריט. אפשר לשייך עלות לפעולות ולהעריך את קיבולת התנועה שאפשר לצפות לה מ-Memcache ייעודי באמצעות יחידה שנקראת Memcache Compute Unit‏ (MCU). ה-MCU מוגדר כך שאפשר לצפות ל-10,000 יחידות MCU בשנייה לכל GB של memcache ייעודי. Google Cloud במסוף מוצג כמה יחידות MCU האפליקציה שלכם צורכת כרגע.

חשוב לזכור ש-MCU הוא הערכה סטטיסטית גסה, וגם לא יחידה ליניארית. לכל פעולת מטמון שקוראת או כותבת ערך יש עלות MCU תואמת, שמשתנה בהתאם לגודל הערך. ה-MCU עבור set תלוי בגודל הערך: הוא פי 2 מהעלות של פעולת get-hit מוצלחת.

גודל פריט הערך (KB) עלות של יחידת MCU עבור get-hit עלות של יחידת MCU עבור set
‫≤1 1.0 2.0
2 ‫1.3 ‫2.6
10 1.7 3.4
100 5.0 ‫10.0
512 20.0 40.0
1024 50.0 100.0

לפעולות שלא קוראות או כותבות ערך יש עלות קבועה של יחידות MCU:

פעולה MCU
get-miss 1.0
delete 2.0
increment 2.0
flush 100.0
stats 100.0

שימו לב שפעולת get-miss היא פעולת get שמוצאת שאין ערך שמאוחסן עם המפתח שצוין.

השוואה והגדרה

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

רכיבים לוגיים מרכזיים של השוואה והגדרה

אם אתם מעדכנים את הערך של מפתח memcache שעשוי לקבל בקשות כתיבה מקבילות אחרות, אתם צריכים להשתמש באובייקט memcache Client, שמאחסן מידע מסוים על מצב המערכת שמשמש את השיטות שתומכות בהשוואה ובהגדרה. אי אפשר להשתמש בפונקציות memcache‏ get() או set(), כי הן חסרות מצב. הסיווג Client עצמו אינו thread-safe, ולכן אין להשתמש באותו אובייקט Client ביותר משרשור אחד.

כשמאחזרים מפתחות, צריך להשתמש בשיטות memcache Client שתומכות בהשוואה ובהגדרה: gets() או get_multi() עם הפרמטר for_cas שמוגדר ל-True.

כשמעדכנים מפתח, צריך להשתמש בשיטות memcache Client שתומכות בהשוואה ובהגדרה: cas() או cas_multi().

רכיב לוגי חשוב נוסף הוא שירות ה-memcache של App Engine וההתנהגות שלו בהקשר של השוואה והגדרה. שירות ה-memcache של App Engine עצמו מתנהג באופן אטומי. כלומר, כששתי בקשות בו-זמניות (עם אותו מזהה אפליקציה) משתמשות ב-memcache, הן מועברות לאותו מופע של שירות memcache, ולשירות memcache יש מספיק נעילות פנימיות כדי שהבקשות בו-זמניות לאותו מפתח יסודרו כראוי בסדר. במילים אחרות, שתי בקשות cas() לאותה מילת מפתח לא יפעלו במקביל – השירות יטפל בבקשה הראשונה שהתקבלה עד לסיום (כלומר, עד לעדכון הערך וחותמת הזמן) לפני שהוא יתחיל לטפל בבקשה השנייה.

במאמר טיפול בפעולות כתיבה בו-זמניות מוסבר איך להשתמש בפונקציות compare ו-set ב-Python.

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