ב-Spanner יש שני מצבים של בקרת בו-זמניות בעסקאות: פסימי ואופטימי. הבחירה במצב של בקרת בו-זמניות משפיעה על האופן שבו טרנזקציות מטפלות בפעולות קריאה וכתיבה בו-זמניות, ומשפיעה על הביצועים, זמן האחזור ושיעורי ביטול הטרנזקציות. בוחרים את המצב שהכי מתאים לדרישות הביצועים והעקביות של האפליקציה.
ההתנהגות שמוגדרת כברירת מחדל תלויה ברמת הבידוד שבה נעשה שימוש בעסקה:
- בידוד ניתן לסדר משתמש בבקרת בו-זמניות פסימית כברירת מחדל.
- בידוד קריאה חוזרת, נעשה שימוש בבקרת בו-זמניות אופטימית כברירת מחדל.
בקרת בו-זמניות פסימית
כברירת מחדל, Spanner משתמש במקביליות פסימית עם בידוד ניתן לסדר. אפשר גם להשתמש במקביליות פסימית עם בידוד קריאה חוזרת.
בו-זמניות פסימית בבידוד שניתן לסדר
במצב הזה, המערכת מניחה שעסקאות מקבילות עשויות להתחרות על אותם נתונים. היא מקבלת נעילות באופן יזום על נתונים בזמן שהיא קוראת או כותבת אותם בתוך טרנזקציה. הוא גם מוודא שהנעילות שהושגו מוקדם יותר בעסקה נשארות בתוקף בהמשך. כש-Spanner מזהה התנגשות נעילה, הוא משתמש באלגוריתם wound-wait כדי לפתור את ההתנגשות.
במקביליות פסימית, העסקאות מקבלות נעילות על הנתונים במהלך שלבי הביצוע והאישור של העסקה.
- לפעולות קריאה: כשעסקה קוראת נתונים, היא מקבלת נעילת קריאה משותפת (
ReaderShared) במהלך שלב הביצוע. הנעילות האלה נשמרות עד שהטרנזקציה מתבצעת. - ל-DML ולפעולות כתיבה:
- במהלך ההרצה, אם נתונים משתנים על ידי DML או פעולות כתיבה, יכול להיות שהטרנזקציה תקבל נעילות קריאה על קיום השורה.
- בזמן ביצוע השינויים, העסקה מנסה לקבל נעילות כתיבה או נעילות בלעדיות לנתונים שנכתבו. נעילות כתיבה חוסמות קריאות בו-זמניות, אבל יכול להיות שהן לא יחסמו כתיבות בו-זמניות, במיוחד אם נעילות הכתיבה משמשות את שתי הפעולות. המשמעות היא שכמה עסקאות יכולות להתקדם לשלב האישור, והתנגשויות של כתיבה-כתיבה נפתרות בזמן האישור באמצעות אלגוריתם wound-wait. כל הנעילות נשמרות עד שהעסקה מתבצעת.
בו-זמניות פסימית בבידוד קריאה חוזרת
שימוש במקביליות פסימית בבידוד של קריאה חוזרת כדי לבצע סריאליזציה של פעולות כתיבה. במצב הזה, פעולות קריאה משתמשות בתמונות מצב, אבל נעילות בלעדיות חלות על נתונים שנקראים משאילתות FOR UPDATE או מרמזים של lock_scanned_ranges=exclusive, ועל נתונים שנכתבים באמצעות שאילתות DML.
היתרונות של שימוש במקביליות פסימית עם בידוד ניתן לסריאליזציה
היתרון העיקרי בשימוש במקביליות פסימית עם בידוד ניתן לסדרות הוא שבמקרים של עומסי עבודה עם רמת סיכון גבוהה, היא עוזרת לעסקאות להתקדם. במהלך קונפליקטים, מערכת Spanner נותנת עדיפות לעסקאות ישנות יותר על פני עסקאות חדשות יותר, כדי להבטיח שהעסקאות יושלמו בסופו של דבר ולצמצם את מספר העסקאות שבוטלו שוב ושוב.
היתרונות של שימוש במקביליות פסימית עם בידוד של קריאה חוזרת
בבידוד של קריאה חוזרת, יכול להיות שעסקאות שרוכשות נעילות עדיין יבוטלו בזמן ביצוע הפעולה (commit) אם הנתונים שנקראו כחלק משאילתה עם FOR UPDATE או כחלק משאילתת DML, שונו על ידי עסקה מקבילה לפני שהעסקה מתבצעת. אבל אחרי שהנעילות מתבצעות, הן מונעות עדכונים מקבילים נוספים עד שהעסקה מתבצעת, וכך הכתיבות מתבצעות ברצף.
הסיכונים של בו-זמניות פסימית
מקביליות פסימית עם בידוד שניתן לסדר בסדרות מציגה את הסיכונים הבאים:
- קריאות ארוכות עלולות לחסום כתיבות שרגישות לזמן האחזור.
- עסקאות שכוללות אינטראקציה של המשתמש לפני השלמתן עלולות לגרום לנעילות להישאר בתוקף למשך זמן רב, ולחסום פעולות אחרות.
תרחישי שימוש במקביליות פסימית עם בידוד ניתן לסריאליזציה
בו-זמניות פסימית מתאימה לעומסי עבודה עם מחלוקות רבות על קריאה-כתיבה וכתיבה-כתיבה. הוא מתאים גם כשביטול של טרנזקציה וניסיון חוזר יקרים. מומלץ להשתמש במצב ברירת המחדל הזה אלא אם עומס העבודה כולל עיכובים ארוכים מדי בנעילה או מושפע באופן משמעותי מהתנגשויות נעילה.
תרחישי שימוש במקביליות פסימית עם בידוד של קריאה חוזרת
משתמשים במקביליות פסימית עם קריאה חוזרת לעומסי עבודה שנדרש בהם סעיף FOR UPDATE או שאילתות DML כדי לקבל נעילות. הגישה הזו שימושית במיוחד לעומסי עבודה שהועברו אל Spanner ממסדי נתונים אחרים שרוכשים נעילות עבור ההצהרות האלה.
בקרת בו-זמניות אופטימית
Spanner מספק גם בקרת בו-זמניות אופטימית. כשמשתמשים בבידוד קריאה חוזרת, מצב ברירת המחדל הוא בקרת מקביליות אופטימית. אפשר גם להגדיר בידוד שניתן לסדר בסדרות כדי להשתמש בבקרת בו-זמניות אופטימית.
בקרת בו-זמניות אופטימית מניחה שהתנגשויות הן נדירות. פעולות קריאה ושאילתות, גם בתוך טרנזקציה של קריאה וכתיבה, מתבצעות בלי לקבל נעילות.
בבידוד הניתן לסדרות (serializable) שמוגדר כברירת מחדל ב-Spanner, פעולות קריאה מאומתות בזמן ביצוע הפעולה (commit). כך מוודאים שאף עסקה אחרת שבוצעה במקביל לא שינתה את הנתונים שהעסקה קראה קודם. אם משתמשים בבידוד קריאה חוזרת, קריאות עם רמז FOR UPDATE או lock_scanned_ranges=exclusive מאומתות בזמן השמירה. אם Spanner מזהה התנגשות, הוא מבטל את העסקה.
איך פועלת אופטימיזציה של פעולות בו-זמניות
בו-זמניות אופטימית משנה את האופן שבו Spanner מבצע קריאות, שאילתות ומחויבויות של טרנזקציות. הוא מבצע הרצה ללא נעילה במהלך שלב הקריאה ומאמת את העקביות בשלב השמירה.
לקריאות ולשאילתות
קריאות ושאילתות לא גורמות לנעילה. כל פעולות הקריאה והשאילתות בטרנזקציה אופטימית מבוצעות בנקודת זמן אחת של תמונת מצב. מערכת Spanner בוחרת את חותמת הזמן הזו כשהפעולה הראשונה של קריאה או שאילתה מבוצעת. כך מובטח שכל הקריאות והשאילתות הבאות בתוך העסקה יראו את הפעולות שבוצעו לפני הקריאה או השאילתה הראשונה.
לקריאה וכתיבה
בטרנזקציה אופטימית עם פעולות קריאה וכתיבה, Spanner מבצע שלב אימות בזמן השמירה. העסקה תתבצע בהצלחה רק אם לא יזוהו התנגשויות ויתקיימו התנאים הבאים:
- אין התנגשות בין פעולות כתיבה שבוצעו בו-זמנית לבין הנתונים שנקראו על ידי העסקה הזו. כלומר, לא בוצעו פעולות כתיבה אחרי חותמת הזמן של הקריאה, אבל לפני שהעסקה הזו ביצעה את פעולות הכתיבה שלה.
- הסכימה לא שונתה מאז חותמת הזמן של הקריאה.
רמת הבידוד קובעת את קבוצת הקריאות שעוברות אימות. בבידוד ניתן לסדר את כל הקריאות. בבידוד קריאה חוזרת, קריאות עם רמז FOR UPDATE או lock_scanned_ranges=exclusive מאומתות בזמן ביצוע השינויים.
במקרים של מחלוקת גבוהה, יכול להיות שעסקאות אופטימיות יבוטלו שוב ושוב. לעומת זאת, בעסקאות פסימיות, התנגשויות קריאה-כתיבה נפתרות על ידי אישור העסקה הישנה וניסיון חוזר של העסקה החדשה.
היתרונות של אופטימיזציה של פעולות מקבילות
היתרונות של שימוש במקביליות אופטימית:
- פעולות קריאה לא מקבלות נעילות: עסקאות אופטימיות לא מקבלות נעילות לקריאות, כך שקריאות ארוכות לא חוסמות כתיבות רגישות לזמן האחזור.
- זמן האחזור של פעולות commit בעסקאות לקריאה בלבד קצר יותר: כל פעולות הקריאה בעסקה אופטימית מבוססות על חותמת זמן של תמונת מצב זהה, ולכן אין צורך לאמת את העקביות במהלך הביצוע או ה-commit של פעולות הקריאה האלה, מה שמקצר משמעותית את זמן האחזור.
הסיכונים של אופטימיזציה של פעולות בו-זמניות
שימוש במקביליות אופטימית כרוך בסיכונים, במיוחד במקרים של מחלוקת גבוהה על קריאה וכתיבה כשמשתמשים בבידוד ניתן לסדר. חשוב להבין את הסיכונים האלה לפני שמשתמשים בבקרת בו-זמניות אופטימית עם בידוד ניתן לסריאליזציה עבור עומס העבודה.
- במקרים של תחרות גבוהה על קריאה וכתיבה, יכול להיות שיהיה שיעור גבוה של ביטולים בעסקאות אופטימיות, כי פעולות כתיבה מקבילות עלולות לפסול את הקריאות של עסקה אופטימית.
- אם יש תחרות גבוהה ומתמשכת על משאבים, יכול להיות שעסקה תבוטל שוב ושוב ולא תאושר בגלל מחסור במשאבים.
תרחישי שימוש במקביליות אופטימית
מקביליות אופטימית מתאימה לעומסי עבודה טרנזקציונליים עם מחלוקת נמוכה על קריאה וכתיבה. בנוסף, היא מועילה לעומסי עבודה שבהם אפשר לבטל עסקאות.
כדאי להשתמש במקביליות אופטימית בעומסי העבודה הבאים:
- עומסי עבודה עם עדיפות נמוכה, שסובלים השהיות, עם טרנזקציות ארוכות: כדאי להשתמש במקביליות אופטימית אם קריאות או שאילתות ארוכות עלולות לגרום להשהיות בכתיבות שרגישות להשהיות. כך נמנעים עיכובים שנגרמים מנעילות קריאה. לדוגמה, עסקאות בלקוחות לנייד עם חיבורים איטיים, או עסקאות עם SLA נמוך שכוללות נעילות קריאה עבור שורות רבות או טווחים גדולים.
- קריאה של עומסי עבודה טרנזקציוניים שרגישים לזמן אחזור עם תחרות נמוכה על קריאה וכתיבה: בהגדרה של כמה אזורים, משתמשים במקביליות אופטימית כדי להציג קריאות אזוריות, להפחית את זמני האחזור של הקריאה ולהימנע מבעיות בייצור כתוצאה מתנועת קריאה לא סדירה לפיצול פעיל. הוא גם משפר את זמינות הקריאה במהלך עומס יתר או חוסר זמינות של הלידר.
- עומסי עבודה טרנזקציוניים שבהם רוב הטרנזקציות הן לקריאה בלבד: מעבר לשימוש במקביליות אופטימית מקטין את זמן האחזור של אישור הטרנזקציות הנפוצות לקריאה בלבד בעומסי העבודה האלה. כדי למנוע שיעורי ביטול גבוהים של עסקאות קריאה-כתיבה, חשוב לוודא שיש תחרות נמוכה על משאבי קריאה-כתיבה.
מומלץ להימנע משימוש במקביליות אופטימית בעומסי עבודה טרנזקציוניים שרגישים לזמן האחזור, שבהם יש התנגשויות תכופות בין פעולות קריאה וכתיבה.
הגדרת בקרת בו-זמניות
אפשר להשתמש בספריות הלקוח של Spanner, ב-REST וב-RPC API כדי לציין את מצב הבו-זמניות של טרנזקציות לקריאה ולכתיבה.
ספריות לקוח
Java
המשך
Node.js
Python
C#
C++
PHP
Ruby
REST
API בארכיטקטורת REST של Spanner TransactionOptions מספק ספירה (enum) של ReadLockMode בתוך ההודעה ReadWrite שמאפשרת לבחור את מצב הנעילה PESSIMISTIC או OPTIMISTIC.
RPC
ממשק ה-API של Spanner Transactionoptions
RPC מספק את סוג ה-enum ReadLockMode בהודעה ReadWrite שמאפשר לבחור את מצב הנעילה PESSIMISTIC או OPTIMISTIC.
דרייברים
אפשר להשתמש בדרייברים של Spanner כדי להגדיר את read_lock_mode כפרמטר חיבור ברמת החיבור או כאפשרות של הצהרת SET ברמת העסקה. מידע נוסף על כל דרייבר זמין במאמר סקירה כללית על דרייברים.