Какие метрики вы используете для оценки производительности базы данных и почему?

Ответ

Для комплексной оценки производительности БД я отслеживаю несколько ключевых групп метрик.

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 минут, отправить уведомление".