תארו לעצמכם: ה-API שלכם מטפל ב-10,000 בקשות בשנייה, השרת האחורי בקושי עומד בעומס, ומחצית מהתשובות מחזירות את אותם נתונים. שמירה במטמון (Caching) ברמת השער (Gateway) פותרת את זה תוך כמה שעות ללא שינוי בקוד השירות. לאחרונה, בפרויקט עם 50 מיקרוסרוויסים, יישמנו שמירה במטמון על Kong, ועומס מסד הנתונים ירד ב-80%, בעוד שזמן התגובה הממוצע ירד מ-500 אלפיות השנייה ל-50 אלפיות השנייה. אנו משלבים שמירה במטמון על השער (Kong, Nginx, AWS) ומפחיתים את עומס השרת האחורי ב-30–70%. לאחר ההגדרה, שיעור הפגיעות (hit rate) מגיע ל-95%. מאמר זה מבוסס על ניסיון מעשי של למעלה מ-10 שנים ביותר מ-40 פרויקטים.
למה שמירה במטמון על השער עדיפה על פני שמירה במטמון על השרת האחורי?
שמירה במטמון ברמת השער מיירטת את הבקשה לפני שהיא מגיעה לשירות. השרת האחורי לא מקבל עומס עבור בקשות שנשמרו במטמון. על השרת האחורי, שמירה במטמון לעיתים קרובות מסבכת את הלוגיקה ודורשת שינויים בכל שירות. השער, לעומת זאת, הוא נקודת הגדרה אחת: הוסיפו תוסף (plugin) או הוראת nginx, וזהו. ב-Kong, התוסף proxy-cache מופעל גלובלית או עבור מסלולים ספציפיים עם שורת הגדרה אחת. החיסכון בתשתית יכול להגיע ל-40% — לקוחות בדרך כלל חוסכים $5,000–$15,000 בחודש בעלויות תשתית.
| קריטריון | מטמון שער | מטמון שרת אחורי |
|---|---|---|
| עומס על שירותים | אפס עבור בקשות שנשמרו במטמון | מלא (הבקשה מגיעה לשירות) |
| מורכבות יישום | הגדרה אחת (תוסף/הוראה) | דורש שינויים בכל שירות |
| נקודת ניהול אחת | כן | לא (תצורה מבוזרת) |
| ביצועים | עד 100,000 RPS על Nginx | תלוי ביישום |
אילו נקודות קצה (Endpoints) לשמור במטמון ואילו לא?
בטוח לשמור במטמון:
-
GETבקשות עם נתונים ציבוריים (קטלוג, ספריות, מאמרים) - תשובות עם כותרות
Cache-Control: public, max-age=Nמהשרת העליון (upstream) - נקודות קצה שאינן תלויות בסשן או באימות
אין לשמור במטמון:
- כל
POST,PUT,PATCH,DELETE - בקשות עם
Authorization: Bearer ...(למעט בידוד מבוסס משתמש) - תשובות עם סטטוס 4xx/5xx (למעט שמירה במטמון מכוונת של 404)
- נתונים אישיים
הגדרת שמירה במטמון ב-Kong, Nginx ו-AWS
להלן תצורות עבודה לשלושה שערים פופולריים. כולן נבדקו בשטח.
Kong Gateway: תוסף proxy-cache
---
plugins:
- name: proxy-cache
config:
response_code:
- 200
- 301
- 404
request_method:
- GET
- HEAD
content_type:
- application/json
- application/json; charset=utf-8
cache_ttl: 300
strategy: memory
memory:
dictionary_name: kong_db_cache
# Для production замените strategy на redis:
# strategy: redis
# redis:
# host: redis.internal
# port: 6379
# timeout: 2000
# database: 0
# password: ${REDIS_PASSWORD}
---
Kong מוסיף את הכותרת plugins: - name: proxy-cache config: response_code: [200, 301, 404] request_method: [GET, HEAD] content_type: - application/json - application/json; charset=utf-8 cache_ttl: 300 strategy: memory memory: dictionary_name: kong_db_cache # Для production замените strategy на redis: # strategy: redis # redis: # host: redis.internal # port: 6379 # timeout: 2000 # database: 0 # password: ${REDIS_PASSWORD} עם הערכים X-Cache-Status, Hit, Miss, Bypass. זה עוזר בניפוי באגים.
ביטול מטמון דרך Admin API:
# Удалить конкретный ключ
curl -X DELETE http://kong-admin:8001/proxy-cache/caches/{cache_key}
# Очистить весь кэш
curl -X DELETE http://kong-admin:8001/proxy-cache/ AWS API Gateway + ElastiCache
עבור REST API, שמירה במטמון מקורית מופעלת כך:
{
"cacheClusterEnabled": true,
"cacheClusterSize": "0.5",
"methodSettings": {
"GET /products": {
"cachingEnabled": true,
"cacheTtlInSeconds": 300,
"cacheDataEncrypted": false,
"requireAuthorizationForCacheControl": false
}
}
}קוד Terraform:
resource "aws_api_gateway_stage" "main" {
deployment_id = aws_api_gateway_deployment.main.id
rest_api_id = aws_api_gateway_rest_api.main.id
stage_name = "v1"
cache_cluster_enabled = true
cache_cluster_size = "0.5"
method_settings {
resource_path = "/products"
http_method = "GET"
settings {
caching_enabled = true
cache_ttl_in_seconds = 300
}
}
}ביטול באמצעות בקשה עם כותרת Refresh (דורש הרשאת # Удалить конкретный ключ curl -X DELETE http://kong-admin:8001/proxy-cache/caches/{cache_key} # Очистить весь кэш curl -X DELETE http://kong-admin:8001/proxy-cache/ ).
Nginx: proxy_cache
proxy_cache_path /var/cache/nginx/api levels=1:2 keys_zone=api_cache:10m max_size=1g inactive=10m use_temp_path=off;
server {
location /api/v1/catalog/ {
proxy_cache api_cache;
proxy_cache_valid 200 5m;
proxy_cache_valid 404 1m;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503;
proxy_cache_background_update on;
proxy_cache_lock on;
# Ключ кэша — без параметров авторизации
proxy_cache_key "$scheme$request_method$host$uri$is_args$args";
# Не кэшировать, если клиент передаёт куку сессии
proxy_cache_bypass $cookie_session_id;
proxy_no_cache $cookie_session_id;
add_header X-Cache-Status $upstream_cache_status;
proxy_pass http://backend;
}
}{ "cacheClusterEnabled": true, "cacheClusterSize": "0.5", "methodSettings": { "GET /products": { "cachingEnabled": true, "cacheTtlInSeconds": 300, "cacheDataEncrypted": false, "requireAuthorizationForCacheControl": false } } } + resource "aws_api_gateway_stage" "main" { deployment_id = aws_api_gateway_deployment.main.id rest_api_id = aws_api_gateway_rest_api.main.id stage_name = "v1" cache_cluster_enabled = true cache_cluster_size = "0.5" method_settings { resource_path = "/products" http_method = "GET" settings { caching_enabled = true cache_ttl_in_seconds = 300 } } } מיישם את תבנית stale-while-revalidate: המשתמש מקבל מיידית את התשובה הישנה בזמן שהעדכון מתרחש ברקע. קריטי עבור נקודות קצה בעומס גבוה.
השוואת ביצועים: Nginx על שער מטפל בעד 100,000 RPS, שזה פי 2 יותר מ-Kong במצב זיכרון (50,000 RPS). AWS REST API מטפל בעד 10,000 RPS בהתאם לגודל האשכול.
| שער | אסטרטגיית מטמון | ביטול | ביצועים |
|---|---|---|---|
| Kong | זיכרון/redis | Admin API | ~50,000 rps לכל מופע |
| Nginx | דיסק | מודול purge | ~100,000 rps |
| AWS REST | בזיכרון | Cache-Control | ~10,000 rps (תלוי בגודל) |
מניעת מפולת מטמון (Cache Stampede)
כאשר ה-TTL של מפתח פופולרי פג, עשרות עובדים (workers) פונים בו-זמנית לשרת העליון — זה נקרא מפולת מטמון. שלוש גישות להפחתה:
-
מנעול (Mutex/lock): רק בקשה אחת מעדכנת את המטמון, האחרות ממתינות (לדוגמה,
Cache-Control: max-age=0ב-Nginx). - פגיעה מוקדמת הסתברותית: עדכון המטמון מעט לפני ה-TTL עם הסתברות שעולה ככל שמתקרבים לזמן הפקיעה.
- Stale-while-revalidate: הגשת התשובה הישנה בזמן שהעדכון מתבצע (מיושם לעיל).
ביטול מטמון הוא כאב הראש של השמירה במטמון. הדרך האמינה ביותר היא שימוש בגרסאות משאבים (לדוגמה, execute-api:InvalidateCache במקום proxy_cache_path /var/cache/nginx/api levels=1:2 keys_zone=api_cache:10m max_size=1g inactive=10m use_temp_path=off; server { location /api/v1/catalog/ { proxy_cache api_cache; proxy_cache_valid 200 5m; proxy_cache_valid 404 1m; proxy_cache_use_stale error timeout updating http_500 http_502 http_503; proxy_cache_background_update on; proxy_cache_lock on; # Ключ кэша — без параметров авторизации proxy_cache_key "$scheme$request_method$host$uri$is_args$args"; # Не кэшировать, если клиент передаёт куку сессии proxy_cache_bypass $cookie_session_id; proxy_no_cache $cookie_session_id; add_header X-Cache-Status $upstream_cache_status; proxy_pass http://backend; } } ). אם גרסאות אינה אפשרית, השתמשו ב:
- בקשות Purge (Nginx purge, Kong Admin API).
- TTL קצר עם עדכונים מקבילים (stale-while-revalidate).
- ביטול מבוסס תגיות (לדוגמה, דרך Surrogate-Key ב-Kong).
לעולם אל תנקו את כל המטמון אלא אם כן הכרחי — זה יגרום למפולת מטמון.
תהליך העבודה
- ניתוח: ביקורת על נקודות קצה, זיהוי מועמדים לשמירה במטמון.
- תכנון: בחירת אסטרטגיה, מפתח מטמון, TTL, שיטת ביטול.
- יישום: הגדרת שער, כתיבת Terraform/Ansible במידת הצורך.
- בדיקות: מדידת יחס פגיעות, אימות נכונות עבור בקשות מורשות.
- ניטור: לוחות מחוונים עם שיעור פגיעות, גודל מטמון, מספר החטאות.
מה כלול בעבודה
- הגדרת שמירה במטמון עבור מסלולים נבחרים.
- תיעוד על ביטול וניטור.
- הדרכת צוות (1–2 שעות).
- אחריות לפעולה תקינה למשך חודש אחד.
צרו קשר לייעוץ — נעריך את הפרויקט שלכם תוך יום אחד. ניסיון של למעלה מ-10 שנים ו-40+ יישומים מוצלחים מבטיחים תוצאות. הזמינו הגדרת שמירה במטמון וקבלו תוצאות תוך 1–5 ימים.







