טרייסים מראים שבקשה לקחה 800 אלפיות השנייה. מדדים מאשרים ש-p99 שולש לאחר דיפלוי. אבל אף אחד מהם לא מסביר איזו שורת קוד צורכת 40% CPU. לשם כך, אתה צריך פרופיילר שרץ ברציפות בפרודקשן. פרופיילינג רציף — הקלטה קבועה של פרופיילים (flamegraphs) של כל התהליכים. במשך 5 שנות ניסיון, מצאנו מאות צווארי בקבוק: מסריאליזציית JSON בנתיבים חמים ועד דליפות זיכרון במידלוור. יישום Pyroscope או Parca לא רק מוצא בעיות אלא גם מונע רגרסיות בכל דיפלוי. דברו על פרופיילינג רציף לפרויקט שלכם וקבלו ייעוץ.
למה פרופיילינג רציף על פני פרופיילרים חד-פעמיים?
בואו נראה מה ניטור רציף מביא. py-spy top חד-פעמי נותן תמונת מצב כאן ועכשיו. פרופיילינג רציף נותן היסטוריה. אם היום p95 CPU הוא 70% ולפני שבוע היה 50%, ה-flamegraph מראה איזו קומיט גרמה לקפיצה. בלי היסטוריה, תנחשו מתי התחילה ההידרדרות. יתרה מזאת, Pyroscope ו-Parca עוזרים לחקור תקלות פי 2–3 מהר יותר בזכות ציר זמן מוכן. אתם יכולים לראות איך ה-flamegraph השתנה עם כל דיפלוי — מצמצם את ה-MTTR משעות לדקות. בהתבסס על הפרויקטים שלנו, חיסכון בזמן דיבוג מגיע ל-40%, ועלויות התשתית יורדות ב-15–20%.
אילו בעיות פרופיילינג רציף פותר?
בואו נסתכל על תרחישים ספציפיים.
דליפות זיכרון בלתי נראות במדדים
container_memory_usage_bytes סטנדרטי מראה גידול אבל לא את האשם. פרופיילר heap (Pyroscope ProfileInuseObjects) מאתר בדיוק איזה אובייקט ואיזו פונקציה מחזיקים זיכרון. בפרויקט אחד, מצאנו דליפה במידלוור שהעלתה את ה-RSS של התהליך מ-200 MB ל-2 GB ב-6 שעות — ה-flamegraph הצביע מיד על קוד שעשה שימוש לרעה ב-context.Context.
רגרסיות CPU לאחר דיפלוי
שחררו גרסה חדשה — CPU קופץ ב-300%. flamegraph 'לפני' ו'אחרי' מראה איזו פונקציה האטה. ממצאים טיפוסיים: מצב דיבוג מקרי, שינוי ברמת לוג, תלות חדשה עם regexps כבדים.
מתאם עם טרייסים
כשטרייס איטי מצביע על span של 500 אלפיות השנייה, ה-flamegraph לאותה תקופה מראה איזו פונקציה בתוך ה-span לקחה 80% מהזמן. Pyroscope תומך במידלוור עבור OpenTelemetry ו-Jaeger — profile.id נכתב ל-span אוטומטית.
איזה כלי לבחור: Pyroscope או Parca?
| מאפיין | Pyroscope (Grafana) | Parca (PolarSignals) |
|---|---|---|
| מצב פעולה | Push-mode (SDK) + Pull-mode (eBPF) | רק Pull-mode (eBPF) |
| צורך בשינויי קוד | Push-mode — כן, Pull-mode — לא | לא |
| שפות נתמכות | Java, Go, Python, Node.js, Ruby (Pull) | כל תהליך על הצומת |
| אינטגרציית טרייסים | מובנית (OpenTelemetry, Jaeger) | רק דרך labels |
| עומס CPU | 1–5% (Pull 1-3%, Push 2-5%) | 1-3% |
| אחסון | S3, GCS, מקומי | S3, GCS, מקומי |
קבלו ייעוץ מומחה לבחירת כלי והתקנה — צרו קשר לייעוץ.
איך אנחנו מקימים פרופיילינג רציף
Pyroscope: Pull Mode (סוכן eBPF)
סוכן Pyroscope רץ כ-DaemonSet, קורא פרופיילים ישירות מהקרנל דרך eBPF ללא שינויי אפליקציה. דורש Kubernetes 1.19+ וקרנל לינוקס 4.9+.
---
# pyroscope-values.yaml для Helm pyroscope:
replicaCount: 1
storage:
backend: s3
s3:
bucket: my-pyroscope-profiles
region: eu-west-1
agent:
enabled: true
tolerations:
- operator: Exists # деплоить на все ноды включая system
config:
discovery.relabel "pods" {} # автодискавери подов
איך eBPF עובד?
eBPF היא טכנולוגיית קרנל לינוקס המאפשרת הרצת תוכניות מבודדות בתגובה לאירועים (קריאות מערכת, חבילות רשת וכו'). בפרופיילינג, eBPF דוגם מחסניות קריאה של כל התהליכים ללא שינוי הקוד שלהם. העומס מינימלי כי האיסוף מתרחש ברמת הקרנל.Pyroscope: Push Mode (SDK)
האפליקציה שולחת פרופיילים במפורש ל-Pyroscope. זה נותן שליטה עדינה יותר על labels ועומס נמוך יותר עבור שירותים ספציפיים.
Go SDK:
import "github.com/grafana/pyroscope-go"
func main() {
pyroscope.Start(pyroscope.Config{
ApplicationName: "order-service",
ServerAddress: "http://pyroscope:4040",
Tags: map[string]string{
"version": os.Getenv("APP_VERSION"),
"region": os.Getenv("REGION"),
},
ProfileTypes: []pyroscope.ProfileType{
pyroscope.ProfileCPU,
pyroscope.ProfileAllocObjects,
pyroscope.ProfileAllocSpace,
pyroscope.ProfileInuseObjects,
pyroscope.ProfileInuseSpace,
},
})
// ...
}# pyroscope-values.yaml для Helm pyroscope: replicaCount: 1 storage: backend: s3 s3: bucket: my-pyroscope-profiles region: eu-west-1 agent: enabled: true tolerations: - operator: Exists # деплоить на все ноды включая system config: discovery.relabel "pods" {} # автодискавери подов ו-import "github.com/grafana/pyroscope-go" func main() { pyroscope.Start(pyroscope.Config{ ApplicationName: "order-service", ServerAddress: "http://pyroscope:4040", Tags: map[string]string{ "version": os.Getenv("APP_VERSION"), "region": os.Getenv("REGION"), }, ProfileTypes: []pyroscope.ProfileType{ pyroscope.ProfileCPU, pyroscope.ProfileAllocObjects, pyroscope.ProfileAllocSpace, pyroscope.ProfileInuseObjects, pyroscope.ProfileInuseSpace, }, }) // ... } הם פרופילי heap למציאת דליפות זיכרון. הם עזרו למצוא את דליפת המידלוור שהעלתה את ה-RSS מ-200MB ל-2GB ב-6 שעות. חקרו את Pyroscope להבנה מעמיקה יותר.
Parca: אלטרנטיבה מוכוונת eBPF
Parca בנוי 100% על eBPF, יותר מינימליסטי, ואינו דורש שינויי קוד.
helm install parca parca/parca \
--set parca.config.object_storage.bucket.type=S3 \
--set parca.config.object_storage.bucket.config.bucket=my-parca-profiles תהליך היישום
| שלב | משך | תיאור |
|---|---|---|
| ביקורת על המחסן הנוכחי ומטרות | יום אחד | תוכנית פרופיילינג: אילו שירותים, אילו מדדים, תדירות דגימה. |
| פריסת Pyroscope/Parca | 1–2 ימים | DaemonSet/Helm release עם אחסון S3, דשבורדים ב-Grafana. |
| אינטגרציית SDK (push-mode) | 1–2 ימים לכל 5 שירותים | קוד עם SDK, נבדק ב-staging. |
| מתאם עם טרייסים ומדדים | יום אחד | מידלוור עבור OpenTelemetry/Jaeger, קישורים מ-Tempo ל-Pyroscope. |
| הדרכת הצוות | חצי יום | תיעוד, runbook, סיור טיפוסי ב-flamegraph. |
מה כלול בעבודה
- תיעוד ארכיטקטורה ותצורה (runbook).
- גישה לדשבורדים ומקורות פרופיילים.
- הדרכת צוות (סשן הדגמה של 30 דקות).
- תמיכה לשבועיים לאחר היישום.
טעויות יישום נפוצות
- דגימה תכופה מדי (1000 הרץ). גורמת לעומס מופרז (עד 10%). אנו ממליצים על 100 הרץ ל-CPU, 50 הרץ ל-heap.
- אחסון פרופיילים על PVC מקומי. נאבד בקלות; השתמשו ב-S3 עם מדיניות שמירה.
- חוסר מתאם טרייסים. בלי profile.id, ה-flamegraph יושב מבודד — מאבד ערך דרמטית.
- אי-החרגת סוכן eBPF מצמתים עם עומס I/O גבוה. במקרים מסוימים זה יכול לגרום ל-latency; השתמשו ב-tolerations לבידוד.
זמן ההתקנה נע בין יום אחד (eBPF pull-mode ללא שינויי אפליקציה) ל-3 ימים (push-mode SDK לכל השירותים בתוספת מתאם טרייסים ומקור נתונים ב-Grafana). התמחור מותאם אישית לאחר הערכה מפורטת. לקבלת ייעוץ על יישום, צרו קשר — נעריך את הפרויקט שלכם ונציע ארכיטקטורה אופטימלית.







