בדף הזה מופיע סקירה כללית של שירות ה-memcache של App Engine. אפליקציות אינטרנט ניתנות להרחבה עם ביצועים גבוהים, ולעתים קרובות משתמשות במטמון נתונים מבוזר בזיכרון לפני אחסון קבוע חזק או במקומו, למשימות מסוימות. App Engine כולל שירות מטמון בזיכרון למטרה הזו. כדי ללמוד איך להגדיר, לנטר ולהשתמש בשירות ה-memcache, אפשר לקרוא את המאמר שימוש ב-Memcache.
מתי כדאי להשתמש במטמון זיכרון
אחד השימושים במטמון זיכרון הוא להאצת שאילתות נפוצות במאגר נתונים. אם הרבה בקשות מבצעות את אותה שאילתה עם אותם פרמטרים, ואין צורך שהשינויים בתוצאות יופיעו באתר באופן מיידי, האפליקציה יכולה לשמור את התוצאות במטמון ב-memcache. בבקשות הבאות, המערכת יכולה לבדוק את ה-memcache, ולבצע את השאילתה במאגר הנתונים רק אם התוצאות לא קיימות או שתוקפן פג. נתוני סשן, העדפות משתמשים ונתונים אחרים שמוחזרים על ידי שאילתות לדפי אינטרנט הם מועמדים טובים לאחסון במטמון.
Memcache יכול להיות שימושי גם לערכים זמניים אחרים. עם זאת, כששוקלים אם לאחסן ערך רק ב-Memcache ולא לגבות אותו באחסון מתמיד אחר, חשוב לוודא שהאפליקציה מתנהגת בצורה מקובלת אם הערך לא זמין פתאום. התוקף של הערכים יכול לפוג בכל שלב מ-memcache, והוא יכול לפוג לפני תאריך התפוגה שהוגדר לערך. לדוגמה, אם היעדר פתאומי של נתוני סשן של משתמש יגרום לתקלה בסשן, כדאי לאחסן את הנתונים האלה במאגר הנתונים בנוסף ל-memcache.
רמות שירות
App Engine תומך בשתי רמות של שירות memcache:
Shared memcache היא ברירת המחדל בחינם לאפליקציות App Engine. הוא מספק קיבולת מטמון על בסיס המאמץ המרבי, והיא תלויה בביקוש הכולל של כל האפליקציות של App Engine שמשתמשות בשירות המשותף של memcache.
מטמון memcache ייעודי מספק קיבולת מטמון קבועה שמוקצית באופן בלעדי לאפליקציה שלכם. החיוב מתבצע לפי גודל המטמון בגיגה-בייט לשעה, ונדרש להפעיל את החיוב. שליטה בגודל המטמון מאפשרת לאפליקציה לפעול בצורה צפויה יותר, עם פחות קריאות מאחסון עמיד ויקר יותר.
שתי רמות השירות של memcache משתמשות באותו API. הוראות להגדרת שירות memcache לאפליקציה זמינות במאמר שימוש ב-Memcache.
בטבלה הבאה מפורטים ההבדלים בין שני הסוגים של שירות memcache:
| תכונה | Dedicated Memcache | Shared Memcache |
|---|---|---|
| מחיר | 0.06$ לכל GB לשעה | חינם |
| קיבולת |
|
אין קיבולת מובטחת |
| ביצועים | עד 10,000 קריאות או 5,000 כתיבות (בלעדיות) בשנייה לכל GB (פריטים < 1KB). פרטים נוספים זמינים במאמר Cache statistics (נתונים סטטיסטיים של מטמון). | לא מובטח |
| מאגר עמיד | לא | לא |
| SLA | ללא | ללא |
החיוב על memcache ייעודי מתבצע במרווחי זמן של 15 דקות. אם אתם משלמים במטבע שאינו דולר ארה"ב, יחולו המחירים הרשומים במטבע שלכם במק"טים של Cloud Platform.
אם האפליקציה שלכם צריכה קיבולת גדולה יותר של memcache, אתם יכולים לפנות לצוות המכירות.
מגבלות
המגבלות הבאות חלות על השימוש בשירות memcache:
- הגודל המקסימלי של ערך נתונים במטמון הוא 1MB (10^6 בייטים).
- גודל המפתח לא יכול להיות גדול מ-250 בייט. בזמן הריצה של Python, מפתחות שהם מחרוזות באורך של יותר מ-250 בייט יעברו גיבוב.
- בפעולות אצווה מסוג 'multi' יכול להיות כל מספר של רכיבים. הגודל הכולל של הקריאה והגודל הכולל של הנתונים שאוחזרו לא יכולים לחרוג מ-32 מגה-בייט.
- מפתח memcache לא יכול להכיל בית null.
- השימוש ב-Memcache API ברמה המשותפת כפוף למגבלות שמוגדרות ב-Shared Centi Memcache Compute Units Per Region Per Minute.
המלצות ושיטות מומלצות
כשמשתמשים ב-Memcache, מומלץ לתכנן את האפליקציות כך:
טיפול במקרים שבהם ערך שמאוחסן במטמון לא תמיד זמין.
- Memcache הוא לא אחסון עמיד. לפי מדיניות הפינוי, המפתחות מפונים כשהמטמון מתמלא. שינויים בהגדרות של המטמון או אירועי תחזוקה במרכז הנתונים יכולים גם הם לגרום לניקוי של חלק מהמטמון או של כולו.
- יכול להיות ש-Memcache לא יהיה זמין באופן זמני. יכול להיות שפעולות Memcache ייכשלו מסיבות שונות, כולל שינויים בהגדרת המטמון או אירועי תחזוקה במרכזי נתונים. האפליקציות צריכות להיות מתוכננות כך שהן יזהו פעולות שנכשלו בלי להציג את השגיאות האלה למשתמשי הקצה. ההנחיות האלה רלוונטיות במיוחד לפעולות על קבוצות.
מומלץ להשתמש בתכונת האצווה של ה-API כשזה אפשרי.
- הפעולה הזו משפרת את הביצועים והיעילות של האפליקציה, במיוחד כשמדובר בפריטים קטנים.
חלוקת העומס במרחב המפתחות של memcache.
אם פריט אחד או קבוצה קטנה של פריטים ב-memcache מייצגים כמות לא פרופורציונלית של תנועת גולשים, האפליקציה לא תוכל להתרחב. ההנחיות האלה רלוונטיות גם לגבי פעולות לשנייה וגם לגבי רוחב פס. כדי לפתור את הבעיה הזו, אפשר לפצל את הנתונים באופן מפורש.
לדוגמה, אפשר לפצל מונה שמתעדכן לעיתים קרובות בין כמה מפתחות, לקרוא אותם בחזרה ולסכום רק כשצריך סכום כולל. באופן דומה, אפשר לפצל נתונים בגודל 500K שצריך לקרוא בכל בקשת HTTP לכמה מפתחות ולקרוא אותם בחזרה באמצעות קריאה אחת ל-API באצווה. (עדיף לשמור את הערך במטמון בזיכרון המופע). ב-memcache ייעודי, שיעור הגישה המקסימלי למפתח יחיד צריך להיות נמוך ב-1-2 סדרי גודל מהדירוג לכל GB.
שומרים את המפתחות שלכם כדי לאחזר ערכים מהמטמון.
- ב-Memcache אין שיטה להצגת רשימה של מפתחות. בגלל האופי של המטמון, אי אפשר להציג רשימה של מפתחות בלי לשבש את המטמון. בנוסף, בשפות מסוימות, כמו Python, מתבצע גיבוב של מפתחות ארוכים, והמפתחות המקוריים ידועים רק לאפליקציה.
איך נתונים שנשמרו במטמון פוקעים
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 של מטמון:
| IOPS לקריאה | IOPS של כתיבה |
|---|---|
| 10000 | 0 |
| 8000 | 1000 |
| 5,000 | 2500 |
| 1000 | 4500 |
| 0 | 5,000 |
יחידות מחשוב של Memcache (MCU)
התפוקה של Memcache יכולה להשתנות בהתאם לגודל הפריט שאליו ניגשים ולפעולה שרוצים לבצע בפריט. אפשר לשייך עלות לפעולות ולהעריך את קיבולת התנועה שאפשר לצפות לה מ-memcache ייעודי באמצעות יחידה שנקראת Memcache Compute Unit (יחידת מחשוב של Memcache, MCU). ה-MCU מוגדר כך שאפשר לצפות ל-10,000 יחידות MCU לשנייה לכל GB של memcache ייעודי. Google Cloud במסוף מוצג כמה יחידות MCU האפליקציה שלכם צורכת כרגע.
שימו לב: יחידת ה-MCU היא הערכה סטטיסטית גסה, והיא לא יחידה ליניארית. לכל פעולת מטמון שקוראת או כותבת ערך יש עלות MCU תואמת שתלויה בגודל הערך. עלות ה-MCU של set תלויה בגודל הערך: היא כפולה מעלות הפעולה המוצלחת של 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.
המאמרים הבאים
- במאמר שימוש ב-Memcache מוסבר איך להגדיר את Memcache, לעקוב אחריו ולהשתמש בו.
- דוגמאות ל-Memcache.