Трейси показують, що запит зайняв 800 мс. Метрики підтверджують: p99 зріс у 3 рази після деплою. Але ні те, ні інше не пояснить, який рядок коду споживає 40% CPU. Для цього потрібен профайлер, що працює в production безперервно. Continuous Profiling — постійний запис профілів (flamegraph'ів) усіх процесів. За 5 років практики знаходили сотні вузьких місць: від JSON-серіалізації в hot path до витоків пам'яті в middleware. Впровадження Pyroscope або Parca дозволяє не просто знаходити проблеми, але й запобігати регресіям при кожному деплої. Зв'яжіться з нами, щоб обговорити впровадження Continuous Profiling у вашому проекті.
Чому варто використовувати Continuous Profiling замість разових профайлерів?
Розберемося, що дає безперервний моніторинг. Разовий py-spy top дає зріз тут і зараз. Continuous profiling дає історію. Якщо сьогодні p95 CPU 70%, а тиждень тому було 50% — flamegraph покаже, який коміт це викликав. Без історії ви будете гадати, коли почалася деградація. Крім того, Pyroscope та Parca в 2–3 рази швидше допомагають розслідувати інциденти завдяки готовій часовій шкалі. Ви можете дивитися, як змінювався flamegraph з кожним деплоєм — це знижує MTTR з годин до хвилин. За даними наших проєктів, економія часу на налагодження досягає 40%, а витрати на інфраструктуру — 15-20%.
Які проблеми вирішує Continuous Profiling?
Розглянемо конкретні сценарії.
Витоки пам'яті, які не видно в метриках
Звичайні container_memory_usage_bytes показують зростання, але не вказують на винуватця. Профайлер heap'а (Pyroscope ProfileInuseObjects) точно показує, який об'єкт і яка функція тримають пам'ять. В одному з проєктів знайшли витік у middleware, який за 6 годин піднімав RSS процесу з 200 МБ до 2 ГБ — flamegraph одразу вказав на код, який неправильно працює з context.Context.
Регресії CPU після деплою
Викотили нову версію — CPU зріс на 300%. Flamegraph 'до' та 'після' показує, яка функція стала повільнішою. Типові знахідки: неочікуване включення налагодження, зміна рівня логування, нова залежність з важкими regexp.
Кореляція з трейсами
При повільному trace, що вказує на span тривалістю 500 мс, flamegraph за той же період покаже, яка функція всередині span зайняла 80% часу. Pyroscope підтримує middleware для 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) | Тільки через лейбли |
| Оверхед CPU | 1–5% (Pull 1-3%, Push 2-5%) | 1-3% |
| Зберігання | S3, GCS, локальний | S3, GCS, локальний |
Отримайте консультацію з вибору інструменту та налаштування.
Як ми налаштовуємо Continuous Profiling
Pyroscope: pull mode (eBPF агент)
Pyroscope Agent запускається як DaemonSet, читає профілі безпосередньо з ядра через eBPF без змін у додатках. Вимагає Kubernetes 1.19+ та ядро Linux 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 — це технологія ядра Linux, яка дозволяє запускати ізольовані програми у відповідь на події (системні виклики, мережеві пакети тощо). У контексті profiling eBPF дозволяє семплювати стек викликів усіх процесів без зміни їх коду. Оверхед мінімальний, оскільки збір відбувається на рівні ядра.Pyroscope: push mode (SDK)
Додаток явно шле профілі до Pyroscope. Дає кращий контроль над лейблами та менший оверхед для конкретних сервісів.
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,
},
})
// ...
}ProfileAllocObjects та ProfileInuseObjects — heap-профілі для пошуку memory leaks. Саме вони допомогли знайти витік у middleware, який за 6 годин піднімав RSS процесу з 200MB до 2GB. Вивчіть 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 Процес впровадження
| Етап | Тривалість | Опис |
|---|---|---|
| Аудит поточного стеку та цілей | 1 день | План профілювання: які сервіси, які метрики, частота семплювання. |
| Розгортання Pyroscope/Parca | 1–2 дні | DaemonSet/Helm-реліз зі зберіганням у S3, дашборди в Grafana. |
| Інтеграція SDK (push-mode) | 1–2 дні на 5 сервісів | Код з SDK, протестований у staging. |
| Кореляція з трейсами та метриками | 1 день | Middleware для OpenTelemetry/Jaeger, посилання з Tempo до Pyroscope. |
| Навчання команди | 0.5 дня | Документація, runbook, розбір типових flamegraph'ів. |
Що входить у роботу
- Документація архітектури та конфігурації (runbook).
- Доступи до дашбордів та джерел профілів.
- Навчання команди (демо-сесія 30 хв).
- Підтримка протягом 2 тижнів після впровадження.
Типові помилки при впровадженні
- Занадто часте семплювання (1000 Hz). Дає надлишковий оверхед (до 10%). Рекомендуємо 100 Hz для CPU, 50 Hz для heap.
- Зберігання профілів у локальному PVC. Легко втрачаються; використовуйте S3 з retention policy.
- Відсутність кореляції з трейсами. Без profile.id flamegraph висить окремо — різко втрачається цінність.
- Не відключати eBPF agent на нодах з високим навантаженням I/O. У деяких випадках він може викликати латенсі; використовуйте tolerations для виділення.
Строк налаштування — від 1 дня (eBPF pull mode без змін у додатках) до 3 днів (push mode SDK для всіх сервісів + кореляція з Tempo + Grafana datasource). Вартість розраховується індивідуально. Замовте аудит вашого стеку для оцінки необхідності Continuous Profiling. Щоб отримати консультацію з впровадження, зв'яжіться з нами — ми оцінимо ваш проект і запропонуємо оптимальну архітектуру.







