
В какой-то момент практически все коммуникации компании ушли в Битрикс24.
А это и мессенджер, и проекты, и задачи практически на любой чих. Количество пользователей постепенно выросло примерно до 200 человек, из которых около 100 были активными пользователями.
Вместе с этим росло и количество запросов к системе.
Изначально коробка Битрикс24 была развёрнута в облаке одного из хостинг-провайдеров. Процессора и памяти вроде как хватало, но периодически вся система начинала здорово тормозить.
Причём тормозить уже не просто так, чтобы это было неприятно администратору. Пользователи начинали это замечать, а значит, тормоза уже реально мешали рабочим процессам.
Техподдержка провайдера всё валила на сам Битрикс:
У вас тяжёлый Битрикс, смотрите код и оптимизируйте приложение.
В принципе, версия вполне правдоподобная. Битрикс действительно нельзя назвать лёгкой системой.
Но что-то не сходилось.
Начали искать, что именно тормозит
CPU не был постоянно загружен под 100%, свободная память тоже была. При этом в моменты активности пользователей система могла резко становиться очень медленной.
Постепенно подозрение перешло на дисковую подсистему.
Для начала на Linux вообще полезно смотреть не только загрузку процессора, но и iowait:
top
или:
vmstat 1
В vmstat нас в первую очередь интересует колонка:
wa
Это время, которое CPU фактически проводит в ожидании операций ввода-вывода.
Для более подробной картины можно использовать iostat:
sudo dnf install -y sysstat
iostat -xz 1
Особенно интересны:
%util
await
r_await
w_await
aqu-sz
Сам по себе высокий %util ещё не приговор, но если одновременно растут задержки await, очередь запросов и Битрикс начинает вставать — повод смотреть на хранилище уже очень внимательно.
Ещё один полезный инструмент:
iotop
Он позволяет посмотреть, какие процессы в данный момент активно работают с диском.
В случае Битрикса среди кандидатов вполне ожидаемо могут оказаться:
mysqld
php-fpm
и процессы, которые работают с файлами.
Точных исторических графиков и цифр у нас, к сожалению, не сохранилось. Тогда задача была не написать статью и построить красивый тест, а просто понять, почему всё тормозит.
Но после серии проверок стало понятно, что основное узкое место находится именно в дисковой подсистеме виртуального сервера.
При большом количестве обращений к базе задержки резко увеличивались и вместе с ними начинал тормозить весь Битрикс.
Почему виртуальный сервер может тормозить даже при свободных CPU и RAM
У виртуального сервера красивые цифры по процессору и памяти ещё не означают, что в вашем распоряжении такая же хорошая дисковая подсистема.
Условно можно иметь:
CPU — свободен
RAM — свободна
↓
Хранилище — очередь
↓
MySQL ждёт диск
↓
PHP ждёт MySQL
↓
пользователь ждёт страницу
Особенно хорошо это проявляется на системах с большим количеством мелких операций с базой.
Сам Битрикс в этой ситуации может быть вообще ни при чём — он просто достаточно активно пользуется ресурсом, который оказался узким местом.
Конечно, это не означает, что любой тормозящий Битрикс нужно немедленно переносить на железный сервер. Сначала надо проверить PHP, MySQL/MariaDB, кеширование, фоновые задания, агенты и сам код.
Но в нашем случае картина всё больше указывала именно на дисковую подсистему.
Вторая проблема — S3
Отдельно было подключено S3-хранилище для пользовательских файлов.
И оно тоже не отличалось высокой скоростью.
Здесь важно уточнить: проблема не в самом S3 как технологии.
Речь именно о хранилище, которое было доступно у нашего тогдашнего провайдера, и о его работе в нашей конфигурации.
В результате получалось два потенциально медленных участка:
Битрикс
│
├── база данных → дисковая подсистема VM
│
└── файлы → S3
Поэтому вместо дальнейшей борьбы с виртуальной инфраструктурой решили посмотреть, сколько будет стоить обычный выделенный сервер.
Выбираем железный сервер
После недолгих поисков нашли в аренду выделенный сервер у одного из крупных провайдеров:
Intel Xeon E-2236 3.4 ГГц
32 ГБ RAM
2 × 512 ГБ SSD
2 × 4 ТБ HDD
Ничего космического.
Но здесь было важное отличие от виртуалки: сервер полностью наш.
Нет соседней виртуальной машины, которая внезапно решила активно писать на ту же дисковую подсистему. Нет неизвестной нам схемы распределения IOPS внутри облака.
Цена при этом отличалась от виртуального сервера не настолько сильно, чтобы продолжать мириться с периодическими тормозами.
Как разложили данные
Получилась примерно такая схема:
Bitrix24
│
┌─────────┴─────────┐
│ │
2 × 512 GB SSD 2 × 4 TB HDD
│ │
RAID 1 RAID 1
│ │
ОС + Bitrix файлы Bitrix
+ база /upload
SSD оставили под систему, Битрикс и базу данных.
Два HDD по 4 ТБ объединили в RAID 1 и использовали для пользовательских файлов.
Почему RAID 1?
Потому что объём файлов на тот момент составлял около 400 ГБ и эффективных 4 ТБ нам хватало с большим запасом.
При этом отказ одного HDD не означал немедленную потерю файлов.
Но здесь важный момент:
RAID — не backup.
Он спасает от отказа одного диска. Он не спасает от:
- случайного удаления файла;
- повреждения данных;
- ошибки администратора;
- шифровальщика;
- повреждения файловой системы;
- физической потери всего сервера.
Поэтому резервное копирование всё равно понадобилось.
Мини-гайд: RAID 1 под файлы
Если RAID собирается средствами Linux через mdadm, сначала полезно посмотреть, как система видит диски:
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINT
Допустим, два диска под файлы определились как:
/dev/sdb
/dev/sdc
Проверяем ещё раз, что на них нет нужных данных.
После этого RAID 1 можно собрать примерно так:
sudo mdadm --create /dev/md0 \
--level=1 \
--raid-devices=2 \
/dev/sdb /dev/sdc
Состояние синхронизации:
cat /proc/mdstat
Более подробная информация:
sudo mdadm --detail /dev/md0
После создания массива его можно отформатировать, например в XFS:
sudo mkfs.xfs /dev/md0
Создать точку монтирования:
sudo mkdir -p /data/bitrix-upload
и смонтировать:
sudo mount /dev/md0 /data/bitrix-upload
Для постоянного монтирования лучше использовать UUID:
sudo blkid /dev/md0
и добавить его в:
/etc/fstab
Например:
UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /data/bitrix-upload xfs defaults 0 0
Конкретные имена дисков, файловая система и точки монтирования, конечно, зависят от сервера.
Операционная система и окружение
На сервер установили Oracle Linux и стандартное Bitrix Environment.
Само окружение разворачивалось по штатному руководству Битрикс24.
Идея была как раз в том, чтобы здесь не изобретать ничего лишнего.
Если производитель даёт готовое окружение под свою систему, для обычной установки проще сначала использовать его и только потом менять то, для чего действительно есть причина.
После установки обязательно проверить хотя бы базовые вещи:
df -h
free -h
lsblk
и состояние сервисов:
systemctl --failed
Отдельно стоит проверить, что база и web-сервисы действительно находятся на SSD, а не случайно попали на HDD.
Перенос файлов Bitrix на отдельный массив
От S3 решили отказаться и вернуть пользовательские файлы на локальное хранилище.
В Битриксе основная масса загружаемых файлов находится в каталоге upload.
Идея простая:
старый upload
│
▼
/data/bitrix-upload
│
▼
симлинк из каталога сайта
Перед такими операциями Битрикс желательно вывести из активной работы, чтобы пользователи не продолжали загружать файлы во время переноса.
Копирование можно сделать через rsync.
Условный пример:
rsync -aHAX --info=progress2 \
/home/bitrix/www/upload/ \
/data/bitrix-upload/
После копирования проверить объём:
du -sh /home/bitrix/www/upload
du -sh /data/bitrix-upload
После этого старый каталог лучше не удалять сразу, а переименовать:
mv /home/bitrix/www/upload \
/home/bitrix/www/upload.old
и создать симлинк:
ln -s /data/bitrix-upload \
/home/bitrix/www/upload
Проверяем:
ls -ld /home/bitrix/www/upload
После запуска Битрикса обязательно проверить:
- загрузку нового файла;
- открытие существующего файла;
- картинки;
- документы;
- права доступа;
- генерацию превью.
И только когда точно понятно, что всё работает, старую копию можно удалить.
Права на файлы
После переноса нельзя забывать о владельце файлов.
Проверить:
ls -la /home/bitrix/www/
ls -la /data/bitrix-upload/
Владельца нужно выставить таким же, какой используется существующим Bitrix Environment.
Здесь специально не привожу универсальный chown, потому что пользователь и группа могут отличаться в зависимости от конкретной установки.
Лучше сначала посмотреть владельцев исходных файлов и только после этого повторить их на новом хранилище.
Что делать с бэкапами
Переезд на физический сервер добавил очевидный вопрос:
А что будет, если этот сервер завтра просто умрёт?
У выделенного сервера есть минус по сравнению с виртуалкой — нельзя нажать пару кнопок и за минуту увеличить CPU, RAM или перенести виртуальную машину на другой узел.
Физическое железо тоже может выйти из строя.
Поэтому файлы и резервные копии должны находиться не только на самом сервере.
Хотя, если честно, для виртуальной машины правило ровно то же самое.
В итоге резервные копии Битрикса стали храниться в нескольких местах:
Bitrix
│
├── локальная резервная копия
│
├── облако Bitrix24
│
└── собственное внешнее хранилище
Самая тяжёлая часть — пользовательские файлы
База данных и конфигурация занимают относительно немного места.
Главный объём — upload.
У нас это было около:
400 ГБ
Каждый раз копировать все 400 ГБ заново смысла нет.
Поэтому для файлов используется rsync.
Раз в три дня содержимое файлового хранилища синхронизируется с отдельным сервером хранения.
Принцип работы rsync здесь как раз удобный: после первой полной передачи дальше передаются в основном изменения.
Упрощённо:
Bitrix server
/data/bitrix-upload
│
│ rsync
▼
Backup server
/backup/bitrix/upload
Мини-гайд: копирование файлов через rsync
Например, через SSH это может выглядеть так:
rsync -aHAX --info=progress2 \
/data/bitrix-upload/ \
backup@backup-server:/backup/bitrix/upload/
Для автоматической работы обычно используется SSH-ключ.
Создать отдельный ключ:
ssh-keygen -t ed25519
Скопировать публичную часть на backup-сервер:
ssh-copy-id backup@backup-server
После этого проверить:
ssh backup@backup-server
Если авторизация работает без пароля, можно автоматизировать rsync.
Например, через cron:
crontab -e
и запускать раз в три дня.
Саму команду удобнее вынести в отдельный скрипт, чтобы писать лог и отслеживать код возврата.
Пример:
#!/bin/bash
SOURCE="/data/bitrix-upload/"
DEST="backup@backup-server:/backup/bitrix/upload/"
LOG="/var/log/bitrix-upload-backup.log"
rsync -aHAX \
--stats \
"$SOURCE" "$DEST" >> "$LOG" 2>&1
EXIT_CODE=$?
echo "$(date '+%F %T') exit=$EXIT_CODE" >> "$LOG"
exit $EXIT_CODE
После этого уже cron запускает сам скрипт.
Осторожнее с --delete
У rsync есть очень удобный параметр:
--delete
Он удаляет на backup-сервере файлы, которых больше нет в источнике.
Это удобно для зеркала.
И одновременно опасно.
Если пользователь случайно удалил каталог на основном сервере, следующая синхронизация может аккуратно удалить его и из зеркала.
Поэтому обычное зеркало через rsync не заменяет версионный backup.
В нашем случае это нужно учитывать отдельно при построении общей схемы резервного копирования.
Проверяем RAID
Сам RAID тоже желательно периодически контролировать.
Самая простая проверка:
cat /proc/mdstat
Нормальное состояние массива RAID 1 выглядит примерно так:
[UU]
Если вместо двух U одна позиция отсутствует — один из дисков выпал из массива.
Подробно:
mdadm --detail /dev/md0
А состояние самих HDD полезно смотреть через SMART:
sudo smartctl -a /dev/sdb
sudo smartctl -a /dev/sdc
Для физического сервера это уже не факультативная информация.
Если диск начинает умирать, лучше узнать об этом до того, как пользователь сообщит:
Битрикс что-то сегодня странно работает.
Что получилось
В итоге схема стала выглядеть достаточно просто:
INTERNET
│
▼
┌──────────────┐
│ Bitrix24 │
│ Oracle Linux │
└───────┬──────┘
│
┌─────────────┴─────────────┐
│ │
▼ ▼
2 × SSD RAID1 2 × HDD RAID1
│ │
▼ ▼
ОС + Bitrix + DB /upload
│
│ rsync
▼
Backup server
+ локальный backup Bitrix
+ облачный backup Bitrix24
Никакой особой магии.
После переезда общая отзывчивость системы стала заметно лучше, а те самые периодические дикие тормоза, из-за которых всё и начиналось, ушли.
Точных цифр «до» и «после» у нас не сохранилось, поэтому придумывать проценты ускорения не будем.
На тот момент задача была проще:
Битрикс тормозит
↓
ищем причину
↓
находим дисковую подсистему
↓
меняем инфраструктуру
↓
тормоза уходят
Плюсом мы получили понятную схему хранения файлов и резервного копирования, которую уже полностью контролировали сами.
Конечно, выделенный сервер не является универсальным лекарством от проблем Битрикса.
Если приложение упирается в PHP, плохие запросы к базе, кривой модуль или отсутствие кеширования, покупка более быстрого железа просто отодвинет проблему.
Но в нашем случае узким местом оказалось именно хранилище.
И иногда вместо очередной попытки добавить виртуальной машине ещё несколько ядер действительно полезнее посмотреть, чего именно она всё это время ждёт.
- Войдите, чтобы оставлять комментарии