Я работаю над импортом в Discourse с использованием массового импортера. Это отлично работает для тем и сообщений, но сейчас узким местом являются файлы. У нас около 50 000 пользователей с аватарами, и хотя данные пользователей загружаются в базу данных за считанные секунды, импорт аватаров занимает часы. Обрабатывается примерно одна загрузка в секунду.
Есть ли способ ускорить этот процесс? Я не уверен, какая часть процесса самая медленная. Если файл аватара не найден (photo_filename не существовал), то выполнение происходит очень быстро, но мне немного трудно разобраться в классе UploadCreator, который в конечном итоге вызывается этим кодом импортера.
У нас более 600 000 вложений, поэтому я очень обеспокоен тем, сколько времени займет их импорт с использованием того же вызова create_upload.
upload = create_upload(u.id, photo_filename, File.basename(photo_filename))
if upload.persisted?
u.import_mode = false
u.create_user_avatar
u.import_mode = true
u.user_avatar.update(custom_upload_id: upload.id)
u.update(uploaded_avatar_id: upload.id)
else
puts "Ошибка: Загрузка не была сохранена для #{u.username} #{photo_real_filename}!"
end
Есть какие-то идеи по этому поводу, @neounix, раз вы уже запускали большой массовый импорт?
Благодаря массовому импорту мы сократили время обработки 26 миллионов постов с недели до примерно двух часов. Теперь основная проблема — вложения, на обработку которых уходят несколько дней.
Мы не использовали скрипты Discourse для переноса самих файлов.
Мы применяли стандартные утилиты передачи файлов, такие как tar, gzip, sftp, rsync и другие.
Честно говоря, мы использовали различные скрипты миграции Discourse, но в итоге написали более половины всего кода, который применяли при миграции. Это связано с тем, что мы потратили месяцы на написание кода с использованием gsub() для очистки (и ревью) десятков лет постов с кодом, которые модераторы публиковали за эти годы. Все хотели, чтобы их код был идеальным, без единой синтаксической ошибки!
Мы считали, что скрипты, предоставленные Discourse, — отличная отправная точка, и активно их использовали. Кроме того, мы написали много собственных скриптов на их основе.
Извините, возможно, мой вопрос был пропущен. Нам не нужны инструкции о том, как переносить файлы в серверную среду, где происходит импорт. У нас есть скрипт пакетного импорта, который пишет @Ghan, и мы пытаемся понять, как ускорить загрузку вложений. Переход с обычного импортера на пакетный сократил время импорта постов с недели до примерно двух часов. Я надеялся, что кто-то укажет правильное направление, как правильно работать с вложениями.
Я не думаю, что существует подобное универсальное решение. Поскольку загрузки не зависят от обработки предыдущих постов, можно запустить несколько процессов (например, каждый обрабатывает свой диапазон дат), чтобы сократить время в зависимости от количества доступных процессоров (при условии, что база данных и файловая система не являются узким местом).
Похоже, что при обработке постов на наличие вложений запускается множество заданий Sidekiq для выполнения дополнительной обработки этих постов. В результате даже один процесс, занимающийся импортом вложений, постепенно поднимает среднюю нагрузку сервера выше 40, несмотря на наличие 8 ядер. (Я увеличил количество воркеров Sidekiq, чтобы справиться с нагрузкой.)
Я мог бы остановить службу Unicorn до завершения импорта, но это лишь перенесёт нагрузку на более позднее время. Похоже, что обработку всё равно нужно выполнить тем или иным способом.