Резкий скачок использования диска во время резервного копирования, Discourse упал :-(

Сегодня утром около 5:35 мои форумы внезапно резко увеличили использование диска и упали, полностью отключившись. Мне пришлось изменить размер образа Digital Ocean, чтобы восстановить их работу. Ох.

Вот использование диска за последние 24 часа:

Вопрос: какие логи или постмортем-анализ я могу изучить, чтобы попытаться понять, что, чёрт возьми, произошло?! Я проверил логи в панели управления Discourse, но там нет никаких подсказок… они просто обрываются в момент падения сайта, а затем снова появляются, когда он вернулся в онлайн.

Я бы начал с того, чтобы выяснить, какая директория вызывает проблему. Мой стандартный подход: перейти в /var/discourse и выполнить команду du -h -d 1. Затем зайти в самую большую директорию, снова выполнить команду и повторять процесс, пока не найдёте виновника. Как только вы его обнаружите, это может дать подсказку о том, что происходит.

Может быть, автоматическое резервное копирование?

Да, резервные копии — это распространённая причина таких сбоев. Как выглядит использование диска за последние 7 дней?

Также обратите внимание, что в эти резервные копии включены локальные загрузки, поэтому, если около 18:00 вы значительно увеличили количество загрузок, это также привело бы к росту размера архива резервной копии.

Хм. Я переносил файлы с S3 обратно на свой локальный сервер (Rake uploads:migrate_from_s3 fails - #31 by pnoeric), но этот процесс, похоже, выполняется «на лету», обрабатывая только несколько сотен изображений (каждое около 300 КБ) за раз — примерно 0,1 ГБ за партию. За последнюю неделю я, возможно, запускал скрипт 20 раз, то есть 20 партий = около 2 ГБ дискового пространства в сумме. У меня для этого было достаточно места.

Есть ли вероятность, что, несмотря на то, что скрипт, по-видимому, перемещает файлы «на лету» (скачивая их с S3 и сразу загружая на Digital Ocean), может существовать какая-то задержка для запланированного задания, которое должно было запуститься в 5:30 утра и было связано с перемещением этих изображений?

(Кроме того: я запускал эти партии вручную до 21:00, так что, насколько мне известно, с 21:00 до 5:30 утра, когда сервер упал, он выполнял только обычные операции.)

Вот моё использование диска за 7 дней. Оно неуклонно росло из-за импортируемых изображений, но вы видите, как оно резко достигло 100% в 5:30 утра:

Есть ли какие-либо файлы журналов, которые могли бы содержать подсказки о том, что произошло в 5:35 утра, помимо журналов, которые я вижу на вкладке «Журналы»?

Хм. Мои резервные копии настроены на отправку в S3 каждые 2 дня, но ничего с 9-го числа?

Просмотр «Резервные копии» в Discourse

Просмотр Amazon S3

Кстати, после просмотра вышеуказанного я нажал кнопку в Discourse, чтобы запустить резервное копирование вручную. Процесс занял 28 минут и, казалось, прошёл успешно; теперь я вижу этот файл .tar.gz как в представлении резервных копий Discourse, так и в представлении Amazon S3. Так почему же автоматические резервные копии не запускаются?! Аааааа.

Я в недоумении… ни одна из этих директорий не кажется особенно большой:

root@x-app:/var/www/discourse# du -h -d 1

3.5M	./lib
104K	./bin
8.0K	./.tx
148M    ./public
8.0K	./.bundle
14M     ./plugins
4.3M	./db
4.0K	./log
532M	./tmp
8.9M	./spec
17M     ./config
556M	./vendor
8.0K	./images
329M	./.git
2.0M	./script
80K	    ./docs
2.5M	./test
16K	    ./.github
17M	    ./app
1.6G	.

Даже если посмотреть на общее использование дискового пространства внутри Docker-контейнера, оно не такое большое, как было раньше. У меня был Droplet от DigitalOcean на 80 ГБ, который достиг 100% заполнения. Тогда я увеличил его до 160 ГБ, удвоив размер. Теоретически это означает, что одна из этих директорий должна занимать около 50%, верно?

root@x-app:/var/www/discourse# df -h

Filesystem      Size  Used Avail Use% Mounted on
overlay         155G   58G   98G  38% /
tmpfs            64M     0   64M   0% /dev
tmpfs           3.9G     0  3.9G   0% /sys/fs/cgroup
shm             512M  2.6M  510M   1% /dev/shm
/dev/vda1       155G   58G   98G  38% /shared
tmpfs           3.9G     0  3.9G   0% /proc/acpi
tmpfs           3.9G     0  3.9G   0% /proc/scsi
tmpfs           3.9G     0  3.9G   0% /sys/firmware

У вас почти каждую ночь уровень заполнения диска приближался к 100% — похоже, именно это стало последней каплей. Я предполагаю, что предыдущие резервные копии не удались из-за нехватки места при создании локального файла резервной копии для отправки в S3, но они просто завершились ошибкой и не сломали ваш форум. Вы наконец заметили проблему, когда нехватка места вызвала сбои в PostgreSQL (или Redis, или в чём-то ещё — это не так важно) в самый неподходящий момент, что привело к падению форума.

(У меня на сервере почти 100 ГБ изображений, поэтому я делаю запланированные резервные копии Discourse без загрузки файлов, но с миниатюрами. Затем я сначала выполняю резервное копирование на внешнем носителе для каталога backups, а затем для каталога uploads. Я тестировал этот метод для восстановления; он стал основой для миграции сайта, которую я провёл в прошлом году. Хранить каждую ночь архивы по 100 ГБ — это безумие.)

Ага, так эти небольшие всплески — это Discourse пытается сделать резервную копию! Это проливает свет на ситуацию.

Итак, вот мой график за последние 7 дней снова.

Возможно, мы видим следующее:

  1. Несколько раз за эту неделю Discourse пытался создать резервную копию. Этот процесс временно занимает много дискового пространства, и каждый раз, когда он пытался, ему не хватало места, поэтому ни одна из этих копий не удалась.

  2. Затем, когда он попытался сделать резервную копию в прошлую ночь, он продвинулся дальше, но, к сожалению, это привело к сбою сайта.

Это имеет смысл, поскольку последняя успешная резервная копия была создана 9 июля. Затем он ждал 2 дня (согласно моим настройкам) и попытался снова 11 июля. Это не удалось, поэтому он ждал 24 часа и попытался снова 12-го, 13-го и, наконец, фатальная попытка 14-го.

Если так всё и произошло, я бы хотел увидеть:

  1. Более подробные уведомления от Discourse при сбое резервного копирования.

  2. Возможно, Discourse должен автоматически «считаться неудачным» резервное копирование (создавая уведомление), если при его запуске свободное дисковое пространство составляет менее x% (10%?). То есть, если дисковое пространство уже ограничено, он даже не должен начинать процесс.

Кстати, если это действительно то, что произошло, то просмотр первой неудачной резервной копии от 11 июля показывает, что было доступно около 40% свободного дискового пространства (что составляло бы около 32 ГБ!!!), но этого всё равно не хватило для успешного завершения резервного копирования. Это правильно?! Почему Discourse требует, казалось бы, чрезмерного количества временного/рабочего пространства при создании резервной копии?

Вчера это не обязательно продвинулось дальше; вы просто «проиграли гонку» — то, что произойдёт, когда место закончится, зависит от того, какой компонент первым пострадает от проблемы.

Если создание резервной копии не удаётся, я скорее ожидаю, что система попытается отправить сообщение, но если место на диске закончилось, это может не получиться. :scream:

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

Я не знаю, как вы определяете «чрезмерное» — мне это не кажется чрезмерным.

Вполне справедливо; как вы верно заметили, в игру вступает множество переменных.

О, «правильный» способ заключался бы в расчёте объёма места, который, по мнению системы, потребуется для резервного копирования и так далее. Но чтобы сохранить всё максимально простым, да, просто фиксированный процент. Я просто думаю… если выбор стоит между «ваш сайт может полностью упасть и уйти в офлайн» и «вот неидеальное, но быстрое решение проблемы», я выберу второе, спасибо. :wink:

И говоря о благодарности, большое спасибо ВАМ за всю помощь с миграцией и за ваши мысли по этому поводу. :+1:t2:

Оценка необходимого места для резервного копирования — одна из сложных проблем в информатике… Это дальний родственник индикатора прогресса. :wink:

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

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

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

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

Почему бы не подтвердить на 100%, что проблема именно в ежедневном процессе резервного копирования? На хостах выполняется более одного процесса из ежедневных crontab-файлов.

Выполнял ли @pnoeric команду du на файловой системе /var/discourse (вне контейнера)?

В своих заметках @pnoeric пишет:

root@x-app:/var/www/discourse# du -h -d 1

Но это полностью пропустило общую директорию Discourse, включая все резервные копии и загрузки! Также это не учитывает все файлы Docker (и образы) на хосте (которые могут значительно увеличиваться, если образы не удаляются со временем).

Эту проверку нужно выполнять вне контейнера (не внутри контейнера!):

Например (вне контейнера):

cd /var/discourse 
/var/discourse# du -sh *
4.0K	bin
4.0K	cids
56K	containers
12K	discourse-doctor
24K	discourse-setup
164K	image
24K	launcher
4.0K	LICENSE
12K	README.md
24K	samples
8.0K	scripts
62G	shared
148K	templates

Как видно на этом хосте, общая директория занимает 62 ГБ.

А также из директории /var файловой системы (вне контейнера):

cd /var
# du -sh *
511M	cache
20K	composetest
62G	discourse
1.6G	docker
8.0K	legacy
52G	lib
4.0K	local
0	lock
4.0K	locks
5.7G	log
24K	logs
64K	mail
4.0K	opt
4.0K	registry
4.0K	shared
1.9M	spool
48K	tmp
25G	 linux_app
2.2G	www

Я не хочу портить праздник, но прежде чем предлагать множество «исправлений» для Discourse, было бы очень хорошо на 100% убедиться, что именно cron-процесс резервного копирования Discourse является реальной проблемой.

У нас не было никаких проблем с текущим процессом резервного копирования Discourse, и кроме того, управление файловой системой на хосте — это не задача самого Discourse.

Вот:

du

Filesystem     1K-blocks      Used Available Use% Mounted on
udev            32892500         0  32892500   0% /dev
tmpfs            6584232      2136   6582096   1% /run
/dev/md2       470927632 215969956 230966124  49% /
tmpfs           32921160         0  32921160   0% /dev/shm
tmpfs               5120         0      5120   0% /run/lock
tmpfs           32921160         0  32921160   0% /sys/fs/cgroup
/dev/md0          482922     75082    382906  17% /boot
/dev/sda1         244988      4636    240353   2% /boot/efi
tmpfs            6584232         0   6584232   0% /run/user/1000
overlay        470927632 215969956 230966124  49% /var/lib/docker/overlay2/0f8be368b0154285423630ad50148ee2d5fdcb357c46125eafa7374ca34ef29a/merged
shm               524288      1620    522668   1% /var/lib/docker/containers/ca7b55fc5a0c123f7b2b1234ea210aa8286a34167cba9344b7929547bd323c9b/mounts/shm
overlay        470927632 215969956 230966124  49% /var/lib/docker/overlay2/7cd7e8b5b35b496eaed68753cc995e9303499a24721062055e2f06beb07e26c8/merged
shm                65536         0     65536   0% /var/lib/docker/containers/3cc0c90c3e3a5db6692e7b5d21727fbb1c13c8e07e48e4f6d954214fc03694a9/mounts/shm
overlay        470927632 215969956 230966124  49% /var/lib/docker/overlay2/31533fdf68033eed96dab4f9df89025ea3dab172ed48b6ce6431840a8df1c8ea/merged
shm               524288         0    522668   0% /var/lib/docker/containers/631fbabedda9a430dd8204ec66fb45c7514d948025124171b960ea424e28d5d4/mounts/shm
overlay        470927632 215969956 230966124  49% /var/lib/docker/overlay2/7a3ba2223ee93bc868b52b3707799d0fd7b4ca6dcc0df29f20c2c98a53903ff1/merged
shm                65536         0     65536   0% /var/lib/docker/containers/7a145366268c8ac5543a4555dc1bfc63c1e85a654e4c793e96fc2cc2e8514388/mounts/shm
overlay        470927632 215969956 230966124  49% /var/lib/docker/overlay2/add4bdd7bd88df7a0e05dff21896d3ef796f7cf2ff9759e0bb04b1953f16cd95/merged
shm                65536         0     65536   0% /var/lib/docker/containers/123743e122089b94660a6bdd2a9e55055ad91b6f75cce4ac760f36066bcf14d0/mounts/shm
overlay        470927632 215969956 230966124  49% /var/lib/docker/overlay2/b376ff32eaac0c58463e8b99b6db9ec0da3405c3f7a9f00b5430f10e07d372b0/merged
shm               524288         0    524288   0% /var/lib/docker/containers/63c52bc571b5f0d2544417da10efc37d3957e7a38f44bc8325145e795ee29559/mounts/shm

Давайте посмотрим на файлы Docker:

# cd /var/lib
# du -sh docker
30G	docker

Наши образы Docker регулярно удаляются и очищаются.

@bartv правильно предложил начать с этого:

Я бы начал с определения, какая именно директория разрастается. Мой стандартный подход — зайти в /var/discourse и выполнить du -h -d 1. Затем войти в самую большую директорию и повторять процесс, пока не найдёте подозреваемого. Как только вы его найдёте, это может дать подсказку о том, что происходит.

Это хорошее начало, но на файловой системе хоста может быть много других мест, которые могут заполнить её, включая Docker, файлы ядра и т. д.

График, показывающий резкий скачок процентов раз в день, недостаточно, чтобы с уверенностью утверждать, что cron-процесс резервного копирования Discourse является корневой причиной. Возможно, это так, но, судя по имеющимся данным, это может быть и не так!

Это отлично. Я попробую все, что вы упомянули. Спасибо.

Да, это явно резервная копия.

Нет, подтверждений достаточно: пики происходят с интервалом в 2 дня (за одним исключением), а частота резервного копирования установлена на 2 дня. Предыдущий опыт работы на Meta также показывал именно такой сценарий сбоя.

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

Поскольку @pnoeric пытается уйти от S3 для изображений, хранение нескольких копий всех изображений в резервной копии, которая находится в S3, не выполнит цель перехода от S3. @pnoeric, это меня смущает — если вы хотите уйти от S3, но переносите лишь часть файлов, потому что храните все изображения в S3 в нескольких копиях резервных копий, в чём смысл?

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

Я перешёл от «S3» (в моём случае — DigitalOcean Spaces), когда у меня появилось достаточно места на сервере и отсутствие стремительного роста или трафика, что сделало бессмысленным пребывание на «S3». Но я — исключение, и, вероятно, именно поэтому мой PR, решающий проблему повреждения данных при миграции с S3, так и не получил ни слова рецензии. :stuck_out_tongue: Поэтому я ожидаю, что моя система резервного копирования будет крайне необычной.

Моя ситуация такова: у меня много изображений, что означает большой объём передаваемого трафика, когда пользователи просматривают эти изображения. Когда изображения хранились на Amazon S3, именно счёт за трафик стал для меня проблемой. Особенно после того, как я понял, что могу хранить все изображения на DO droplet, и это будет включено в уже оплачиваемые мной тарифы за трафик и хранилище. (В какой-то момент в будущем может иметь смысл вернуть всё обратно на S3, или, возможно, будет целесообразнее просто увеличить мощность моего DO droplet…)

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

Сохранение полной резервной копии (включая изображения) на S3 — это совсем другая история: она находится в «холодном хранилище» на S3 и не используется, если не возникнет проблем. Поэтому больших счетов за трафик нет.

Кроме того: я ещё раз обдумал ситуацию с резервным копированием и использованием дискового пространства. Я всё ещё считаю, что здесь чего-то не хватает. Возможно, это просто предупреждающее сообщение или более подробная документация. Мой Discourse использовал всего 60% дискового пространства, но при этом внешние резервные копии не удавались. Какая-то оценка необходимого дискового пространства или предупреждение о нехватке места, или что-то ещё казались бы лучше того, что происходит сейчас, когда места недостаточно: отсутствие резервных копий в течение нескольких дней, за которым следует полный сбой, полностью выводящий форум из строя. :-\

(@riking даже сказал: «резервные копии — частая причина подобных сбоев». Значит, экземпляры Discourse регулярно падают из-за неудачных резервных копий без предупреждения о возможной проблеме?)

Иными словами, очень просто, если посмотреть сверху: кажется, что это конструктивный недостаток, если базовая функция программного обеспечения (автоматическое резервное копирование) может вывести всю систему из строя. Особенно когда речь идёт о функции, которая просто использует дисковое пространство для подготовки резервной копии, но даже не хранит её на том же диске.

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

Конечно, но именно поэтому S3 нужно закрывать CDN. Не отдавайте изображения напрямую из S3 — это будет невероятно дорого :scream:. Вы легко можете закрыть S3 через CloudFront или даже CloudFlare. Бесплатный тариф CloudFlare справится с этим.

А хранение их локально — тоже плохая идея: вам придется без необходимости масштабировать свой VPS. Локальные SSD будут значительно дороже.

Ах, понял, теперь ясно.

Так как же узнать, сколько дискового пространства может потребоваться для создания резервной копии в Discourse? Программа не сообщает об этом, и, возможно, завтра потребуется уже 500 ГБ, и мой сервер Digital Ocean снова отключится. :man_shrugging:t2: По крайней мере, если я смогу сделать приблизительный расчет, я смогу держать ситуацию под контролем.

Ого, отличная идея. Никогда об этом не думал. Значит, я должен применить CDN к своему бакету Amazon, а затем настроить Discourse на использование S3 для всех активов? (Как у меня было раньше? lol)