Discourse로 데이터를 가져오는 작업(bulk importer 사용)을 진행 중입니다. 토픽과 포스트는 매우 잘 처리되지만, 현재 병목은 파일 업로드입니다. 약 50,000명의 사용자에게 아바타가 있으며, 사용자 데이터는 DB에 몇 초 만에 가져와지지만 아바타는 몇 시간씩 걸립니다. 초당 약 1개씩만 처리되고 있습니다.
이를 더 빠르게 할 수 있는 방법이 있을까요? 이 과정에서 어떤 부분이 가장 느린지 정확히 파악이 안 됩니다. 아바타 파일이 없는 경우(photo_filename이 존재하지 않는 경우)에는 매우 빠르게 실행되지만, 이 importer 코드가 최종적으로 호출하는 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 "Error: Upload did not persist for #{u.username} #{photo_real_filename}!"
end
대신 tar, gzip, sftp, rsync 등 일반적인 파일 전송 도구를 사용했습니다.
솔직히 말씀드리면, 우리는 Discourse(마이그레이션) 스크립트의 여러 부분을 활용했지만, 마이그레이션 과정에서 실제로 사용한 코드의 절반 이상은 직접 작성해야 했습니다. 수십 년치 “코딩” 게시글을 정리(검토)하기 위해 몇 달 동안 gsub() 코드를 작성해야 했기 때문이죠. 수년에 걸쳐 많은 코드를 게시한 모더레이터들이 검토에 참여했고, 모두가 문법 오류가 전혀 없는 완벽한 코드를 원했기 때문입니다.
Discourse에서 제공하는 스크립트는 훌륭한 출발점이라고 생각했으며, 이를 광범위하게 활용했습니다. 또한 해당 스크립트를 기반으로 우리만의 스크립트도 많이 작성했습니다.
죄송합니다. 제 질문이 놓친 것 같습니다. 가져오기가 수행되는 서버 환경으로 파일을 이동하는 방법에 대한 지침은 필요하지 않습니다. @Ghan이 작성 중인 일괄 가져오기(bulk importer) 스크립트가 있으며, 첨부 파일을 더 빠르게 처리하는 방법을 알아내려고 하고 있습니다. 일반 가져오기 도구에서 일괄 가져오기 도구로 전환하면서 게시물 가져오기 시간이 일주일에서 약 2시간으로 단축되었습니다. 첨부 파일을 올바르게 처리하는 방법에 대해 올바른 방향을 제시해 주실 수 있는 분이 있기를 바랐습니다.
유사한 만능 해결책은 없다고 생각합니다. 업로드 처리가 이전 게시글의 처리에 의존하지 않으므로, 여러 프로세스를 실행하도록 구성할 수 있습니다(예: 각 프로세스가 서로 다른 날짜 범위를 처리). 이렇게 하면 사용할 수 있는 CPU 수만큼 처리 시간을 줄일 수 있습니다(데이터베이스와 파일 시스템이 병목 현상이 되지 않는다는 전제 하에).
첨부 파일이 포함된 게시물이 처리되는 동안, 해당 게시물에 대한 기타 처리 작업을 위해 여러 sidekiq 작업이 생성되는 것으로 보입니다. 그 결과, 첨부 파일 가져오기를 처리하는 단일 프로세스 하나만으로도 8코어 환경에서 서버의 평균 부하(load average)가 40을 넘게 천천히 끌어올리는 상황이 발생합니다. (부하를 감당하기 위해 sidekiq 워커 수를 늘렸습니다.)
가져오기가 완료될 때까지 unicorn 서비스를 중지할 수도 있지만, 이는 단순히 부하를 나중에로 미루는 것에 불과합니다. 처리 작업은 결국 어떤 방식으로든 수행되어야 하는 것 같습니다.