Почему реактивное восстановление дисков устарело
Реактивная схема знакома большинству: диск работает, массив теряет избыточность, администратор меняет накопитель и запускает rebuild. Самая опасная часть здесь - сам rebuild. При заявленной вероятности невосстановимой ошибки чтения 1e-14 чтение 12 ТБ данных даёт примерно 60% шанс встретить хотя бы одну такую ошибку, и в raidz1 без запасного диска деградация превращается в потерю данных.
Диски сообщают о проблемах заранее. Анализ атрибутов SMART в отчётах Backblaze показывает: у накопителей с ненулевым Reallocated_Sector_Ct, Reported_Uncorrect, Current_Pending_Sector и Offline_Uncorrectable вероятность отказа заметно выше средней. Исследование Google по парку более 100 000 дисков дало важное дополнение: больше половины отказов произошли на дисках, о проблемах которых SMART не сигнализировал. Отсюда практический вывод: SMART закрывает часть рисков, но не все.
Второй слой - события уровня пула: ZFS считает контрольные суммы каждого блока, фиксирует ошибки в zpool status и отдаёт их через ZFS Event Daemon (ZED), а регулярный scrub проверяет весь массив целиком. Третий слой - внешний мониторинг на Prometheus, Zabbix или Grafana, который хранит историю и видит парк из сотен дисков. В 2026 году накопители на 24-30 ТБ стали обычной практикой, resilver одного диска занимает от 12 часов до нескольких суток, и цена пропущенного предупреждения выросла вместе с ёмкостью.
Какие атрибуты SMART действительно предсказывают отказ
Атрибуты делятся на три группы: счётчики, которые коррелируют с отказом; косвенные показатели износа механики и электроники; статистика, которая к отказу отношения не имеет. Первые требуют алертов, вторые - наблюдения, третьи - места на дашборде, но не в очереди инцидентов.
Отдельно о том, как читать значения. У каждого атрибута есть нормализованные VALUE и WORST (шкала вендора, обычно отсчёт от 100, порог в поле THRESH) и RAW. Критические счётчики оценивают по RAW: переназначенные и ожидающие сектора измеряются десятками и сотнями, а не нормализованными единицами. Нормализованные значения полезны для износа SSD, где производитель сам задаёт порог.
Критические атрибуты: Reallocated_Sector_Ct, Pending_Sector, Offline_Uncorrectable
| ID | Атрибут | Что означает | Реакция |
|---|---|---|---|
| 5 | Reallocated_Sector_Ct | Сектора, переназначенные из резервной области. Рост значит, что поверхность деградирует. | Любой рост за сутки - warning, больше 10 новых секторов или рост за час - замена |
| 197 | Current_Pending_Sector | Сектора, которые не удалось прочитать. Диск попробует переназначить их при следующей записи. | Больше нуля - critical, подтвердить длинным тестом |
| 198 | Offline_Uncorrectable | Сектора, которые не исправились при офлайн-сканировании поверхности. | Больше нуля - critical |
| 187 | Reported_Uncorrect | Операции, завершившиеся ошибкой, которую диск не смог исправить. | Больше нуля - critical |
Заводское значение Reallocated_Sector_Ct бывает ненулевым: некоторые модели выходят с производства с десятком переназначенных секторов. Ориентироваться стоит на скорость роста, а не на абсолютную цифру. Диск с тремя переназначенными секторами, которые не растут полгода, спокойно отработает ещё годы. Диск, добавивший три сектора за сутки, обычно доживает недели.
Current_Pending_Sector иногда сбрасывается в ноль после записи в проблемный сектор: диск переназначает его, и инцидент закрывается. Если счётчик держится или растёт после длинного теста smartctl -t long, стоит готовить замену. Какие метрики хранилища смотреть вместе с SMART (IOPS, latency, заполнение пула), разобрано в руководстве по мониторингу систем хранения.
Атрибуты, которые часто игнорируют, но они важны
Raw_Read_Error_Rate (ID 1) и Seek_Error_Rate (ID 7) у Seagate отдают огромные RAW-числа, которые не имеют смысла как абсолютная величина, и это сбивает с толку при первом знакомстве. Ценность в другом: резкий скачок значения за сутки говорит о проблемах с головками или позиционированием, и сигналом служит изменение, а не абсолютная цифра.
Spin_Retry_Count (ID 10) считает попытки раскрутить шпиндель. Любое значение больше нуля означает, что механика не запускается с первой попытки, и это один из самых надёжных предвестников отказа HDD.
Command_Timeout (ID 188) фиксирует команды, которые диск не успел выполнить в отведённое время. Причины разные: кабель, контроллер, деградация электроники. Backblaze включает этот атрибут в список значимых для прогноза отказа.
UDMA_CRC_Error_Count (ID 199) описывает ошибки на линии SATA. Диск здесь ни при чём: виноваты кабель, разъём или backplane. Алерт нужен, но замена накопителя проблему не решит.
У SSD картина другая. Wear_Leveling_Count (ID 177 у Samsung, у других вендоров встречается под ID 173 или как Media_Wearout_Indicator) показывает, сколько циклов перезаписи пережили ячейки. Percentage_Used в отчёте NVMe измеряет износ напрямую в процентах от ресурса. Available_Spare и Available_Reservd_Space говорят о запасе резервных блоков: их падение опаснее высокого износа, потому что диск уже расходует подменный фонд.
Статистический шум: какие атрибуты не стоят внимания
Power_On_Hours (ID 9), Power_Cycle_Count (ID 12) и Start_Stop_Count (ID 4) описывают возраст и режим работы. Они полезны в отчётах о парке и бесполезны как триггер: диск с 70 000 часов может работать, а диск с 3 000 часов умирает.
Temperature_Celsius (ID 194) важна как условие эксплуатации: длительная работа выше 50 °C ускоряет деградацию, а скачок до 60 °C указывает на проблемы с охлаждением. Порог алерта держите на 50 °C для HDD и 70 °C для NVMe, но не считайте температуру предиктором отказа. Исключение - NVMe, где перегрев выше 80 °C вызывает троттлинг и реально сокращает ресурс.
Load_Cycle_Count (ID 193) значим для ноутбучных дисков с частной парковкой головок, в сервере с круглосуточной работой он почти не меняется. Вендор-специфичные атрибуты без документации лучше не выводить в алерты: смысл не подтверждён, а шум гарантирован.
ZFS Event Daemon (ZED): настройка и алертинг в TrueNAS
ZED подписывается на очередь событий ядра ZFS через /dev/zfs и превращает их в уведомления, записи в syslog и запуск скриптов. Демон приходит с пакетом zfs-zed, юнит называется zfs-zed. Без него пул продолжит работать, но о деградации вы узнаете из zpool status в момент плановой проверки.
Как включить ZED и настроить уведомления в TrueNAS
- Проверить статус демона: systemctl status zfs-zed, при необходимости включить командой systemctl enable --now zfs-zed.
- В TrueNAS SCALE открыть System, затем Alert Services, и добавить транспорт: email через SMTP, Slack, Telegram или webhook.
- Отредактировать /etc/zfs/zed.d/zed.rc: указать почту администратора, программу отправки и режим подробных уведомлений.
- Ограничить поток событий через ZED_SYSLOG_SUBCLASS_INCLUDE, чтобы в почте не смешивались рутина и инциденты.
- Перезапустить демон: systemctl restart zfs-zed.
- Проверить доставку: запустить zpool scrub на тестовом пуле и убедиться, что уведомление о завершении пришло.
ZED_EMAIL_ADDR="admin@example.com" ZED_EMAIL_PROG="mail" ZED_NOTIFY_VERBOSE=1 ZED_NOTIFY_INTERVAL_SECS=3600 ZED_SYSLOG_SUBCLASS_INCLUDE="checksum|scrub_finish|statechange|pool_import" ZED_USE_ENCLOSURE_LEDS=1
Осторожно с TrueNAS: обновления системы перезаписывают файлы в /etc/zfs/zed.d/, включая zed.rc. Надёжнее держать события ZFS в штатных алертах TrueNAS, а zed.rc использовать для нестандартных задач вроде собственного хука с отправкой в мессенджер. Как связать алерты TrueNAS и Zabbix в один канал с готовыми триггерами, показано в руководстве по Express-уведомлениям в Zabbix для TrueNAS.
Какие события ZED отслеживать в первую очередь
| Событие | Когда возникает | Уровень |
|---|---|---|
| ZEVENT_POOL_DEGRADED, statechange | Пул потерял избыточность: диск выпал, число ошибок превысило лимит | Critical |
| ZEVENT_CHECKSUM | Контрольная сумма блока не совпала при чтении | Critical при повторах |
| ZEVENT_IO_FAILURE | Ошибка ввода-вывода на устройстве | Warning |
| ZEVENT_POOL_RESILVER_FINISH | Восстановление после замены диска завершено | Info, проверять итог |
| ZEVENT_SCRUB_FINISH | Scrub завершён, в отчёте видно число исправленных байт и ошибок | Info при нуле ошибок |
| ZEVENT_POOL_TOO_MANY_ERRORS | Число ошибок на vdev превысило порог | Critical |
ZED_NOTIFY_VERBOSE=0 отключает уведомления о рутине вроде старта scrub, оставляя критичные события. Проверять поток событий вживую удобно командой zpool events -v: она показывает всё, что ядро отдаёт демону, и помогает убедиться, что фильтры не съели важный класс.
Интеграция SMART-метрик в Prometheus и Zabbix
Встроенные уведомления TrueNAS работают, но истории метрик у них нет. Внешняя система даёт графики, динамические пороги и общий вид на парк из сотен дисков, включая узлы, которые не относятся к NAS.
Настройка smartctl_exporter для Prometheus
- Скачать бинарник smartctl_exporter из репозитория prometheus-community и положить его в /usr/local/bin.
- Создать юнит systemd с запуском по адресу :9633, чтобы порт не конфликтовал с node_exporter.
- Добавить target в prometheus.yml: job smart, один таргет на узел хранения.
- Проверить вывод: curl -s localhost:9633/metrics | grep -i reallocated.
/usr/local/bin/smartctl_exporter --smartctl.path=/usr/sbin/smartctl --web.listen-address=:9633
Имена метрик зависят от версии экспортера. В актуальных сборках атрибуты приходят метрикой smartctl_device_attribute с метками device и attribute_name, отдельно отдаются smartctl_device_smart_status, smartctl_device_media_errors, smartctl_device_temperature и smartctl_device_power_on_seconds. Точные названия смотрите в выводе /metrics своей версии: между релизами 0.7 и 0.8 список менялся. Для узлов, где экспортер не подходит, работает связка node_exporter и textfile collector со скриптом smartmon.sh из репозитория node_exporter.
groups:
- name: disks
rules:
- alert: DiskReallocatedSectorsGrowing
expr: increase(smartctl_device_attribute{attribute_name="Reallocated_Sector_Ct"}[24h]) > 0
for: 15m
labels:
severity: warning
annotations:
summary: "Растут переназначенные сектора: {{ $labels.device }} на {{ $labels.instance }}"
- alert: DiskPendingSectors
expr: smartctl_device_attribute{attribute_name="Current_Pending_Sector"} > 0
for: 5m
labels:
severity: critical
- alert: DiskSmartStatusFailed
expr: smartctl_device_smart_status != 1
for: 5m
labels:
severity: critical
NVMe на большинстве систем опрашивается автоматически, но при ручной проверке нужен явный флаг: smartctl -d nvme -a /dev/nvme0n1. Здесь важнее атрибутов HDD медиа-ошибки (media_errors) и Percentage_Used: ненулевые медиа-ошибки на NVMe означают потерю данных внутри устройства, и такой диск меняют без обсуждений.
Шаблоны Zabbix для мониторинга SMART
Zabbix agent 2 с версии 6.0 содержит плагин Smart. В zabbix_agent2.conf достаточно указать путь к smartctl и таймаут:
Plugins.Smart.Path=/usr/sbin/smartctl Plugins.Smart.Timeout=5
Обнаружение дисков идёт через ключ smart.disk.discovery, данные снимаются ключом smart.disk.get[/dev/sda]. Шаблон SMART by Zabbix agent 2 из поставки строит зависимые элементы из JSON и содержит триггеры на статус SMART, медиа-ошибки и переназначенные сектора. Агенту нужен доступ к /dev/sd*, иначе smartctl вернёт пустой ответ: запускайте agent 2 от root или настройте sudo для конкретной команды.
Для старых схем остаётся UserParameter, но парсинг лучше вынести в отдельный скрипт: символ доллара внутри ключа конфликтует с подстановкой параметров Zabbix, и awk-поля в конфиге агента превращаются в источник ошибок.
UserParameter=smart.attr[*],/usr/local/bin/smart-attr.sh "$1" "$2"
Скрипт smart-attr.sh запускает smartctl -A для указанного устройства и печатает RAW-значение нужного атрибута. Триггер на десять переназначенных секторов выглядит так:
last(/TrueNAS by Zabbix agent 2/smart.disk.get[/dev/sda,"reallocated_sector_count"])>10
Ключи элементов отличаются между версиями шаблона, поэтому сверяйте выражение с тем, что реально создаётся после импорта. Полная инструкция по UserParameter и алертам на критические атрибуты собрана в руководстве по мониторингу SMART в Zabbix, а про LLD-обнаружение и кастомные триггеры для парка дисков - в материале от стандартных шаблонов до кастомных триггеров.
Как отличить деградацию массива от единичной ошибки чтения
ZFS считает контрольные суммы, поэтому одна ошибка чтения на диске с избыточностью данных не теряет: пул восстанавливает блок из копии или с чётности и записывает исправленное значение. Вопрос в том, разовая это помеха или начало отказа.
Чтение вывода zpool status: на что смотреть
pool: tank
state: DEGRADED
status: One or more devices has experienced an unrecoverable error.
Applications are unaffected.
action: Determine if the device needs to be replaced.
scan: scrub repaired 0B in 06:12:44 with 0 errors on Sun Sep 6 03:45:11 2026
config:
NAME STATE READ WRITE CKSUM
tank DEGRADED 0 0 4
raidz2-0 DEGRADED 0 0 8
sda ONLINE 0 0 0
sdb ONLINE 0 0 0
sdc DEGRADED 0 0 8 too many errors
sdd ONLINE 0 0 0
errors: No known data errors
Колонки READ, WRITE и CKSUM показывают число ошибок с момента импорта пула. Рост CKSUM на одном устройстве указывает на этот накопитель или его путь подключения. Одинаковые ошибки на нескольких дисках одного контроллера, backplane или полки чаще говорят об инфраструктуре: кабель, HBA, питание, перегрев.
Строка errors: No known data errors значит, что непоправимых повреждений нет и избыточность сработала. Если ZFS пишет Permanent errors have been detected с путями к файлам, часть данных утрачена: там, где копий и чётности не хватило. Отдельно про zpool clear: команда обнуляет счётчики ошибок, поэтому перед её запуском сохраните вывод zpool status -v в тикет или заметку, иначе история исчезнет и разбираться будет не с чем.
Когда запускать scrub и как интерпретировать результаты
TrueNAS по умолчанию запускает scrub раз в месяц через таймер zfs-scrub. Для пулов с критичными данными разумно раз в одну-две недели: scrub читает все блоки, сверяет контрольные суммы и исправляет найденные повреждения, если избыточность позволяет. Полный scrub 8-дискового raidz2 на 100 ТБ идёт от нескольких часов до двух суток, интенсивность ограничена параметром zfs_scrub_min_time_ms (по умолчанию 1000 мс работы на транзакционную группу).
Читать результат просто. Строка scrub repaired 0B с нулём ошибок означает, что всё в порядке. Запись scrub repaired 15.5M with 12 errors означает, что повреждённые блоки исправлены: ошибки были, избыточность скрыла их от приложений. Дальше важен повтор: если тот же диск снова собирает ошибки при следующем scrub, его меняют. Если ошибки разовые и после zpool clear не возвращаются, ограничиваются наблюдением.
- Зафиксировать вывод zpool status -v до любых действий.
- Запустить zpool scrub и дождаться завершения.
- Сравнить счётчики CKSUM по устройствам до и после.
- Повтор ошибок на том же диске - планировать замену накопителя.
- Ошибки на нескольких дисках одного тракта - проверять кабели, HBA, питание.
- Ошибки не повторяются - zpool clear и наблюдение с алертом на новые события.
Перед заменой прогоните длинный SMART-тест по всем дискам vdev. Resilver читает весь массив целиком, и скрытые проблемы соседних накопителей всплывают именно в этот момент, когда избыточность уже ослаблена.
Пороги алертинга: как избежать ложных тревог и пропусков
Порог, который срабатывает всегда, бесполезен; порог, который молчит на реальной деградации, опасен. Рабочий принцип такой: критические счётчики дают мгновенный critical при выходе из нуля; медленные деградации отслеживаются по скорости изменения; метрики окружения срабатывают по абсолютному порогу.
| Метрика | Warning | Critical | Логика |
|---|---|---|---|
| Reallocated_Sector_Ct (RAW) | любой рост за 24 ч | рост за 1 ч или больше 10 новых секторов | for: 15m, оценка через increase() |
| Current_Pending_Sector | - | больше 0 | for: 5m, подтверждение длинным тестом |
| Offline_Uncorrectable | - | больше 0 | for: 5m |
| Reported_Uncorrect | - | больше 0 | for: 5m |
| Command_Timeout, UDMA_CRC_Error_Count | рост за 6 ч | - | проверить кабель и контроллер |
| Spin_Retry_Count | - | больше 0 | планировать замену HDD |
| SSD: Percentage_Used, Wear_Leveling_Count | больше 80% | больше 90% или Available_Spare ниже 10% | for: 1h |
| ZFS checksum errors на vdev | любые новые | рост за 1 ч или больше 10 за сутки на одном устройстве | grouping по пулу |
| Состояние пула | - | не ONLINE (DEGRADED, FAULTED, UNAVAIL) | for: 1m |
| Заполнение пула | больше 80% | больше 90% | у ZFS влияет и на производительность |
Пороги зависят от класса дисков: consumer SATA и enterprise SAS ведут себя по-разному, а NVMe живёт по метрикам media_errors и percentage_used, где любые ненулевые медиа-ошибки требуют внимания. Динамические пороги надёжнее статических для шумных атрибутов: сравните значение с базовой линией за 7-14 дней и алертите на выход за коридор.
Alertmanager спасает от потопа через group_by и inhibition: алерт о деградации пула подавляет алерты по отдельным дискам этого пула, а окно обслуживания на время scrub не пускает уведомления. Каждый алерт должен иметь действие из runbook. Правило без действия - кандидат на удаление, потому что оно только тренирует привычку игнорировать письма.
Автоматизация реакции на инциденты
ZED запускает скрипты из /etc/zfs/zed.d/, и имя файла определяет класс событий: checksum-notify.sh реагирует на ошибки контрольных сумм, statechange-notify.sh на смену состояния vdev. Собственный хук называется по той же схеме, например statechange-telegram.sh, и получает переменные ZEVENT_POOL, ZEVENT_VDEV_PATH и ZEVENT_VDEV_STATE.
#!/bin/sh [ "$ZEVENT_VDEV_STATE" = "DEGRADED" ] || exit 0 curl -s -X POST "https://api.telegram.org/bot$TOKEN/sendMessage" \ -d chat_id="$CHAT" \ -d text="Пул $ZEVENT_POOL деградировал: $ZEVENT_VDEV_PATH"
Хук делают исполняемым через chmod +x и проверяют, что демон запускает его от root. Готовые сценарии уведомлений в Telegram и email для smartd, Zabbix и Grafana собраны в руководстве по автоматическому мониторингу дисков.
Дальше подключается Alertmanager: webhook создаёт инцидент в Jira или PagerDuty, отдельный receiver отправляет сообщение в дежурный чат. При наличии hot spare ZFS подставит его автоматически при отказе диска, а для замены в тот же слот включают autoreplace командой zpool set autoreplace=on для нужного пула. Проверку состояния и замену удобно описывать в Ansible-плейбуке: собрать zpool status -j, найти vdev в состоянии DEGRADED, выполнить zpool replace и дождаться завершения resilver по тому же JSON.
Автоматическую замену диска тестируют на стенде: ошибка в плейбуке на боевом пуле обойдётся дороже ручной операции. Если выгрузки zpool events и логи контроллеров слишком велики для ручного разбора, их можно суммаризировать через LLM: агрегатор вроде AiTunnel даёт доступ к моделям GPT, Gemini и Claude через единый интерфейс с оплатой в рублях и без VPN, что удобно для быстрого анализа длинных логов инцидентов.
Сравнение подходов: встроенные средства TrueNAS vs внешние системы
| Критерий | TrueNAS | Prometheus и Grafana | Zabbix |
|---|---|---|---|
| Время запуска | минуты | день на экспортеры и правила | день при готовых шаблонах |
| История метрик | ограничена | полная, с retention | полная |
| Парк из разных систем | только этот NAS | любые узлы и ОС | любые узлы и ОС |
| Гибкость порогов | фиксированные уровни | PromQL и динамические пороги | триггеры, зависимости, эскалации |
| Что нужно развернуть | ничего | сервер и хранилище метрик | сервер и базу данных |
Для домашней лаборатории и одного NAS хватает встроенных алертов TrueNAS и ZED с email-уведомлениями. Для парка от десятка узлов и требований к отчётности выбирают внешнюю систему: Prometheus с Alertmanager даёт гибкие правила и динамические пороги, Zabbix удобнее там, где нужны эскалации, дежурства и единая база хостов.
Комбинированная схема работает лучше крайностей: ZED отвечает за события ZFS и мгновенные реакции, Prometheus или Zabbix собирают SMART и метрики производительности, Grafana показывает состояние парка на одном экране. Для самого стека мониторинга подойдёт отдельный VPS: Timeweb Cloud предоставляет облачные серверы, хранилище и Kubernetes, поэтому Prometheus с 30-дневным retention и Grafana размещаются без привязки к боевому железу и не конкурируют с нагрузкой хранилища.
Чек-лист: как выстроить проактивный мониторинг
- Проверить, что SMART включён на всех дисках: smartctl -i /dev/sdX и признак SMART support: Enabled.
- Настроить регулярные тесты: короткий ежедневно, длинный раз в неделю, отдельно для HDD, SATA SSD и NVMe.
- Собрать базовую линию атрибутов за первые две недели, чтобы пороги опирались на факт, а не на догадку.
- Включить ZED или штатные алерты TrueNAS и проверить доставку тестовым scrub.
- Развернуть экспортер SMART и подключить его к Prometheus или импортировать шаблон в Zabbix.
- Задать пороги по таблице выше, разделив severity на warning и critical.
- Собрать дашборд: состояние пулов, рост переназначенных секторов, температура, checksum errors.
- Провести учения: имитировать ошибку чтения на тестовом пуле и убедиться, что алерт дошёл до дежурного.
- Описать runbook: кому идёт алерт, кто принимает решение о замене, где лежит запасной диск.
- Пересматривать пороги после крупных обновлений прошивок и системы: базовая линия меняется.
Проверка алертов после обновлений обязательна. Правки в zed.rc, смена имени метрики в экспортере или новые ключи шаблона Zabbix ломают доставку тихо, и о поломке узнают в момент аварии. Прогоните тестовое событие после каждого апгрейда и держите рядом с мониторингом один запасной диск с той же моделью и прошивкой.