Проектирование отказоустойчивых систем хранения данных: от ZFS до распределенных СУБД | AdminWiki

Проектирование отказоустойчивых систем хранения данных: от ZFS до распределенных СУБД

17 августа 2026 8 мин. чтения

Введение: зачем нужна отказоустойчивость хранения данных

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

В статье разберем четыре уровня защиты. Локальная избыточность на уровне RAID защищает от выхода из строя отдельных дисков. Файловые системы ZFS и Btrfs добавляют контрольные суммы и самовосстановление данных. Репликация master-slave и multi-master обеспечивает высокую доступность на уровне сервисов. Распределенные СУБД вроде CockroachDB дают глобальную отказоустойчивость с горизонтальным масштабированием.

Каждый раздел содержит пошаговые команды и конфигурации, проверенные на практике. В конце статьи - таблица критериев выбора технологии под конкретный сценарий.

Основы отказоустойчивости: RAID и его уровни

RAID (Redundant Array of Independent Disks) объединяет несколько физических дисков в один логический массив. Цель - избыточность данных или производительность. Основные уровни:

  • RAID 0 - чередование без избыточности. Увеличивает скорость, но отказ любого диска уничтожает все данные. Для отказоустойчивости не подходит.
  • RAID 1 - зеркалирование. Данные дублируются на два диска. Переживает отказ одного диска. Полезная емкость - 50%.
  • RAID 5 - чередование с распределенной четностью. Переживает отказ одного диска. Минимум три диска. Полезная емкость - N-1.
  • RAID 6 - как RAID 5, но с двумя блоками четности. Переживает отказ двух дисков. Минимум четыре диска.
  • RAID 10 - зеркалирование поверх чередования. Высокая производительность и отказоустойчивость. Переживает отказ одного диска в каждой зеркальной паре. Полезная емкость - 50%.

Для серверов баз данных с интенсивной записью выбирают RAID 10. Для файловых хранилищ с большим объемом - RAID 6. RAID 5 допустим для небольших массивов из 3-4 дисков, где риск второго отказа во время восстановления минимален.

Программный RAID в Linux: настройка mdadm

Программный RAID в Linux реализуется через утилиту mdadm. Он не требует аппаратного контроллера и работает на любом сервере. Настройка RAID 1 из двух дисков /dev/sdb и /dev/sdc:

# Установка mdadm
apt install mdadm -y

# Создание массива RAID 1
mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sdb /dev/sdc

# Проверка статуса
cat /proc/mdstat

# Создание файловой системы
mkfs.ext4 /dev/md0

# Добавление в fstab для автомонтирования
echo '/dev/md0 /mnt/storage ext4 defaults 0 2' >> /etc/fstab

# Сохранение конфигурации массива
mdadm --detail --scan >> /etc/mdadm/mdadm.conf
update-initramfs -u

Перед созданием массива убедитесь, что на дисках нет данных. Команда mdadm --create перезаписывает метаданные и уничтожает существующую информацию. Замена отказавшего диска выполняется так:

# Пометить диск как отказавший
mdadm --manage /dev/md0 --fail /dev/sdb

# Удалить из массива
mdadm --manage /dev/md0 --remove /dev/sdb

# Добавить новый диск
mdadm --manage /dev/md0 --add /dev/sdd

Подробный разбор программных RAID-массивов с командами для RAID 5, 6 и 10 есть в руководстве по mdadm, ZFS и LVM.

Файловые системы нового поколения: ZFS и Btrfs

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

ZFS - зрелая файловая система, разработанная Sun Microsystems. Она объединяет функции файловой системы и менеджера томов. Пул хранения (zpool) состоит из виртуальных устройств (vdev), каждое из которых может быть зеркалом, RAID-Z или отдельным диском. Снапшоты в ZFS почти мгновенны и занимают место только при изменении данных.

Btrfs - встроенная в Linux файловая система с аналогичными возможностями. Она поддерживает подтома, снапшоты, сжатие и встроенный RAID. Btrfs проще в настройке, но для критически важных продакшен-систем ZFS остается более предсказуемым выбором.

ZFS: создание пула и настройка репликации снапшотов

Создание зеркального пула из двух дисков:

# Установка ZFS
apt install zfsutils-linux -y

# Создание зеркального пула
zpool create tank mirror /dev/sdb /dev/sdc

# Создание файловой системы с включенным сжатием
zfs create tank/data
zfs set compression=lz4 tank/data

# Проверка статуса пула
zpool status

Репликация снапшотов позволяет переносить данные на другой сервер или в резервное хранилище:

# Создание снапшота
zfs snapshot tank/data@backup-2026-08-17

# Отправка снапшота на удаленный сервер
zfs send tank/data@backup-2026-08-17 | ssh backup-server zfs receive backup-pool/data

# Инкрементальная отправка следующего снапшота
zfs send -i tank/data@backup-2026-08-17 tank/data@backup-2026-08-18 | ssh backup-server zfs receive backup-pool/data

Связка ZFS с инструментами резервного копирования рассмотрена в практическом руководстве по резервному копированию сервера.

Btrfs: работа с подтомами и RAID

Btrfs позволяет создавать RAID средствами самой файловой системы без mdadm:

# Создание RAID1 из двух дисков
mkfs.btrfs -d raid1 -m raid1 /dev/sdb /dev/sdc

# Монтирование
mount /dev/sdb /mnt/storage

# Создание подтома
btrfs subvolume create /mnt/storage/data

# Создание снапшота
btrfs subvolume snapshot /mnt/storage/data /mnt/storage/snapshots/data-2026-08-17

# Проверка целостности данных
btrfs scrub start /mnt/storage

# Просмотр статуса scrub
btrfs scrub status /mnt/storage

Scrub - важная процедура. Она читает все данные, сверяет контрольные суммы и исправляет ошибки при наличии избыточности. Запускайте scrub еженедельно через cron для раннего обнаружения деградации дисков.

Репликация данных: master-slave и multi-master

RAID и ZFS решают проблему отказа оборудования. Репликация решает проблему отказа сервера целиком. Данные копируются на другой узел, который может принять нагрузку при сбое основного.

Master-slave репликация предполагает один узел для записи (master) и один или несколько узлов для чтения (slave). Запись всегда идет на master, изменения асинхронно или синхронно передаются на slave. Преимущество - простота и предсказуемость. Недостаток - единая точка отказа на запись. При падении master нужен механизм переключения.

Multi-master позволяет писать на любой узел. Это устраняет единую точку отказа и распределяет нагрузку. Недостаток - конфликты при одновременной записи одного и того же ключа на разных узлах. Решение конфликтов требует либо разрешения на уровне приложения, либо использования CRDT и векторных часов.

Выбор между подходами зависит от требований к доступности записи. Если приложение может пережить короткую паузу при переключении - master-slave достаточно. Если запись должна работать всегда - нужен multi-master.

Настройка master-slave репликации PostgreSQL

Потоковая репликация PostgreSQL передает WAL-записи с master на slave. Настройка master-узла в postgresql.conf:

listen_addresses = '*'
wal_level = replica
max_wal_senders = 10
wal_keep_size = 1GB
hot_standby = on

Создание репликационной роли:

CREATE ROLE replicator WITH REPLICATION LOGIN PASSWORD 'secure_password';

Добавление правила в pg_hba.conf:

host replication replicator 192.168.1.0/24 md5

Клонирование данных на slave:

pg_basebackup -h master-host -U replicator -D /var/lib/postgresql/16/main -P -R

После запуска slave проверьте состояние репликации на master:

SELECT client_addr, state, sync_state FROM pg_stat_replication;

Детальная настройка кластеров PostgreSQL и MySQL с автоматическим переключением разобрана в руководстве по отказоустойчивой архитектуре ИС.

Patroni: автоматическое переключение и высокая доступность PostgreSQL

Patroni - это шаблон высокой доступности для PostgreSQL. Он управляет кластером из нескольких узлов, автоматически выбирает master и выполняет failover при отказе. Patroni использует распределенное хранилище конфигурации (etcd, Consul или ZooKeeper) для координации узлов.

Пример конфигурации patroni.yml:

scope: postgres-cluster
namespace: /db/
name: node1

restapi:
  listen: 0.0.0.0:8008
  connect_address: 192.168.1.10:8008

etcd:
  host: 192.168.1.10:2379

bootstrap:
  dcs:
    ttl: 30
    loop_wait: 10
    retry_timeout: 10
    maximum_lag_on_failover: 1048576
  initdb:
    - encoding: UTF8
    - data-checksums

postgresql:
  listen: 0.0.0.0:5432
  connect_address: 192.168.1.10:5432
  data_dir: /var/lib/postgresql/16/main
  bin_dir: /usr/lib/postgresql/16/bin
  pgpass: /tmp/pgpass
  authentication:
    replication:
      username: replicator
      password: secure_password
    superuser:
      username: postgres
      password: postgres_password
  parameters:
    wal_level: replica
    hot_standby: on
    max_wal_senders: 10

При отказе master Patroni автоматически повышает один из slave до master и перенаправляет трафик. Время переключения обычно составляет 10-30 секунд. Для приложений это означает короткую паузу, но не потерю данных при синхронной репликации.

Распределенные СУБД: CockroachDB и другие

Распределенные СУБД изначально проектируются для работы на множестве узлов без единой точки отказа. CockroachDB - это SQL-база данных, совместимая с PostgreSQL-протоколом. Она автоматически реплицирует данные на несколько узлов и использует консенсус Raft для согласования состояния.

Каждая строка в CockroachDB хранится в нескольких репликах (по умолчанию три). Запись подтверждается только после согласования большинства реплик. При отказе узла система автоматически перераспределяет данные на оставшиеся узлы. Это устраняет необходимость в ручном failover и дает непрерывную доступность записи.

CockroachDB подходит для сценариев, где требуется горизонтальное масштабирование и глобальная отказоустойчивость. Цена - более высокая задержка записи по сравнению с одиночным PostgreSQL из-за сетевых раундов для консенсуса.

Развертывание CockroachDB: пошаговое руководство

Установка и запуск первого узла:

# Скачивание и установка
curl https://binaries.cockroachdb.com/cockroach-v24.1.0.linux-amd64.tgz | tar -xz
cp cockroach-v24.1.0.linux-amd64/cockroach /usr/local/bin/

# Запуск первого узла
cockroach start --insecure --store=node1 --listen-addr=192.168.1.10:26257 --http-addr=192.168.1.10:8080 --join=192.168.1.10:26257,192.168.1.11:26257,192.168.1.12:26257 --background

Запуск второго и третьего узлов выполняется аналогично на соответствующих серверах. Инициализация кластера:

cockroach init --insecure --host=192.168.1.10:26257

Проверка состояния:

cockroach node status --insecure --host=192.168.1.10:26257

Создание базы данных и таблицы:

cockroach sql --insecure --host=192.168.1.10:26257

CREATE DATABASE app;
USE app;
CREATE TABLE users (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    email STRING UNIQUE,
    created_at TIMESTAMP DEFAULT now()
);
INSERT INTO users (email) VALUES ('admin@example.com');

Для продакшен-развертывания обязательно настройте TLS-сертификаты. Флаг --insecure допустим только для тестирования.

Критерии выбора технологии хранения

Выбор технологии зависит от требований проекта. Сравнительная таблица:

КритерийRAID (mdadm)ZFS / BtrfsPatroni + PostgreSQLCockroachDB
Защита от отказа дискаДаДаДа (через RAID/ZFS)Да
Защита от повреждения данныхНетДа (контрольные суммы)НетДа
Защита от отказа сервераНетНет (только репликация снапшотов)Да (автоматический failover)Да
Горизонтальное масштабирование записиНетНетНетДа
Сложность администрированияНизкаяСредняяСредняяВысокая
Задержка записиМинимальнаяМинимальнаяНизкаяСредняя
СтоимостьНизкаяНизкаяСредняяВысокая

Рекомендации по сценариям:

  • Одиночный сервер, файловое хранилище - RAID 10 или RAID 6 + ZFS. Достаточно для NAS и файловых серверов.
  • Одиночный сервер, база данных - RAID 10 + ZFS + PostgreSQL. Защита от отказа диска и повреждения данных.
  • Кластер из 2-3 узлов, высокая доступность - Patroni + PostgreSQL. Автоматический failover за 10-30 секунд.
  • Мультирегиональное развертывание, непрерывная запись - CockroachDB. Горизонтальное масштабирование и отсутствие единой точки отказа.

Сравнение объектного, блочного и файлового хранилищ для выбора базовой архитектуры приведено в отдельном руководстве.

Заключение: итоговые рекомендации

Отказоустойчивость хранения данных строится послойно. Начните с RAID для защиты от отказа дисков. Добавьте ZFS или Btrfs для контроля целостности данных. Внедрите репликацию PostgreSQL с Patroni для высокой доступности. Если проект требует горизонтального масштабирования и непрерывной записи - рассмотрите CockroachDB.

Не пытайтесь внедрить все сразу. Оцените реальные риски: какой простой допустим, какие данные критичны, какой бюджет доступен. Для большинства проектов связка RAID 10 + ZFS + Patroni закрывает 95% сценариев отказов. Распределенные СУБД нужны там, где простой записи недопустим в принципе.

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

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