Мониторинг и обслуживание системы хранения изображений: метрики, алерты и регламентные работы | AdminWiki

Мониторинг и обслуживание системы хранения изображений: метрики, алерты и регламентные работы

12 сентября 2026 14 мин. чтения

Почему свободного места в мониторинге недостаточно

Хранилище на 50 ТБ с 40 млн изображений может неделю отдавать картинки за 8 мс, а потом за 200 мс при том же объёме данных и 30% свободного места. Причина в очереди на одном узле, разросшемся индексе метаданных или SSD, который начал перевыделять сектора. График занятости диска в такой ситуации выглядит ровным, и дежурный узнаёт о проблеме от пользователей.

Хранилище изображений отличается от обычной файловой шары тремя свойствами. Миллионы мелких объектов, миниатюры по 20-150 КБ и оригиналы по 1-5 МБ, поэтому нагрузка ложится на метаданные и количество операций, а не на объём. Высокая чувствительность к задержке чтения: изображение участвует в отрисовке страницы, и лишние 100 мс видны в метриках фронтенда. Деградация накопителя проявляется постепенно, через рост latency и ошибок, задолго до полного отказа.

Прямой ответ на вопрос «что мониторить»: latency отдачи и записи (p50, p95, p99 отдельно для GET и PUT), throughput в МБ/с, IOPS и средний размер блока, заполнение в байтах и в inode, ошибки бэкенда (5xx, таймауты, ошибки целостности), состояние дисков через SMART, трафик репликации и ребалансировки. К этому набору добавляются алерты с продуманными порогами и регламентные работы: scrub, балансировка, обновление версий.

Экономика проста. Если p95 отдачи выросло с 120 до 180 мс, страница каталога с 30 изображениями добавляет почти 2 секунды к загрузке. При SLA p95 меньше 200 мс запас остаётся небольшим, и следующий пик трафика выводит сервис за границу. Подробный разбор метрик накопителей, SMART-атрибутов и состояния пулов собран в материале про мониторинг систем хранения: ключевые метрики и инструменты для администратора.

Отдельный источник нагрузки, о котором часто забывают: генерация изображений. Если хранилище наполняется не только загрузками пользователей, но и работой моделей, доступ к ним удобно держать через единый шлюз, например через агрегатор API AiTunnel, а на стороне хранилища измерять всплески записи и рост числа объектов по префиксам.

Ключевые метрики системы хранения изображений и их интерпретация

Latency, throughput и IOPS: как связаны и на что влияют

Latency это время от одной операции. Throughput это объём данных за секунду. IOPS это число операций за секунду. Связь между ними задаёт закон Литтла: при фиксированной глубине очереди рост IOPS упирается в потолок, и дальше растёт только задержка. Хранилище, которое держит 10 000 IOPS при latency 10 мс, после роста нагрузки до 15 000 IOPS отдаёт уже 50 мс, потому что очередь выросла, а не потому что диски стали медленнее.

Для изображений важно разделять операции чтения и записи. PUT миниатюры размером 40 КБ и GET оригинала на 4 МБ нагружают разные подсистемы. Мелкие объекты упираются в IOPS и метаданные, крупные в пропускную способность сети и диска. Средний размер блока в iostat или node_exporter показывает, какая из двух проблем у вас: 4-8 КБ означает давление на IOPS, 128 КБ и выше означает давление на полосу.

Смотрите на перцентили, а не на среднее. Среднее по выборке из миллионов запросов скрывает хвост, а именно хвост портит пользовательский опыт. p50 показывает типичный запрос, p95 ловит деградацию под нагрузкой, p99 вскрывает редкие, но дорогие случаи: попадание в холодный кэш, чтение с ремонтируемого OSD, ожидание блокировки метаданных.

МетрикаЧто показываетОриентир для картинокПорог алерта
Latency p95Отдача объекта под обычной нагрузкойменее 200 мсболее 300 мс в течение 10 минут
Latency p99Хвост запросов, холодный кэшменее 500 мсболее 500 мс в течение 10 минут
ThroughputПропускная способность чтения и записи60-70% от полки каналаустойчиво выше 90%
IOPSЧисло операций, нагрузка на метаданныедо 70% от измеренного максимумаустойчиво выше 85%
ЗаполнениеЗанятое место и inodeдо 80%warning 85%, critical 90%
Ошибки S3 API5xx, отказы, таймаутыменее 0,1% запросоврост на 10% за 5 минут

Нормы зависят от железа. На NVMe-пулах реальны p99 в 20-30 мс, на SATA-массивах с шардированием те же 200 мс уже хороший результат. Снимайте baseline на своём стенде под целевой нагрузкой и сравнивайте текущие значения с ним, а не с чужой таблицей.

Заполнение дисков и ошибки бэкенда: пороги и тренды

Порог 80% удобен как точка внимания для локальных ФС и объектных шлюзов. В Ceph граница жёстче: при заполнении пула выше 70-75% кластер начинает ребалансировать размещение, растёт recovery-трафик, и latency чтения картинок подскакивает вместе с ним. Поэтому для Ceph имеет смысл ставить warning на 70%, critical на 80%, и держать отдельный алерт на полный nearfull кластера.

Inode не менее важны, чем байты. Каталог с десятками миллионов миниатюр в одной директории съедает inode быстрее, чем место, а ext4 по умолчанию создаёт один inode примерно на 16 КБ, что для мелких изображений даёт неожиданно жёсткий лимит. Проверяйте node_filesystem_files_free наравне с node_filesystem_avail_bytes, а раскладку объектов по префиксам проектируйте заранее: хеш от ключа или дата в первых символах пути разгружает метаданные и ускоряет листинг.

Ошибки бэкенда делятся на три группы. Транспортные: таймауты, обрывы соединений, недоступность узла. Прикладные: 5xx от S3 API, отказ записи из-за нехватки места. Ошибки целостности: несовпадение контрольных сумм, повреждённые объекты, ошибки чтения с диска. Третья группа самая опасная, потому что не влияет на доступность, но означает потерю данных. В ZFS это ошибки checksum в zpool status, в Ceph ошибки deep scrub и значение ceph_health_status выше OK.

Тренд полезнее текущего значения. Функция predict_linear в Prometheus по шестичасовому окну показывает, когда закончится место: predict_linear(node_filesystem_avail_bytes[6h], 7*24*3600) меньше нуля означает заполнение за неделю при текущем темпе. Такой алерт даёт время договориться о закупке дисков или почистить старые производные изображения, а не разбираться с инцидентом в три часа ночи.

Настройка Prometheus и Grafana для MinIO, Ceph и TrueNAS

Схема одна для всех трёх систем: экспортер отдаёт метрики по HTTP, Prometheus собирает их по расписанию, Grafana рисует дашборды, Alertmanager рассылает уведомления. Разница в источнике данных. MinIO отдаёт метрики сам, Ceph публикует их через mgr-модуль, TrueNAS требует поставить node_exporter и smartctl_exporter в jail или на сам хост. Конфигурации ниже проверялись на Prometheus 3.x, Grafana 11.x, node_exporter 1.8, smartctl_exporter 0.13, MinIO RELEASE.2025, Ceph 19.2 Squid и TrueNAS SCALE 25.04. Перед переносом в продакшен сверьте имена метрик и флаги с версией, которая стоит у вас.

Если стек мониторинга удобнее держать вне своего железа,Prometheus с Grafana и Alertmanager поднимаются на облачных серверах или в managed Kubernetes, например в Timeweb Cloud. Тогда хранилище остаётся на месте, а сбор и хранение метрик живут отдельно и переживают падение площадки.

MinIO: экспортер, scrape-конфиг и дашборд

Встроенный endpoint включается одной командой: mc admin prometheus generate myminio выдаёт JWT и готовый блок scrape-конфига. Метрики кластера доступны по пути /minio/v2/metrics/cluster, метрики узла по /minio/v2/metrics/node, бакета по /minio/v2/metrics/bucket. Токен лучше положить в файл, а не в командную строку Prometheus.

scrape_configs:
  - job_name: minio-cluster
    metrics_path: /minio/v2/metrics/cluster
    scheme: http
    bearer_token_file: /etc/prometheus/minio-token
    static_configs:
      - targets: ['minio-1:9000', 'minio-2:9000', 'minio-3:9000']
  - job_name: minio-bucket
    metrics_path: /minio/v2/metrics/bucket
    bearer_token_file: /etc/prometheus/minio-token
    static_configs:
      - targets: ['minio-1:9000']

Ключевые метрики для дашборда: minio_cluster_capacity_usable_free_bytes и minio_cluster_usage_total_bytes для заполнения, minio_bucket_usage_total_bytes для разбивки по бакетам, minio_s3_requests_total и minio_s3_errors_total для нагрузки и ошибок, minio_node_disk_used_bytes и minio_node_disk_free_bytes для состояния дисков, minio_cluster_nodes_offline_total для доступности узлов. Гистограмма времени до первого байта minio_s3_requests_ttfb_seconds_distribution даёт перцентили latency через histogram_quantile.

Готовый дашборд MinIO Dashboard импортируется по ID 13502, для детального разбора дисков подойдёт Node Exporter Full с ID 1860. Обе панели требуют правки под свои job-имена.

Ceph: мониторинг кластера через Prometheus

Модуль prometheus входит в состав Ceph и включается командой ceph mgr module enable prometheus. По умолчанию он слушает порт 9283 и отдаёт метрики на /metrics, дополнительно можно поднять на всех mgr-узлах. Альтернатива для старых кластеров, ceph_exporter от DigitalOcean, требует доступа к сокету и отдельного сервиса.

scrape_configs:
  - job_name: ceph
    metrics_path: /metrics
    static_configs:
      - targets: ['ceph-mgr-1:9283', 'ceph-mgr-2:9283']
    relabel_configs:
      - source_labels: [__address__]
        regex: '([^:]+):(\d+)'
        target_label: instance
        replacement: '$1'

Смотрите на ceph_health_status (0 означает HEALTH_OK), ceph_osd_up для упавших OSD, ceph_pool_used_bytes и ceph_pool_max_avail для заполнения пулов, ceph_pool_percent_used для порогов nearfull, ceph_osd_apply_latency_ms и ceph_osd_commit_latency_ms для задержек операций, ceph_pg_degraded и ceph_pg_undersized для состояния размещения, ceph_cluster_total_recovering_bytes_per_sec для трафика восстановления. Рост recovery-трафика объясняет всплеск latency без внешней нагрузки, и это нормальное поведение, а не инцидент.

Дашборд Ceph Cluster импортируется по ID 2842. Расширенный набор панелей для кластерной инфраструктуры, включая Ceph и Pacemaker, разобран в статье про мониторинг кластеров серверов с Prometheus и Grafana.

TrueNAS: мониторинг дисков и ZFS через node_exporter и smartctl_exporter

TrueNAS SCALE не отдаёт метрики ZFS и SMART из коробки в формате Prometheus. Практичный путь: создать jail или виртуальную машину, поставить туда node_exporter с включённым коллектором zfs и smartctl_exporter, дать им доступ к /dev и к команде smartctl, а затем добавить job в Prometheus.

scrape_configs:
  - job_name: truenas-node
    static_configs:
      - targets: ['truenas:9100']
  - job_name: truenas-smart
    static_configs:
      - targets: ['truenas:9633']

Полезные метрики: node_zfs_zpool_state (значение 0 для ONLINE), node_zfs_zpool_used_bytes и node_zfs_zpool_free_bytes, node_disk_io_time_seconds_total и node_disk_read_bytes_total для нагрузки на диски, node_filesystem_avail_bytes и node_filesystem_files_free для места и inode. От smartctl_exporter нужны smartctl_device_smart_status, smartctl_device_attribute_raw_value с attribute_id 5 и 197 (перевыделенные и ожидающие сектора), smartctl_device_temperature. Показатель температуры дисков выше 50 градусов в стойке с плохой продувкой объясняет скачки latency лучше, чем очередь запросов.

Для TrueNAS удобны общий дашборд Node Exporter Full (ID 1860) и дашборды SMART-атрибутов (например, Smartctl Exporter, ID 19841), дополненные самодельной панелью по состоянию пулов.

Алерты на деградацию дисков и критическое заполнение

Алерт полезен, если по нему есть действие. Уведомление «диск заполнен» в момент, когда запись уже упала, бесполезно, а правило «заполнение выше 85% в течение 10 минут» даёт часы на реакцию. Для каждого правила фиксируйте порог, длительность (for), уровень важности и текст с указанием узла и метрики. Группировку и маршрутизацию держите в Alertmanager, а сами условия в Prometheus.

Правила алертов для деградации дисков

Основу дают SMART-правила и проверка состояния кластера. Дополнительно полезно ловить не только смену статуса, но и медленное накопление дефектов, потому что диск с растущим числом перевыделенных секторов продолжает работать месяцами и деградирует по скорости.

groups:
  - name: storage-images-disks
    rules:
      - alert: SmartStatusFailed
        expr: smartctl_device_smart_status != 1
        for: 5m
        labels:
          severity: critical
          team: storage
        annotations:
          summary: "SMART-статус диска не PASSED"
          description: "{{ $labels.instance }} диск {{ $labels.device }}"

      - alert: SmartReallocatedGrowing
        expr: increase(smartctl_device_attribute_raw_value{attribute_id="5"}[24h]) > 0
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "Растёт число перевыделенных секторов"

      - alert: CephOsdDown
        expr: ceph_osd_up == 0
        for: 2m
        labels:
          severity: critical
        annotations:
          summary: "OSD {{ $labels.ceph_daemon }} недоступен"

      - alert: CephOsdApplyLatencyHigh
        expr: ceph_osd_apply_latency_ms > 100
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "Задержка применения операций на OSD выше 100 мс"

Для RAID-массивов на TrueNAS и Linux отдельно следите за состоянием через метрики mdstat или node_md_disks: деградация зеркала до одного диска означает нулевой запас по отказоустойчивости. Порог ceph_osd_apply_latency_ms в 100 мс исторически считается признаком проблемного OSD, но на NVMe-кластерах его стоит опустить до 10-20 мс, ориентируясь на свой baseline.

Алерты на критическое заполнение и ошибки бэкенда

Правила заполнения делайте двухуровневыми, а прогноз выносите в отдельный алерт. Он срабатывает раньше остальных и обычно превращает инцидент в плановую задачу.

      - alert: DiskFillWarning
        expr: (1 - node_filesystem_avail_bytes{fstype!~"tmpfs|overlay|squashfs"} /
              node_filesystem_size_bytes{fstype!~"tmpfs|overlay|squashfs"}) * 100 > 85
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "Раздел {{ $labels.mountpoint }} заполнен более чем на 85%"

      - alert: DiskFillCritical
        expr: (1 - node_filesystem_avail_bytes{fstype!~"tmpfs|overlay|squashfs"} /
              node_filesystem_size_bytes{fstype!~"tmpfs|overlay|squashfs"}) * 100 > 90
        for: 5m
        labels:
          severity: critical

      - alert: InodesAlmostExhausted
        expr: (1 - node_filesystem_files_free / node_filesystem_files) * 100 > 85
        for: 15m
        labels:
          severity: warning
        annotations:
          summary: "Свободных inode меньше 15%"

      - alert: DiskWillFillIn7Days
        expr: predict_linear(node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"}[6h], 7*24*3600) < 0
        for: 1h
        labels:
          severity: warning
        annotations:
          summary: "При текущем темпе раздел заполнится за неделю"

      - alert: MinioS3ErrorsGrowing
        expr: sum by (bucket) (rate(minio_s3_errors_total[5m])) > 1
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Рост ошибок S3 API в бакете {{ $labels.bucket }}"

      - alert: MinioTtfbP99High
        expr: histogram_quantile(0.99, sum by (le) (rate(minio_s3_requests_ttfb_seconds_distribution_bucket[5m]))) > 0.5
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "p99 отдачи объектов выше 500 мс"

      - alert: CephPoolNearFull
        expr: ceph_pool_percent_used > 80
        for: 15m
        labels:
          severity: critical

Чтобы правила не спамили, используйте group_by по кластеру и типу проблемы, repeat_interval не меньше 4 часов для warning и 30 минут для critical, а также inhibition: пока активен алерт о недоступности узла, правила по его дискам и latency молчат. Каналы уведомлений подбирайте по скорости реакции: Telegram или Slack для critical, email или тикет для warning. Ошибки целостности, которые приходят из zpool status и deep scrub, стоит отправлять в тот же канал, что и отказ диска, даже если сервис продолжает работать.

Регламентное обслуживание: scrub, балансировка и обновление версий

Регулярные работы предотвращают сбои не хуже алертов, но требуют окна обслуживания и плана отката. Ниже периодичность, проверенная на практике для хранилищ изображений среднего размера, и команды для каждой системы.

Scrub и проверка целостности данных

Scrub читает все блоки, сверяет контрольные суммы и восстанавливает повреждённые данные из избыточности. В ZFS это zpool scrub tank, статус смотрится командой zpool status -v, ошибки показываются в секции errors. В Ceph обычный scrub запускается автоматически, а deep scrub раз в неделю проверяет контрольные суммы объектов: ceph osd deep-scrub osd.5 для конкретного OSD и ceph osd scrub all для запуска вручную.

Scrub конкурирует за дисковый ввод-вывод. На массиве из 12 дисков полный проход ZFS по 40 ТБ занимает от нескольких часов до суток, и всё это время latency отдачи картинок растёт. Планируйте задачу через cron на ночь или выходные, ограничивайте скорость: в ZFS параметр zfs_scrub_delay добавляет паузы между блоками, в Ceph параметры osd_scrub_begin_hour и osd_scrub_end_hour задают окно, а osd_scrub_load_threshold не даёт запускать scrub при высокой нагрузке. Для Ceph разумный ритм: deep scrub раз в неделю в ночном окне, для ZFS: scrub раз в месяц, а также после замены диска или сбоя питания.

Балансировка и обновление версий

Дисбаланс в Ceph возникает после добавления или замены OSD: одни диски заполнены под 90%, другие под 60%. Команда ceph osd reweight-by-utilization 110 корректирует вес OSD с отклонением от среднего и запускает перемещение данных. На время ребалансировки полезно выставить ceph osd set norebalance, если нужно сначала освободить ресурсы под пиковую нагрузку, и снять флаг в окне. Помните, что миграция данных сама создаёт нагрузку на сеть и диски, поэтому выполнять её в час пик не стоит.

Обновление версий проходит по-разному. MinIO обновляется командой mc admin update, при этом rolling-рестарт узлов в кластере идёт по одному и сервис остаётся доступен. Ceph обновляется управляемо через ceph orch upgrade start --image, который переводит демонов по одному и позволяет остановиться на любом шаге при появлении ошибок. TrueNAS обновляется через веб-интерфейс с возможностью откатить системный датасет, но перед обновлением проверяйте примечания к версии: смена схемы ZFS или поведения плагинов иногда требует ручных шагов.

Чек-лист перед любым обновлением: свежий бэкап конфигураций и данных, проверенный на восстановление; тестовый стенд с той же версией, на котором прогнано обновление; окно обслуживания с уведомлением пользователей; известный способ отката; мониторинг latency и ошибок, включённый до старта работ. Автоматизировать снапшоты и проверку восстановления помогают готовые скрипты, разобранные в статье про автоматизацию резервного копирования и восстановления.

Примеры дашбордов и готовые конфигурации

Набор, который закрывает задачи мониторинга хранилища изображений без написания панелей с нуля: MinIO Dashboard (ID 13502), Ceph Cluster (ID 2842), Node Exporter Full (ID 1860) для узлов и ZFS, Smartctl Exporter (ID 19841) для атрибутов дисков, а также дашборд Alertmanager Overview (ID 9578) для контроля самих уведомлений. Публичные дашборды рассчитаны на стандартные имена метрик, поэтому после импорта проверьте, что панели не пустые, и поправьте фильтры instance и job.

Минимальный JSON-фрагмент панели для латентности, который можно вставить в дашборд через Import JSON и адаптировать под свои метрики:

{
  "type": "timeseries",
  "title": "MinIO TTFB p95 / p99",
  "datasource": "Prometheus",
  "targets": [
    {
      "expr": "histogram_quantile(0.95, sum by (le) (rate(minio_s3_requests_ttfb_seconds_distribution_bucket[5m])))",
      "legendFormat": "p95"
    },
    {
      "expr": "histogram_quantile(0.99, sum by (le) (rate(minio_s3_requests_ttfb_seconds_distribution_bucket[5m])))",
      "legendFormat": "p99"
    }
  ],
  "fieldConfig": {
    "defaults": { "unit": "s" }
  }
}

Конфигурацию Alertmanager для дежурной смены удобно строить на маршрутах: critical уходит в голосовой канал илиTelegram, warning в тикет-систему, а правила по дискам одного узла собираются в одно уведомление через group_by: ['alertname', 'instance']. Отдельно проверьте, что алерты доходят: создайте тестовое правило с искусственным условием и убедитесь, что уведомление пришло за ожидаемое время.

Похожий подход применим и в медицинских хранилищах, где важна не только доступность, но и целостность самих файлов: разбор контроля DICOM-изображений и алертов по потере данных собран в статье про мониторинг PACS-серверов.

Как выстроить систему мониторинга, которая предотвращает сбои

Порядок запуска выглядит так. Сначала выпишите критичные метрики и снимите baseline на целевом профиле нагрузки: latency чтения и записи по перцентилям, IOPS, throughput, заполнение в байтах и inode, ошибки API. Затем поднимите сбор: endpoint MinIO, mgr-модуль Ceph, node_exporter и smartctl_exporter на TrueNAS, и убедитесь, что метрики приходят без пропусков. После этого импортируйте дашборды и правьте их под свои job-имена, чтобы дежурный видел картину за 10 секунд. Следующий шаг: правила алертов с порогами, длительностью и понятными текстами, плюс маршрутизация в Alertmanager. И последний: регламент работ с расписанием scrub, окнами для балансировки и процедурой обновления с проверкой на стенде.

Мониторинг не заканчивается запуском. Раз в квартал пересматривайте пороги: после перехода на NVMe алерт по latency в 500 мс перестаёт быть полезным, а после роста числа изображений прежний порог заполнения может срабатывать слишком поздно. Раз в месяц проверяйте, что каждый активный алерт кто-то действительно обработал, и удаляйте правила, которые только шумят. Если разбираетесь с уже случившейся деградацией, начните с поиска узкого места по метрикам, а не с закупки железа: методика разбора описана в материале про поиск узкого места в системе.

Поделиться:
Сохранить гайд? В закладки браузера