Ответ
Для комплексной оценки производительности БД я отслеживаю несколько ключевых групп метрик.
1. Метрики времени отклика (Latency)
Это самая важная метрика с точки зрения пользователя. Я смотрю не на среднее, а на перцентили:
- p99 (99-й перцентиль): Показывает максимальное время отклика для 99% запросов. Это ключевая метрика для соблюдения SLA, так как она отсекает редкие, но критичные выбросы. Если p99 в норме, значит, почти все пользователи получают хороший опыт.
- p95 и p50 (медиана): Помогают понять общее распределение времени отклика.
Почему перцентили важнее среднего (average)? Среднее значение может скрывать проблемы. Например, 99 быстрых запросов по 10 мс и 1 очень медленный запрос на 1 секунду дадут среднее ~20 мс, что выглядит отлично. Но p99 покажет реальную проблему — 1-секундный запрос, который испортил опыт одному пользователю.
2. Метрики пропускной способности (Throughput)
- QPS (Queries Per Second) / RPS (Requests Per Second): Показывает текущую нагрузку на базу данных. Помогает соотнести рост времени отклика с ростом нагрузки.
3. Метрики ошибок (Error Rate)
- Количество ошибок в секунду/минуту: Отслеживание ошибок подключения, таймаутов, deadlock'ов и других сбоев. Рост этой метрики — явный сигнал о проблемах.
4. Метрики утилизации ресурсов
- CPU / Memory / Disk I/O: Помогают диагностировать, не упирается ли производительность в аппаратные ограничения.
- Connection Pool Metrics: Количество активных, ожидающих и свободных соединений. Если много запросов в очереди (waiting), это указывает на нехватку соединений или медленную обработку запросов.
Пример реализации с Prometheus в Go:
Обычно это реализуется через middleware или обертку над database/sql
.
// Псевдокод для иллюстрации
// Создаем гистограмму для замера времени выполнения запросов
var dbQueryDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{
Name: "db_query_duration_seconds",
Help: "Duration of database queries.",
}, []string{"query_name"})
func executeQuery(queryName string) {
start := time.Now()
// ... логика выполнения запроса к БД ...
// db.Query("SELECT ...")
duration := time.Since(start)
// Записываем наблюдение в метрику
dbQueryDuration.WithLabelValues(queryName).Observe(duration.Seconds())
}
На основе этих метрик настраиваются алерты, например: "Если p99 latency для запроса X превышает 500ms в течение 5 минут, отправить уведомление"
.