백업이 여러 번 S3 업로드에 실패 - 결국 작동함

S3 백업은 몇 년 동안 잘 작동해 왔습니다. 하지만 한 달 전부터는 백업이 실패했다는 알림을 여러 번 받는 경우가 많습니다. 그런 다음 재시도가 이루어지고, 약 1시간 후 다시 실패하여 두 번째 알림을 받게 되며, 최종적으로 성공하기 전까지 하루에 최대 6번까지 알림을 받는 경우가 많습니다.

알림의 로그에는 S3로 압축된 tar 파일을 업로드하는 데 실패했다고 나와 있습니다. 제 S3 계정에서는 오류를 찾을 수 없습니다.

로그 로그의 첫 부분은 정상적으로 보이다가, 이후 다음과 같은 내용이 나옵니다:

[2025-05-20 07:11:38] Finalizing backup…
[2025-05-20 07:11:38] Creating archive: 506-investor-group-2025-05-20-070428-v20250513161753.tar.gz
[2025-05-20 07:11:38] Making sure archive does not already exist…
[2025-05-20 07:11:38] Creating empty archive…
[2025-05-20 07:11:38] Archiving data dump…
[2025-05-20 07:12:17] Archiving uploads…
[2025-05-20 07:15:48] Removing tmp ‘/var/www/discourse/tmp/backups/default/2025-05-20-070428’ directory…
[2025-05-20 07:15:48] Gzipping archive, this may take a while…
[2025-05-20 07:32:51] Uploading archive…
[2025-05-20 07:34:28] EXCEPTION: Sidekiq::Shutdown
[2025-05-20 07:34:28] /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-s3-1.182.0/lib/aws-sdk-s3/multipart_file_uploader.rb:199:in value' /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-s3-1.182.0/lib/aws-sdk-s3/multipart_file_uploader.rb:199:in map’
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-s3-1.182.0/lib/aws-sdk-s3/multipart_file_uploader.rb:199:in upload_in_threads' /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-s3-1.182.0/lib/aws-sdk-s3/multipart_file_uploader.rb:82:in upload_parts’
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-s3-1.182.0/lib/aws-sdk-s3/multipart_file_uploader.rb:59:in upload' /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-s3-1.182.0/lib/aws-sdk-s3/file_uploader.rb:42:in block in upload’
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.219.0/lib/aws-sdk-core/plugins/user_agent.rb:69:in metric' /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-s3-1.182.0/lib/aws-sdk-s3/file_uploader.rb:40:in upload’
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-s3-1.182.0/lib/aws-sdk-s3/customizations/object.rb:477:in block in upload_file' /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.219.0/lib/aws-sdk-core/plugins/user_agent.rb:69:in metric’
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-s3-1.182.0/lib/aws-sdk-s3/customizations/object.rb:476:in upload_file' /var/www/discourse/lib/backup_restore/s3_backup_store.rb:48:in upload_file’
/var/www/discourse/lib/backup_restore/backuper.rb:351:in upload_archive' /var/www/discourse/lib/backup_restore/backuper.rb:41:in run’
/var/www/discourse/lib/backup_restore.rb:13:in backup!' /var/www/discourse/app/jobs/regular/create_backup.rb:10:in execute’
/var/www/discourse/app/jobs/base.rb:316:in block (2 levels) in perform' /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rails_multisite-6.1.0/lib/rails_multisite/connection_management/null_instance.rb:49:in with_connection’
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rails_multisite-6.1.0/lib/rails_multisite/connection_management.rb:21:in with_connection' /var/www/discourse/app/jobs/base.rb:303:in block in perform’
/var/www/discourse/app/jobs/base.rb:299:in each' /var/www/discourse/app/jobs/base.rb:299:in perform’
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:220:in execute_job' /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:185:in block (4 levels) in process’
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:180:in traverse' /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in block in traverse’
/var/www/discourse/lib/sidekiq/discourse_event.rb:6:in call' /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in traverse’
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in block in traverse' /var/www/discourse/lib/sidekiq/pausable.rb:131:in call’
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in traverse' /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in block in traverse’
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/job/interrupt_handler.rb:9:in call' /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in traverse’
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in block in traverse' /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/metrics/tracking.rb:26:in track’
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/metrics/tracking.rb:134:in call' /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in traverse’
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:173:in invoke' /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:184:in block (3 levels) in process’
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:145:in block (6 levels) in dispatch' /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/job_retry.rb:118:in local’
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:144:in block (5 levels) in dispatch' /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/config.rb:39:in block in class:Config’
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:139:in block (4 levels) in dispatch' /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:281:in stats’
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:134:in block (3 levels) in dispatch' /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/job_logger.rb:15:in call’
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:133:in block (2 levels) in dispatch' /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/job_retry.rb:85:in global’
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:132:in block in dispatch' /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/job_logger.rb:40:in prepare’
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:131:in dispatch' /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:183:in block (2 levels) in process’
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:182:in handle_interrupt' /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:182:in block in process’
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:181:in handle_interrupt' /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:181:in process’
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:86:in process_one' /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:76:in run’
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/component.rb:10:in watchdog' /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/component.rb:19:in block in safe_thread’
[2025-05-20 07:34:28] Deleting old backups…
[2025-05-20 07:34:28] Cleaning stuff up…
[2025-05-20 07:34:28] Removing archive from local storage…
[2025-05-20 07:34:28] Removing ‘.tar’ leftovers…
[2025-05-20 07:34:28] Marking backup as finished…
[2025-05-20 07:34:28] Notifying ‘system’ of the end of the backup…

디스크 공간은 충분합니다(백업 크기의 6배 이상 여유 공간이 있음).

오늘의 CPU 사용률 - 백업은 1시간 이내에 완료되어야 하지만, 9번이나 시도해야 하므로 4시간이 걸립니다:

메모리가 부족할 수 있습니다. 이 예외는 자동 백업을 실행하는 Sidekiq이 운영체제에 의해 종료되었거나 다른 이유로 충돌했음을 시사합니다.

이를 해결하기 위해 Docker 컨테이너를 재구축(./launcher rebuild app)해 보셨나요?

그렇지 않은 것 같습니다. 16GB RAM을 가진 서버는 우리 커뮤니티 규모에 비해 과도한 사양입니다. top 명령어를 확인해보면 11GB의 여유 메모리가 표시되며, 수동으로 백업을 트리거해도 이 값이 거의 변하지 않습니다.

내일 /var/log/syslog에서 메모리, kill 또는 OOM과 관련된 항목이 있는지 확인하겠습니다. (오늘은 관련 없는 상세 로그가 너무 많이 출력되어서 백업 이벤트가 syslog 버퍼에서 밀려나 버려서 확인이 불가능합니다.)

네, 며칠 전에 3.5.0.beta5-dev로 업데이트를 했는데도 문제가 계속되고 있습니다.

저는 /logs에 이 내용을 가지고 있습니다. 이 특정 경고는 백업과 일치하지 않았습니다 - 저는 내일 아침에 확인해 보겠습니다 (백업은 밤에 수행됩니다). 하지만 저는 Discourse가 자체 메모리 체크를 수행한다는 사실을 몰랐습니다. OOM killer에 대해 말씀하시는 줄 알았거든요. Sidekiq에 허용되는 메모리 크기를 늘릴 수 있을까요?

메시지

'ip-172-26-9-xxx-app’의 Sidekiq이(가) 너무 많은 메모리(사용량: 547.87M)를 소비하고 있어 재시작 중

백트레이스

/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-7.2.2.1/lib/active_support/broadcast_logger.rb:130:in block in warn' /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-7.2.2.1/lib/active_support/broadcast_logger.rb:231:in block in dispatch’
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-7.2.2.1/lib/active_support/broadcast_logger.rb:231:in each' /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-7.2.2.1/lib/active_support/broadcast_logger.rb:231:in dispatch’
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-7.2.2.1/lib/active_support/broadcast_logger.rb:130:in warn' /var/www/discourse/lib/demon/sidekiq.rb:59:in block in rss_memory_check’
/var/www/discourse/lib/demon/sidekiq.rb:53:in each' /var/www/discourse/lib/demon/sidekiq.rb:53:in rss_memory_check’
config/unicorn.conf.rb:132:in `block (2 levels) in reload’

수정: 다음 내용을 확인했습니다:

실제로 제가 언급한 것은 OOM 킬러였습니다. Sidekiq에 메모리 한도가 있다는 사실을 완전히 잊고 있었습니다. Sidekiq의 메모리를 늘린 것이 도움이 되었나요?

그렇게 하면 해결될 것 같습니다. 확실하기 위해 몇 번 더 깨끗한 야간 백업이 정상적으로 진행되는지 확인해 보겠습니다. 여기서 다시 공유하겠습니다.

네, 수정되었습니다. 이 주제를 닫으셔도 됩니다.