שיטות מומלצות לשימוש ב-Spanner כמסד נתונים למשחקים

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

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

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

במסמך הזה מפורטות השיטות המומלצות הבאות:

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

הסברים על המונחים

הרשאות
משחקים, חבילות הרחבה או רכישות מתוך האפליקציה ששייכים לשחקן.
פרטים אישיים מזהים (PII)
במשחקים, מידע שבדרך כלל כולל כתובת אימייל ופרטי חשבון תשלום, כמו מספר כרטיס אשראי וכתובת לחיוב. בשוקים מסוימים, המידע הזה עשוי לכלול מספר תעודת זהות.
מסד נתונים של משחקים (game DB)
מסד נתונים שבו נשמרים נתוני ההתקדמות והמלאי של שחקן במשחק.
מסד נתונים של אימות (auth DB)
מסד נתונים שכולל את זכויות השחקנים ואת הפרטים האישיים המזהים (PII) שהם משתמשים בהם כשהם מבצעים רכישה. מסד הנתונים של ההרשאות נקרא גם מסד הנתונים של החשבון או מסד הנתונים של השחקן. לפעמים מסד הנתונים הזה משולב עם מסד הנתונים של המשחק, אבל
עסקה
טרנזקציה במסד נתונים – קבוצה של פעולות כתיבה שיש להן השפעה של הכול או כלום. העסקה מצליחה וכל העדכונים נכנסים לתוקף, או שהמסד נתונים חוזר למצב שלא כולל אף אחד מהעדכונים של העסקה. במשחקים, עסקאות במסד נתונים הן קריטיות במיוחד כשמעבדים תשלומים, וכשמקצים בעלות על מלאי או מטבעות בעלי ערך במשחק.
מערכת ניהול של מסד נתונים יחסי (RDBMS)
מערכת מסדי נתונים שמבוססת על טבלאות ושורות שמפנות אחת לשנייה. ‫SQL Server,‏ MySQL ו-Oracle® (בשימוש פחות נפוץ) הן דוגמאות למסדי נתונים רלציוניים שמשמשים במשחקים. השימוש בהם נפוץ כי הם מספקים מתודולוגיות מוכרות וערבויות חזקות לגבי עסקאות.
מסד נתונים NoSQL
מסדי נתונים שלא בנויים בצורה רלציונית. השימוש במסדי נתונים כאלה הופך לפופולרי יותר במשחקים כי הם מאפשרים גמישות רבה כשמודל הנתונים משתנה. מסדי נתונים ב-NoSQL כוללים את MongoDB ו-Cassandra.
מפתח ראשי
בדרך כלל העמודה שמכילה את המזהה הייחודי של פריטי מלאי, חשבונות של שחקנים ועסקאות רכישה.
Instance
מסד נתונים יחיד. לדוגמה, באשכול מופעלים כמה עותקים של תוכנת מסד הנתונים, אבל הוא מופיע כמופע יחיד בקצה העורפי של המשחק.
צומת
לצורך המסמך הזה, מכונה אחת שמריצה עותק של תוכנת מסד הנתונים.
רפליקה
עותק שני של מסד נתונים. רפליקות משמשות לעיתים קרובות לשחזור נתונים ולזמינות גבוהה, או כדי להגדיל את תפוקת הקריאה.
אשכול
עותקים רבים של התוכנה שפועלים במכונות רבות, וביחד נראים כמו מופע יחיד לשרת העורפי של המשחק. האשכול משמש למדרגיות ולזמינות.
רסיס
מופע של מסד נתונים. הרבה סטודיות למשחקים מריצות כמה מופעים הומוגניים של מסדי נתונים, שכל אחד מהם מכיל קבוצת משנה של נתוני המשחק. כל אחד מהמופעים האלה נקרא בדרך כלל shard. בדרך כלל מבצעים שרדינג כדי לשפר את הביצועים או את יכולת ההתאמה, אבל זה פוגע ביעילות הניהול ומגדיל את מורכבות האפליקציה. החלוקה לשברים ב-Spanner מיושמת באמצעות פיצולים.
פיצול
Spanner מחלק את הנתונים שלכם לחלקים שנקראים splits. כל split יכול לעבור באופן עצמאי ולהיות מוקצה לשרתים שונים. פיצול מוגדר כטווח של שורות בטבלה ברמה העליונה (כלומר, לא משולבת), שבה השורות מסודרות לפי מפתח ראשי. המפתחות שמתחילים ומסיימים את הטווח הזה נקראים 'גבולות פיצול'. מערכת Spanner מוסיפה ומסירה באופן אוטומטי גבולות פיצול, מה שמשנה את מספר הפיצולים במסד הנתונים. ‫Spanner מפצל את הנתונים על סמך העומס: הוא מוסיף גבולות פיצול באופן אוטומטי כשהוא מזהה עומס גבוה של קריאה או כתיבה שמתפרס על פני הרבה מפתחות בפיצול.
נקודה לשיתוף אינטרנט (Hotspot)
כשפיצול יחיד במסד נתונים מבוזר כמו Spanner מכיל רשומות שמקבלות חלק גדול מכל השאילתות שמופנות למסד הנתונים. התרחיש הזה לא רצוי כי הוא פוגע בביצועים.

שימוש ב-Spanner למשחקים

ברוב המקרים שבהם שוקלים להשתמש ב-RDBMS במשחק, Spanner היא בחירה מתאימה כי היא יכולה להחליף ביעילות את מסד הנתונים של המשחק, את מסד הנתונים של האימות או, במקרים רבים, את שניהם.

מסדי נתונים של משחקים

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

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

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

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

מסדי נתונים של אימות

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

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

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

השיטות המומלצות במסמך הזה מבוססות על חוויות משימוש של לקוחות וממחקרים לדוגמה.

שימוש ב-UUID כמזהי שחקנים ותווים

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

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

שימוש בשילוב נתונים בטבלאות מלאי

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

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

itemID type playerID
7c14887e-8d45 1 6f1ede3b-25e2
8ca83609-bb93 40 6f1ede3b-25e2
33fedada-3400 1 5fa0aa7d-16da
e4714487-075e 23 5fa0aa7d-16da
d4fbfb92-a8bd 14 5fa0aa7d-16da
31b7067b-42ec 3 26a38c2c-123a

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

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

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

תכנון האינדוקס כדי להימנע מנקודות חמות

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

בדוגמה הבאה יש טבלה של שיאי ניקוד של שחקנים לטווח ארוך:

CREATE TABLE Ranking (
        PlayerID STRING(36) NOT NULL,
        GameMode INT64 NOT NULL,
        Score INT64 NOT NULL
) PRIMARY KEY (PlayerID, GameMode)

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

כדי להאיץ את השאילתות שמסננות לפי מצב המשחק, כדאי להשתמש באינדקס הבא:

CREATE INDEX idx_score_ranking ON Ranking (
        GameMode,
        Score DESC
)

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

אם משנים את הסדר של האינדקס הקודם, אפשר לפתור את הבעיה של הנקודה לשיתוף אינטרנט (Hotspot):

CREATE INDEX idx_score_ranking ON Ranking (
        Score DESC,
        GameMode
)

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

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

CREATE TABLE GameMode1Ranking (
        PlayerID STRING(36) NOT NULL,
        Score INT64 NOT NULL
) PRIMARY KEY (PlayerID)

CREATE INDEX idx_score_ranking ON Ranking (
        Score DESC
)

מומלץ להוציא את מצב המשחק מסכימת הטבלה ולהשתמש בטבלה אחת לכל מצב, אם אפשר. כשמשתמשים בשיטה הזו כדי לאחזר את הניקוד של מצב מסוים, השאילתה מופנית רק לטבלה שמכילה את הניקוד של אותו מצב. אפשר ליצור אינדקס של הטבלה הזו לפי הניקוד כדי לאחזר במהירות טווחי ניקוד בלי סיכון משמעותי לנקודות חמות (בתנאי שהניקוד מפוזר היטב). בזמן כתיבת המסמך הזה, מספר הטבלאות המקסימלי לכל מסד נתונים ב-Spanner הוא 2,560, וזה יותר ממספיק לרוב המשחקים.

מסדי נתונים נפרדים לכל דייר

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

איך להימנע מעדכונים מצטברים של סכימות

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

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

כדאי לקחת בחשבון את הגישה למסד הנתונים ואת הגודל שלו

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

שימוש בספריות ובדרייברים מובנים

כשמפתחים ב-Spanner, חשוב לחשוב על האופן שבו הקוד מתקשר עם מסד הנתונים. ב-Spanner יש ספריות לקוח מובנות לשפות פופולריות רבות, והן בדרך כלל עשירות בתכונות ומניבות ביצועים טובים. יש גם מנהלי התקנים של JDBC שתומכים בהצהרות של שפת טיפול בנתונים (DML) ושפת הגדרת נתונים (DDL). במקרים שבהם נעשה שימוש ב-Spanner בפיתוח חדש, מומלץ להשתמש בספריות הלקוח של Cloud ל-Spanner. למרות שבדרך כלל אין הרבה גמישות בבחירת שפה בשילובים של מנועי משחקים, יש מקרים שבהם לקוחות בתחום הגיימינג משתמשים ב-Java או ב-Go כדי לגשת ל-Spanner בשירותי פלטפורמה. לאפליקציות עם תפוקה גבוהה, מומלץ לבחור ספרייה שבה אפשר להשתמש באותו לקוח Spanner לכמה בקשות רצופות.

התאמת גודל מסד הנתונים לצרכים של בדיקות ושל ייצור

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

הערכת הצרכים של Spanner לסביבת הייצור

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

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

הפעלת בדיקות עומס באמצעות נתונים אמיתיים

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

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

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

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

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

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

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

CREATE TABLE Player (
        PlayerID STRING(36) NOT NULL,
        Attribute INT64 NOT NULL
) PRIMARY KEY (PlayerID)

CREATE INDEX idx_attribute ON Player(Attribute)

האינדקס נשאל כדי למצוא עד עשרה שחקנים עם Attribute=23, כמו בדוגמה הבאה:

SELECT PlayerID
        FROM Player@{force_index=idx_attribute}
        WHERE Attribute = 23
        LIMIT 10

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

השחקנים מחולקים בין הפיצולים של Spanner לפי המאפיין שלהם.

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

שחקנים בהשקה עם אותו מאפיין שיוצרים נקודה לשיתוף אינטרנט בפיצול יחיד של Spanner.

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

CREATE TABLE Player (
        PlayerID STRING(36) NOT NULL,
        IndexPartition INT64 NOT NULL
        Attribute INT64 NOT NULL
) PRIMARY KEY (PlayerID)

CREATE INDEX idx_attribute ON Player(IndexPartition,Attribute)

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

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

במקרה הזה, האולפן הקצה ידנית לכל שחקן IndexPartitionבין 1 ל-6 באפליקציית המשחק.

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

כך נראה העדכון של השאילתה הקודמת כדי להשתמש באינדקס המשופר הזה:

SELECT PlayerID
        FROM Player@{force_index=idx_attribute}
        WHERE IndexPartition BETWEEN 1 and 6
        AND Attribute = 23
        LIMIT 10

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

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

בדרך כלל, משחקים פופולריים מגיעים לשיא התנועה שלהם בזמן ההשקה. יצירת קצה עורפי (backend) שניתן להרחבה רלוונטית לא רק לשירותי פלטפורמה ולשרתי משחקים ייעודיים, אלא גם למסדי נתונים. אפשר להשתמש בפתרונות כמו App Engine כדי ליצור שירותי API של קצה קדמי שניתן להרחיב במהירות. Google Cloud למרות ש-Spanner מאפשר גמישות בהוספה והסרה של צמתים אונליין, הוא לא מסד נתונים עם התאמה אוטומטית לעומס. צריך להקצות מספיק צמתים כדי להתמודד עם העלייה החדה בתנועה בזמן ההשקה.

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

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

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

מעקב אחרי הביצועים והבנתם

כל מסד נתונים של ייצור דורש מעקב מקיף ומדדי ביצועים. ל-Spanner יש מדדים מובנים ב-Cloud Monitoring. אם אפשר, מומלץ לשלב את ספריות ה-gRPC שסיפקנו בתהליך העיבוד של ה-backend של המשחק, כי הספריות האלה כוללות מעקב OpenCensus. באמצעות מעקב OpenCensus אפשר לראות את עקבות השאילתות ב-Cloud Trace וגם בכלי מעקב אחרים בקוד פתוח שנתמכים.

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

‫Spanner מציע תוכניות להפעלת שאילתות. אפשר לעיין בתוכניות האלה במסוף Google Cloud ולפנות לתמיכה אם אתם צריכים עזרה בהבנת ביצועי השאילתות.

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

כשמסירים נתונים, מוחקים שורות במקום ליצור מחדש טבלאות

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

בחירת מיקום נתונים כדי לעמוד בדרישות התאימות

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

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