• Добро пожаловать на сайт - wlux.net!

    FAQ по форуму

    1. Все сообщения до группы местный проходят модерацию от 1 минуты до 24 часа

    2. Сообщения учитываються в следующих разделах: Читать

    3.Что-бы скачать вложение нужно 2 сообщения.

    4.Личные переписки работают только с Администрацией форума

    5. Запрещено: Просить скрытый текст , спам, реклама, скам, ддос, кардинг и другая чернуха, нарушать любые законы РФ/СНГ = бан аккаунта

    6. Внимание! Мы не удаляем аккаунты с форума! Будьте внимательны ДО регистрации! Как удалить аккаунт на форуме?!

    5.Не понимаю, как и что тут работает у вас?!Как создавать темы, писать сообщения, как получать реакции. Почему не засчитывает сообщения. Все ответы здесь

This is a mobile optimized page that loads fast, if you want to load the real page, click this text.

Гайд ZFS+zrepl как "механизм резервного копирования" форума

Оффлайн

wlux.net

Где волчьи уши, там волчьи зубы.
Команда форума
LV
7
 
20.06.2022
23 868
218
36
Награды
10
Пол
Муж.

Репутация:

  • Автор темы
  • Администратор
  • Модератор
  • Команда форума
  • #1
Совместимость с XenForo: 2.0 - 2.1 - 2.2

DISCLAIMER раз
: Эта инструкция должна быть обратно совместима и с XenForo 1.x, т.к. фактически здесь рассматривается и настраивается файловая система, которая работает на уровне операционной системы. Но, как говорится, я не проверял.
DISCLAIMER два: Наличием этой статьи я Вас ни к чему не призываю. Просто рассказываю свой опыт, какие плюсы лично я получил от внедрения ZFS на место ext4 и старого механизма резервного копирования (о нём тоже кратко напишу), и какие минусы.
DISCLAIMER три: С момента внедрения прошло около полугода. И хотя я для себя старался документировать всё, что мною делалось, и при написании ресурса сверялся несколько раз с мануалами, которыми пользовался, вполне мог что-то упустить. Всегда обкатывайте новые, неведомые технологии, на виртуалках, и лишь потом тащите в прод!
DISCLAIMER четыре: Хоть это и пошаговый мануал с описанием своего опыта от результата внедрения, я могу не всегда приводить полный листинг команд, которые выполнялись. Этим самым, я подстраховываюсь от того, что бы Вы просто пошли и бездумно делали всё то, что я тут понаписал. Но, если что, в обсуждении я готов поотвечать на вопросы, и, возможно даже, поделиться командами.

Что копировали, и как копировали?​

Раньше (до мая 2023 г.), мой форум располагался на сервере "типового сетапа": Ubuntu 20.04 (актуальная на момент установки ОС) утилизировала два SSD-диска по 240Гб. Диски были объединены в обычный программный рейд (mdadm) 1-го уровня ("зеркало"). Так же, в этом же сервере был установлен жёсткий диск на 2Тб, который был смонтирован как /datastore. Форум сам никак не взаимодействовал с ним, но с ним взаимодействовали скрипты резервного копирования: именно в /datastore сохранялись дампы БД, снимаемые mysqldump, а так же рсинкались файлы. Рсинкнутые туда файлы впоследствии сохранялись на AWS S3 через s3cmd. Всё это происходило каждое утро, в 5 часов.
То есть, фактически, мы имеем неограниченное (условно) кол-во резервных копий базы данных, и всегда лишь последнюю резервную копию файлов. Если потеряется какое-то вложение (по каким-то причинам), а мы заметим поздно, то достать его уже будет буквально невозможно.
Хранить несколько копий одних и тех же файлов кажется дорогим удовольствием, потому решено было посмотреть в сторону файловых систем, которые умеют в точки восстановления (в дальнейшем, просто "снапшоты").

Средняя нагрузка на сервер:

Используем дешёвый дедик на Хецнере. Думаю все видели такие. Но суть в том, что у нас там был (и остаётся) большой запас по ресурсам.



В среднем, на базу данных генерируется по 60-80 запросов в секунду, а nginx пропускает через себя 15-20 HTTP-запросов (так же в секунду).
На графике выше видна аномалия, когда на nginx прилетало больше 1000 запросов в секунду, но Zabbix за тот момент времени это "заагрегировал", и вывел как ~300. Это был DDoS (и нас ими пошатывает), но опять же, nginx сам отбился, как смог, и не нагрузил базу.

Я не хвастаюсь, и не нужно мне устраивать стресс-тест. DDoS для меня это всегда стресс. Он почти всегда начинается, когда я не дома. Бесит.

Кажется, будто у нас есть большой запас по ресурсам.

Кандидаты?​

Когда речь заходит о "снапшотах", вспоминают, как правило, о BTRFS. Мы её тоже рассматривали, и тестировали. Но, исходя из обсуждений в Интернетах, BTRFS не очень хорошо работает с рейдами. Проверять это как-либо не хотелось, особенно на проде, а собирать тестовый стенд в домашних условиях - сильно лениво. Ру-хостинги естественно не дадут мне какой-нибудь очень дешёвый сервер с двумя дисками (ибо RAID1), а в Зарубежье настолько запариваться не хотелось, как мы сейчас паримся с оплатой продовой машины.
Какие ещё файловые системы есть? И тут на сцену выходит ZFS.

Ещё есть LVM, но в LVM снапшоты - это совсем другое.

ZFS (Zettabyte FileSystem) - это файловая система, разработанная Sun Microsystems изначально для Solaris. Помимо функциональности файловой системы, ZFS так же реализует "менеджер томов" (аля LVM), который позволяет объединять диски для создания тех же рейдов. Это называется zpool.
Хоть это файловая система для совершенно другой ОС (хоть и Unix-подобной), силами энтузиастов ZFS был портирован для Linux, и им можно пользоваться и тут.
У ZFS есть три основных понятия: pool, vdev и dataset.
  • vdev - virtual device, которым может являться не один, а два и больше диска.

    Пожалуйста, войдите или зерегистрируйтесь, чтобы увидеть скрытый текст.

    .
  • pool - набор из одного и более vdev, образующий сам "сторадж" для данных.
  • dataset - собственно, сама логическая единица файловой системы, куда и пишутся "пользовательские данные".


У ZFS есть важные нюансы, которые нужно учитывать (перед использованием):
  • ZFS очень привередлива к ОЗУ. Некачественная плашка памяти может привести к повреждению данных при записи на диск. Перед установкой, проведите тестирование своей системы. В частности, качество установленной ОЗУ. Она не должна выдавать ошибок во время мемтестов вообще.
  • ZFS работает по CoW-принципу (Copy-on-Write). Данные при перезаписи, вместо того, чтобы просто перезаписаться на диске, копируются в уже изменённом виде, а после просто обновляется ссылка на сектора диска в метаданных. Это привносит как плюсы в надёжность, так и минусы. Но так же, появляется очень важный нюанс: нельзя заполнять весь пул на 100%. Чтобы обезопасить себя от такой ошибки, можно создать датасет с резервированием только под него какого-то дискового объёма. Главное - не забивать весь пул!
    Сам не проверял, но по информации от одного человека с работы, если забить весь пул на 100%, то файловая система переходит в режим "только чтение", из которого её якобы никак не вывести. Потому важно следить за дисковым пространством.
  • Объём пула ZFS можно увеличивать, но нельзя уменьшать. Это вам не ext4, которую можно как уменьшать, так и увеличивать.
  • Всевозможные кэши ZFS могут жрать и процессор, и ОЗУ. Их нужно крутить.

    Пожалуйста, войдите или зерегистрируйтесь, чтобы увидеть скрытый текст.

    .

Как внедряем?​

Ввести в эксплуатацию ZFS на уже работающем сервере - очень проблематично, особенно если всё дисковое пространство уже выделено под разделы. Как делал лично я:
  1. Запланировал работы на 2-3 дня (с запасом). Не хотелось всё делать в одну ночь.
  2. Арендовал VDS-сервер на хостинге с объёмом диска, который бы смог уместить на себе форум, с небольшим запасом. ЦПУ и ОЗУ взял по минимуму. ОС установил той же версии, что была и на исходном сервере (Ubuntu 20.04).
    В этом плане удобно пользоваться хостингами с почасовой оплатой, вроде

    Пожалуйста, войдите или зерегистрируйтесь, чтобы увидеть скрытый текст.

    или

    Пожалуйста, войдите или зерегистрируйтесь, чтобы увидеть скрытый текст.

    .
  3. Перенёс одну из резервных копий форума, чисто на тесты конфигурации.
  4. Как только на временном сервере всё было готово, запланировал отключение на ~15 минут.
  5. Выключил MySQL и nginx, рсинкнул актуальные файлы. Папку с базами целиком рсинкал.
  6. Запустил всё обратно.
  7. Выключил Enhanced Search, т.к. Эластик не переносился.
После того, как форум перенёс, прокликал мышкой всё, и ушёл спать.


На следующий день:
  1. Обновил ОС на сервере до Ubuntu 22.04.
  2. Удалил все файлы форума, чтобы освободить диск. Так же почистил немного корень.
  3. Переразметил диски таким образом, чтобы корневой раздел был только 30Гб.
  4. Hetzner ещё зачем-то сажает своп в рейд, и наш "сетап" был таким же, так что ещё избавился от этого, сделав просто два раздела со свопом на дисках, но поменьше.
  5. Оставшееся свободное дисковое пространство выделил в разделы, которые потом были скормлены как "диски" для ZFS Pool.
  6. Создал четыре датасета (zfs create poolname/datasetname):
    • Резерв на 10Гб
    • Файлы форума
    • MySQL (он требует индивидуальной настройки)
    • Docker
    Датасеты фактически делят доступное пространство пула между собой, но то, что принадлежит резерву, не доступно никому. И сам этот датасет никуда не смонтирован, потому эти 10Гб просто "потерялись", чтобы пул не смог забиться.
  7. Смонтировал каждый датасет в свою папку.
Итого, имеем:
Код:
# zfs get mountpoint forum/{web,database,docker}
NAME            PROPERTY    VALUE            SOURCE
forum/database  mountpoint  /var/lib/mysql   local
forum/docker    mountpoint  /var/lib/docker  local
forum/web       mountpoint  /var/www/forum   local

MySQL​


И это, на самом деле, не просто прикол, который я решил вставить. MySQL коробочно с ZFS и правда не очень дружит, и будет тормозить.
Дело в том, что MySQL реализует в себе функционал, который так же реализуется и в ZFS, из-за чего одна и та же работа для надёжности хранения данных, проводится этими двумя братьями-акробатами, а выполнять её должен только кто-то один.
Ещё, MySQL рассчитывает на определенные размеры блоков в файловой системе при своей работе, и ZFS в реальности дефолтно использует блоки бОльшего размера, чем ожидает MySQL.

Это не MySQL такой плохой, просто сами DBMS пишут так. И с Постгресом тоже нельзя вот так просто взять, и... Ну, вы поняли.

У OpenZFS (проект по воссозданию файловой системы для FreeBSD и Linux) на эту тему есть отдельная статья по тюнингу, и они

Пожалуйста, войдите или зерегистрируйтесь, чтобы увидеть скрытый текст.

, что нужно покрутить в настройках датасета и самого MySQL, чтобы получить +- схожую с extX производительность.
Percona относительно недавно, кстати, проводили тестирование ZFS в лоб с ext4, можете полюбоваться на его результаты

Пожалуйста, войдите или зерегистрируйтесь, чтобы увидеть скрытый текст.

.

Docker​

В Docker у меня крутится Elasticsearch и ещё пара сервисов для работы форума, например

Пожалуйста, войдите или зерегистрируйтесь, чтобы увидеть скрытый текст.

. Потому Докер, чтобы спать спокойнее (и корень не забивался), я тоже решил унести в ZFS.
Вообще, у Docker есть поддержка ZFS, и он даже иначе с ним работает, но нельзя вот так просто взять, скопировать все файлы из extX раздела в ZFS и надеяться, что оно заработает. Даже если предварительно остановить все контейнеры, сам Докер и рантайм контейнеров (runc / containerd).
В общем, втупую и его перенести не получилось, пришлось руками дёргать всё из старой папки, но благо контейнеров немного, а образы скачать снова - не страшно, всё равно все версии в используемых docker-compose зафиксированы.


Запускаем форум обратно​

Перед полноценным внедрением zrepl, хотелось оценить, насколько изменится нагрузка на процессор (и не только) от замены файловой системы. Предварительно я оценил работоспособность MySQL путём настройки репликации продовской базы на виртуалку на домашний комп, и в целом был доволен результатами тестов, но хотелось понять, что будет именно в проде.
Потому первые пару месяцев форум работал на ZFS со старой схемой резервного копирования.

Что там по нагрузке ZFS?

Ну, вообще, всё очень хорошо. Я и графики вам принёс... Без карты нападения, правда, ведь во время этих двух месяцев снова случился DDoS, но шатать уже пытались дольше, и сильнее.



Буквально пару дней шатали. Не отпускали. В результате этих шатаний даже создали проблему, над которой я сидел и "тупил" неделю. Процессор нагружен был на 20% как раз из-за неё.

Что за проблема ?

Размер корня уменьшился с 220Гб до 30Гб, и, даже не смотря на вынос всех тяжёлых данных на ZFS, не был рассчитан на хранение больших объёмов данных. А логи nginx пишутся как раз туда...
В общем, у DDoS-еров успешно удалось забить корень диска, и создать вместе с этим две проблемы:
  1. Redis. Это один из тех сервисов, которые крутились вне Докера, которые "персистентно" хранили что-то на диске (буквально пару метров), и который я забыл унести в ZFS. О сервисе, который реально жрёт копеечные ресурсы, поди ещё вспомни. А он с забитой ФС сдох, и повлёк за собой проблемы, ведь дополнение на стороне форума не ожидает мёртвого Redis.
  2. Crowdsec. Это решение, наподобие Fail2ban, которым я пользуюсь для блокировки "злоумышленников", которые сильно шатают по HTTP форум. Оно парсит access и error-логи nginx, и на основании некоторых "триггеров", помечает IP-адрес как "заблокированный", а специальная служба ходит на CloudFlare и блокирует его там.
    В чём случилась с ним проблема? Описать конкретно - сложно, но из-за забившегося диска, в какой-то момент он начал утилизировать на 100% одно из ядер процессора (те самые аномальные 20%, которые долго держались в нагрузке). Чистка лога не помогла, он просто "забился" в цикл сисколлов, и что-то делал. Очень долгое время было непонятно, что, но перезапускать тогда не решился (зря).
В ходе изучения и этой проблемы, Redis был унесён так же в ZFS, а логи nginx были перенесены на жёсткий диск 2Тб. Пускай его забивает. Логов немного, пропускной способности HDD должно быть более чем достаточно.

zrepl​

zrepl (ZFS replication) - простое решение для реализации репликации файловой системы ZFS. Настроить его можно буквально за 10 минут. Расписывать фичи не буду, разве что упомяну, что ZFS вообще умеет в шифрование данных, а zrepl умеет реплицировать шифрованные данные без необходимости расшифровывать их на принимающей стороне (но и внутрь файловой системы заглянуть не получится). Этого более чем достаточно, если нужно просто копировать данные на сервер, который принадлежит кому-то другому, а у Вас чувствительные данные лежат там, или Вы просто не хотите, чтобы туда заглядывал кто-то посторонний.
В общем, конфигурация очень простая:

Код:
global:
  logging:
    - type: syslog
      format: human
      level: warn

jobs:
    # Название задачи на репликацию. Может быть любым.
    # В документации говорится, что его нельзя менять. На деле,
    # скорее всего, можно, но только не посередине репликации.
  - name: "general_push"
    # Способ репликации. Может быть как push (настраивается на отдающей),
    # так и pull (настраивается на принимающей).
    type: push
    connect: {
      # Как подключаться, и куда? 172.30.250.250 - адрес сервера-стораджа (VPN), а
      # 8888 - порт zrepl.
      type: tcp,
      address: "172.30.250.250:8888"
    }
    send:
      # Шифрование отключаю, чтобы принимающая сторона могла читать ФС. Мне это надо.
      encrypted: false
    # Какие датасеты реплицируем?
    filesystems: {
      "forum/database": true,
      "forum/web": true
    }
    # По какой логике создаются снапшоты?
    snapshotting:
      type: cron
      cron: "0 3 * * *"
      prefix: zrepl_
      timestamp_format: dense
      hooks:
      - type: mysql-lock-tables
        # Чтобы MySQL "безопасно" заснапшотился, нужно залочить все
        # таблицы на время создания снапшота. Операция быстрая, но может
        # привести к проблемам на это время.
        dsn: "root:password@unix(/run/mysqld/mysqld.sock)/"
        filesystems: {
          "forum/database": true
        }
    pruning:
      # Автоудаление снапшотов. В моей настройке, на
      # отдающей стороне хранится только один нереплицированный снапшот, а на
      # принимающей - 90 снапшотов (90 бэкапов).
      keep_sender:
      - type: not_replicated
      - type: last_n
        count: 1
      keep_receiver:
      - type: last_n
        count: 90

А стоила ли эта игра - свеч?​

Я считаю, что да. Судите сами.
На полное резервное копирование по старой схеме уходило ~5 минут, из которых 30 секунд MySQL был "вынужден" висеть, ведь mysqldump лочит базу для "консистентности" дампа. То есть форум "кастовался" в "read only" состояние.

У zrepl есть cli, с помощью которого можно смотреть процесс выполнения задач на репликацию:



Как вы могли заметить, на резервное копирование небольшого, скромного форума, уходит 14 секунд, из которых снапшот создаётся меньше чем за секунду (а ведь с этого момента резервную копию можно считать уже сделанной, просто хранящейся только локально). При этом, по сети передаётся примерно 500 мебибайт данных.
Форум в целом занимает 60Гб:

Код:
# zfs list forum/{database,web}
NAME             USED  AVAIL     REFER  MOUNTPOINT
forum/database  9.67G  73.1G     9.53G  /var/lib/mysql
forum/web       49.4G  73.1G     49.3G  /var/www/forum

За всё то время, что форум работает на ZFS (это уже почти полгода), пул ни разу не развалился, и прекрасно себя чувствует, разве что подвергся небольшой фрагментации:

Код:
root in ~ λ zpool list
NAME    SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT
forum   189G  80.0G   109G        -         -    49%    42%  1.00x    ONLINE  -
root in ~ λ zpool status forum
  pool: forum
 state: ONLINE
  scan: scrub repaired 0B in 00:03:24 with 0 errors on Sun Oct  8 00:27:25 2023
config:

        NAME                                                  STATE     READ WRITE CKSUM
        forum                                                 ONLINE       0     0     0
          mirror-0                                            ONLINE       0     0     0
            ata-INTEL_SSDSC2CW240A3_CVCV207202V1240CGN-part4  ONLINE       0     0     0
            ata-INTEL_SSDSC2CW240A3_CVCV331104S6240FGN-part4  ONLINE       0     0     0

errors: No known data errors

По месту тоже произошёл настоящий win: чтобы хранить ежедневные резервные копии базы данных за 3 месяца в виде дампов + по одной копии за каждый прошедший месяц каждого года, уходит 48Гб. Каждая копия сжата gzip.

А что там на ZFS+zrepl (хоть хранятся и не дампы, а бинарные файлы баз MySQL, из которых дамп тоже несложно получить)?
Код:
root in ~ λ zpool list
NAME          SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT
storagepool  3.58T   100G  3.48T        -         -     0%     2%  1.00x    ONLINE  -
root in ~ λ zpool status storagepool
  pool: storagepool
 state: ONLINE
  scan: scrub repaired 0B in 00:29:41 with 0 errors on Sun Oct  8 00:53:42 2023
config:

        NAME                                                STATE     READ WRITE CKSUM
        storagepool                                         ONLINE       0     0     0
          mirror-0                                          ONLINE       0     0     0
            ata-WDC_WD40EFRX-68N32N0_WD-WCC7K2XVK081-part3  ONLINE       0     0     0
            ata-WDC_WD40EFRX-68WT0N0_WD-WCC4E3HKS16R-part3  ONLINE       0     0     0

errors: No known data errors
root in ~ λ zfs list storagepool/zrepl/server/forum/database
NAME                                      USED  AVAIL     REFER  MOUNTPOINT
storagepool/zrepl/server/forum/database  44.3G  3.37T     9.44G  none
root in ~ λ zfs get compression storagepool/zrepl/server/forum/database
NAME                                     PROPERTY     VALUE           SOURCE
storagepool/zrepl/server/forum/database  compression  off             default

Чтобы хранить несжатые двоичные файлы MySQL за 90 дней, уходит чуть меньше места, чем на сжатые дампы. Если их пережать, то можно получить выигрыш. Но вот какой - уже не подскажу, для меня этот вопрос не принципиален. Самое главное - на хранение полных (буквально) файловых резервных копий за 90 дней уходит 56Гб, ведь за счёт снапшотов и CoW, ZFS хранит только отличающиеся куски изменённых файлов, умело их накладывая в ходе своей работы. А ещё мы храним даже удалённые файлы, и можем восстанавливать их без проблем.


Итог?​

ZFS+zrepl как "архитектурное решение для резервного копирования" может помочь не только с резервным копированием (внезапно), но и с дисковым пространством. Как самого сервера, так и стораджа. ZFS умеет "сжимать данные". Главное настроить это до того, как в датасете появятся данные, ведь при изменении параметров, ZFS уже существующие данные в датасете не "перезаписывает" с учётом изменений: файлы не сжимаются, размеры блоков не уменьшаются, и так далее...
ZFS привнёс в моём случае несколько плюсов:
  • Любые удалённые пользователями вложения теперь можно восстанавливать. Даже если пользователь удалил в тот же день, что и залил, ведь движок удаляет вложение с диска только через сутки после заливки.
  • Получилось позволить себе хранить много резервных копий. Экспериментально настраивалось 90 дней, но в контексте того, как мало жрут копии, и в контексте объёмов дисков, можно увеличить вплоть до 5 лет.
  • Особо отличий от extX по производительности не было замечено.
Минусы? Они тоже есть.
  • Помните, я говорил, что ZFS чувствительна к дисковому пространству? Эта проблема никуда не уходит даже с резервом, хотя и намного смягчается (ФС не уйдёт в "только чтение", как минимум).
    Масла в огонь подливает тот самый CoW: на сервере, который таким образом "копируется", всегда есть один снапшот, который может бесконечно раздуваться в зависимости от того, сколько данных пишется. Может дойти до абсурда, что снапшот займёт х2 от самих данных, если они бесконечно удаляются и создаются заново.

  • Под софт может понадобиться "персонально" настраивать датасет ZFS, чтобы он работал лучше или не хуже, чем на extX. Keep in mind. Не стесняйтесь гуглить и экспериментировать, в Интернете скорее всего на все виды нагрузок уже есть "готовые рецепты". Какие-то из них, например, перечислены в документации OpenZFS (я на неё ссылаюсь в разделе про MySQL).
  • zrepl не умеет в хуки на стороне "стораджа" (принимающего сервера). А хотелось бы кастовать те же бинарные файлы БД сразу в дампы (не по запросу). Тут пока думаю над новой архитектурой, которая бы утилизировала zrepl без кардинальных изменений, и при этом давала нужный мне функционал.
Кстати, о графиках:

К счастью, с тех пор живём без DDoS-атак, и наконец-то графики нормальные!



RPS с полноценного внедрения немного просел, но тут скорее сказываются события последних полутора лет потихоньку. Выход Counter-Strike 2, например, и отсутствие до сих пор для него какой-то вменяемой платформы для плагинов, за что собственно и держится HLmod. Есть ещё некоторые события, но их бы обсуждать тут не хотелось.


В ходе написания статьи (и экспериментов с ZFS), я черпал своё вдохновение с нескольких источников:
 

Поиск по форуму

Похожие темы:

Данный сайт использует cookie. Вы должны принять их для продолжения использования. Узнать больше....