Memorystore for Redis מספק מדדים בזמן אמת בצד השרת למעקב אחרי קצב העברת הנתונים, ניצול המעבד ושימוש בזיכרון, אבל יכול להיות שהנתונים האלה לבדם לא יסבירו למה אפליקציית הלקוח שלכם חווה חביון גבוה במערכות מורכבות ומבוזרות.
מדדים בצד הלקוח פותרים את הבעיה הזו כי הם מספקים שקיפות לגבי המחזור המלא של בקשות ותגובות. הם מודדים פקודה מהרגע שבו האפליקציה מתחילה אותה ועד שהאפליקציה מעבדת את התגובה. בעזרת הנתונים האלה אפשר לקבוע בצורה מדויקת אם זמן האחזור נובע מהלוגיקה של האפליקציה, מנתיב הרשת או משרת Redis.
לפני שמתחילים
מוודאים שאפליקציית הלקוח משתמשת בחשבון שירות, ושמוקצים לה תפקידי ניהול הזהויות והרשאות הגישה (IAM) הבאים:
-
roles/cloudtrace.agent(Cloud Trace Agent) -
roles/monitoring.metricWriter(Monitoring Metric Writer)
מידע נוסף על מתן תפקידים זמין במדריך למתחילים איך נותנים תפקידים ב-IAM באמצעות מסוף Google Cloud .
הפעלת Cloud Monitoring API
כדי לייצא מדדים בצד הלקוח אל Monitoring, צריך להפעיל את Monitoring API באפליקציה. ייצוא של המדדים האלה ל-Monitoring והצגה שלהם מאפשרים לכם לזהות את שורש הבעיה של צווארי בקבוק כדי לקבוע מהיכן נובעת ההשהיה.
כדי להפעיל את Monitoring API:
במסוף Google Cloud , נכנסים לדף APIs & Services.
בוחרים את הפרויקט שבו יצרתם את מכונת Memorystore for Redis.
לוחצים על Enable APIs and services.
חיפוש של
monitoring.בתוצאות החיפוש, לוחצים על Cloud Monitoring API.
אם מופיע הכיתוב API enabled, סימן שממשק ה-API כבר מופעל. אחרת, לוחצים על הפעלה.
הפעלת Cloud Trace API
כדי לראות עקבות מבוזרים ב-Trace, צריך להפעיל את Trace API. אחר כך תוכלו להשתמש ב-Trace Explorer כדי לראות את העקבות האלה, לאבחן צווארי בקבוק ולבודד את מקור זמן האחזור באפליקציה.
כדי להפעיל את Trace API:
במסוף Google Cloud , נכנסים לדף APIs & Services.
בוחרים את הפרויקט שבו יצרתם את מכונת Memorystore for Redis.
לוחצים על Enable APIs and services.
חיפוש של
trace.בתוצאות החיפוש, לוחצים על Cloud Trace API.
אם מופיע הכיתוב API enabled, סימן שממשק ה-API כבר מופעל. אחרת, לוחצים על הפעלה.
הפעלה של מדדים בצד הלקוח
כדי להפעיל מדדים בצד הלקוח, מוסיפים את OpenTelemetry SDK, את כלי הייצוא של Cloud Monitoring ואת כלי הייצוא של Cloud Trace לקוד של האפליקציה. המדדים נאספים על ידי OpenTelemetry, שפועל ישירות בספריית הלקוח של Redis באפליקציה. כך האפליקציה יכולה לתעד נקודות נתונים של זמן האחזור ולייצא אותן ל-Monitoring ול-Trace לצורך ויזואליזציה.
כדי להפעיל מדדים בצד הלקוח, אפשר להשתמש ב-Go, Java, Node.js או Python. בכרטיסיות הבאות מופיע מידע על הפעלת המדדים לכל שפה.
המשך
כדי להתקין את יחסי התלות הנדרשים של OpenTelemetry ושל Google Cloud כלי לייצוא נתונים מריצים את הפקודות הבאות בטרמינל:
go get github.com/gomodule/redigo/redis@latest go get go.opentelemetry.io/otel go get go.opentelemetry.io/otel/sdk/trace go get go.opentelemetry.io/otel/sdk/metric go get github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace go get github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric
כדי להפעיל את המדדים בצד הלקוח, יוצרים קובץ
main.goומוסיפים לו את הקוד הבא:מריצים את האפליקציה למשך דקה לפחות כדי לתת לכלי הייצוא מספיק זמן לאגד את המדדים שפורסמו ולשלוח אותם ל-Monitoring.
Java
כדי להתקין את יחסי התלות הנדרשים של OpenTelemetry ושל Google Cloud exporter מוסיפים את הקוד הבא לקובץ
pom.xmlשל האפליקציה:כדי להפעיל את המדדים בצד הלקוח, יוצרים קובץ
RedisTelemetryApp.javaומוסיפים לו את הקוד הבא:מריצים את האפליקציה למשך דקה לפחות כדי לתת לכלי הייצוא מספיק זמן לאגד את המדדים שפורסמו ולשלוח אותם ל-Monitoring.
Node.js
כדי להתקין את יחסי התלות הנדרשים של OpenTelemetry ושל Google Cloud כלי לייצוא נתונים מריצים את הפקודות הבאות בטרמינל:
npm install redis@^4.6.0 @opentelemetry/api@^1.9.0 @opentelemetry/sdk-trace-node@^2.1.0 @opentelemetry/sdk-trace-base@^2.1.0 @opentelemetry/sdk-metrics@^2.1.0 @opentelemetry/instrumentation@^0.205.0 @opentelemetry/instrumentation-redis@^0.67.0 @google-cloud/opentelemetry-cloud-trace-exporter@^3.0.0 @google-cloud/opentelemetry-cloud-monitoring-exporter@^0.21.0 @opentelemetry/resources@^2.1.0
כדי להפעיל את המדדים בצד הלקוח, יוצרים קובץ
server.jsומוסיפים לו את הקוד הבא:מריצים את האפליקציה למשך דקה לפחות כדי לתת לכלי הייצוא מספיק זמן לאגד את המדדים שפורסמו ולשלוח אותם ל-Monitoring.
Python
כדי להתקין את יחסי התלות הנדרשים של OpenTelemetry ושל Google Cloud כלי לייצוא נתונים מריצים את הפקודות הבאות בטרמינל:
pip install redis==7.0.1 opentelemetry-api==1.39.1 opentelemetry-sdk==1.39.1 opentelemetry-instrumentation-redis==0.60b1 opentelemetry-exporter-gcp-trace==1.11.0 opentelemetry-exporter-gcp-monitoring==1.11.0a0
כדי להפעיל את המדדים בצד הלקוח, יוצרים קובץ
main.pyומוסיפים את הקוד הבא לאפליקציה:מריצים את האפליקציה למשך דקה לפחות כדי לתת לכלי הייצוא מספיק זמן לאגד את המדדים שפורסמו ולשלוח אותם ל-Monitoring.
הצגת מדדים ב'מעקב'
אחרי שמפעילים את המדדים בצד הלקוח ומריצים את האפליקציה למשך דקה לפחות כדי לתת לכלי הייצוא מספיק זמן לאגד את המדדים ולשלוח אותם ל-Monitoring, אפשר להשתמש ב-Monitoring כדי להציג את המדדים באופן חזותי, לקבץ אותם לפי פעולה או מופע ולהחיל פונקציות צבירה כדי לעקוב אחרי הביצועים של האפליקציה.
כדי לראות את המדדים ב-Monitoring:
נכנסים לדף Metrics explorer במסוף Google Cloud .
בוחרים את הפרויקט Google Cloud .
לוחצים על בחירת מדד.
חיפוש של
workload.googleapis.com/redis.בוחרים מדד מצד הלקוח. מקבצים את הנתונים לפי
operationו-instanceלפי הצורך, ובוחרים פונקציית צבירה. כדי לראות אפשרויות נוספות, אפשר לעיין במאמר איך בוחרים מדדים כשמשתמשים ב-Metrics Explorer.
צפייה בנתוני מעקב מבוזרים ב-Trace
אחרי שהאפליקציה מתחילה לייצא נתונים, אפשר להשתמש ב-Trace כדי להציג באופן חזותי את מחזור הבקשה-תגובה המלא של פקודות Redis. הצגת העקבות המבוזרים ב-Trace מאפשרת לאבחן צווארי בקבוק, כך שתוכלו לבודד במהירות את המקור המדויק של זמן האחזור באפליקציה.
כדי לראות את העקבות המבוזרים ב-Trace:
נכנסים לדף Trace explorer במסוף Google Cloud .
בוחרים מעקב אחרון שמיוצג על ידי נקודה בתרשים הפיזור.
בודקים את התצוגה של Waterfall כדי לזהות את מקור זמן האחזור. לשם כך, צריך לזהות את צווארי הבקבוק הבאים:
משך הבקשה הכולל: בסרגל ברמה העליונה (הורה) מוצג הזמן הכולל שצריך לחכות עד שהפעולה תסתיים.
זמן האחזור (RTT) של הרשת והשרת: הפסים המשניים (כמו אלה שמסומנים בתווית
GETאוSET) מראים את הזמן שחלף מהרגע שהפקודה נשלחה ברשת ועד שהיא הופעלה בשרת Memorystore for Redis.חסימת חיבור לקוח: אם יש רווח אופקי גדול וריק לפני תחילת הטווח המשני של Redis, סימן שהשרשור של האפליקציה תקוע בהמתנה לחיבור TCP זמין ממאגר החיבורים.
חסימה של ניתוח האפליקציה: אם יש רווח אופקי גדול וריק אחרי שטווח הצאצא של Redis מסתיים, האפליקציה מתקשה לנתח או לעבד את מטען הייעודי (payload) שמוחזר. זה קורה בדרך כלל עם מחרוזות JSON של כמה מגה-בייט.
ניסיונות חוזרים: אם אתם רואים כמה טווחי צאצא קצרים לאותה פקודה שמתרחשים ברצף באותו מעקב אב, יכול להיות שהלקוח שלכם חווה אובדן של מנות נתונים ברשת, והוא צריך להפעיל את לולאת הניסיון החוזר של הנסיגה האקספוננציאלית.
פתרון בעיות
בקטע הזה מפורטות בעיות נפוצות בביצועים שאפשר לזהות באמצעות מדדים בצד הלקוח. מוסברות בו הסיבות העיקריות לבעיות האלה ומופיעות בו הנחיות לפתרון שלהן.
| שגיאה | מטרה | פתרון בעיות |
|---|---|---|
באפליקציה חווים עלייה פתאומית בחביון, אבל נראה ש-Memorystore for Redis תקין לחלוטין.
|
צוואר הבקבוק נמצא בתוך האפליקציה. השרשורים מנסים להריץ פקודות Redis, אבל מאגר החיבורים מלא. הערך הגבוה redis_client_blocking_latency מייצג
את הזמן שבו הקוד ממתין לשקע TCP זמין לפני שהפקודה נשלחת לרשת. |
כדי לטפל בתנועה המקבילה הגבוהה יותר, צריך להגדיל את מגבלות הגודל של מאגר החיבורים בהגדרות של לקוח Redis (לדוגמה, MaxActive עבור Go, MaxTotal עבור Java או max_connections עבור Node.js ו-Python). |
הבקשה הושלמה, אבל נקודת הקצה נמשכת הרבה יותר זמן מהצפוי. אין בעיות שקשורות לתקינות של הרשת או השרת.
|
הפקודה מורצת ב-Memorystore for Redis והמטען הייעודי (payload) מועבר ברשת במהירות (זמן הלוך ושוב נמוך). עם זאת, המטען הייעודי (payload) שמוחזר גדול (לדוגמה, מחרוזת JSON בגודל 15MB). האפליקציה שלך חווה שימוש גבוה בזיכרון redis_application_blocking_latency כי היא צורכת משאבים מוגזמים בזמן הקצאת הזיכרון וביטול הסדרות של המחרוזת הגדולה הזו לאובייקט. |
אופטימיזציה של מודל הנתונים. לא כדאי לאחסן בלובים גדולים של JSON במפתחות יחידים.
מפרקים את הנתונים באמצעות פונקציות hash של Redis (HSET) ומשתמשים בפקודות HGET או HMGET כדי לאחזר רק את השדות הספציפיים שאתם צריכים.
|
ההשהיה באפליקציה שפונה למשתמשים עולה באופן חד, אבל מדדי Redis מדווחים על השהיה נמוכה בשרת ועל בדיקות אופייניות של מאגר החיבורים.
|
מכיוון ש-redis_client_rtt מתעד רק את זמן ה-RTT של בקשות מוצלחות, הוא לא משקף את משך הזמן הקצוב לתפוגה של מנות שנכשלו. אם האפליקציה חווה נפילות חבילות זמניות או איפוסים של TCP, לוגיקת הניסיון החוזר של הלקוח שמוגדר בו מעקב מגדילה את הערך של redis_retry_count ומפעילה את לולאת ההשהיה המעריכית לפני ניסיון חוזר שלו.
השיטה הזו מוסיפה זמן השהיה בין הניסיונות (למשל, 100ms, 200ms או 400ms). המשתמש חווה זמן השהיה כולל גבוה, אבל שורש הבעיה הוא אובדן מנות ברשת, שגורם להשהיות בצד הלקוח. |
בודקים ביומני הזרימה של ה-VPC אם יש מנות שהושמטו, הגבלת רוחב פס או חריגות בניתוב בין אזורים. אם אתם חווים התנתקויות רשת לאחר שתם הזמן הקצוב לתפוגה,
צריך לוודא שהזמן הקצוב לתפוגה של חיבור הלקוח (socket_timeout או
connect_timeout) גדול יותר מה-RTT הצפוי, כדי להתחשב בתנודות רגעיות ברשת. |
הכול נעצר וכל השכבות של צינור הטלמטריה מדווחות על זמן טעינה ארוך.
|
Redis הוא single-threaded. כשמריצים פקודה של מורכבות זמן O(N) – כמו KEYS *, SMEMBERS על מערך גדול, או HGETALL על hash עם מיליוני שדות – מנוע Redis מושהה כדי למלא את הבקשה. בזמן שהפקודה הזו פועלת, כל בקשה אחרת לאפליקציה נכנסת לתור, מה שגורם לעלייה חדה בשיעור ההשהיה בכל המערכת. מכיוון שהערך המותאם אישית redis_client_rtt תואם לזמן האחזור של השרת (commands/usec_per_call), השרת שמריץ את הפקודה הוא צוואר הבקבוק. |
פותחים את Trace ומסתכלים על פקודות Redis בטווחים האיטיים כדי לזהות איזו שאילתה גורמת לחסימה. מחליפים את פקודות החסימה בפקודות שלא חוסמות בקוד. כדי לבצע איטרציה על מערכי נתונים גדולים באופן מצטבר בלי לנעול את שרשור השרת, משתמשים ב- |
האפליקציה מדווחת על חביון בסיסי גבוה ועקבי לכל פקודות Redis, גם כשהתעבורה נמוכה.
|
שרת Redis מריץ פקודות באופן מיידי, אבל האפליקציה והמכונה שלכם נפרסים באזורים שונים (לדוגמה, us-central1 ו-us-east1). כל מנת נתונים ברשת צריכה לעבור בתשתית הענן הפיזית של Google Cloud בין מרכזי הנתונים הגיאוגרפיים האלה. התוצאה היא קנס חובה של מהירות האור
בכל נסיעה הלוך ושוב בין אזורים. |
כדי להקטין את זמן האחזור, כדאי לפרוס את האפליקציה כך שהיא תמוקם באותו אזור ותחום כמו המופע. כדי לראות את האזור של האפליקציה והמופע, משתמשים במסוף Google Cloud . |