UploadCreator をバイパスしてインポート

Discourse への一括インポートツールを使用して作業を進めています。トピックや投稿のインポートは非常にスムーズに動作していますが、現在はファイルの処理がボトルネックとなっています。ユーザーは約 5 万人おり、アバター画像が含まれていますが、ユーザーデータの DB へのインポートは数秒で完了するのに対し、アバターのインポートには数時間かかっています。現在、1 秒間に約 1 件のアップロードしか処理できていません。

これを高速化する方法はありますか?どの部分が最も遅いか特定できていません。アバターファイルが見つからない場合(photo_filename が存在しない場合)は非常に高速に処理されますが、このインポートコードから最終的に呼び出される UploadCreator クラスを調査しようとして、少し混乱しています。

添付ファイルは 60 万件以上あるため、同じ 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
「いいね!」 2

@neounix、以前大規模な一括インポーターを実行されたので、何かご存知でしょうか?

一括インポーターのおかげで、2600万件の投稿を1週間かかっていた処理を約2時間に短縮できました。現在は添付ファイルの処理に数日を要することが課題となっています。

@TheDarkWizard さん、こんにちは。

実際のファイルの移行には、Discourse のスクリプトは使用しませんでした。

代わりに、targzipsftprsync などの通常のファイル転送ユーティリティを使用しました。

正直なところ、Discourse の(移行)スクリプトの様々な部分を参考にしましたが、移行時に使用したコードの半分超は、結局は私たちが自分で記述しました。というのも、長年にわたって多くのコードを投稿してきたモデレーターがレビューした、数十年分の「コーディング」投稿をクリーンアップするために、gsub() を使ったコードを数ヶ月にわたって記述する必要があったからです。誰もが自分のコードが完璧で、構文エラーがゼロであることを望んでいたのです!

Discourse が提供するスクリプトは素晴らしい出発点だと考え、それらを大いに活用しました。また、それらのスクリプトをベースに、独自のコードも多数作成しました。

参考になれば幸いです。

申し訳ありませんが、私の質問が見落としてしまったのかもしれません。インポートが行われるサーバー環境へのファイル移動方法に関する手順は不要です。@Ghan が作成しているバッチインポートスクリプトを使用しており、添付ファイルの転送速度をどうすれば向上できるか模索しています。通常のインポートからバッチインポートに切り替えたことで、投稿のインポートにかかる時間が1週間から約2時間に短縮されました。添付ファイルの適切な処理方法について、何かヒントをいただけないでしょうか。

もし私の質問の読み方が間違っていて、回答が役に立たなかったならお詫びします。

とにかく、きっと解決策を見つけられると思います。これはロケット科学ではありません(ただのソフトウェアです):slight_smile: しかも、皆さんは賢い方々ですから。

幸運を祈ります。もっとお役に立てず申し訳ありません。当社は2020年第2四半期にマイグレーションを完了しており、その作業(マイグレーションタスク)はすでに過去の出来事となっています。

「いいね!」 1

なるほど!
あなたのサイト、とても素敵ですね :slight_smile:

「いいね!」 1

同様の「銀の弾丸」のような解決策はないと思います。アップロードは過去の投稿の処理を前提としていないため、複数のプロセス(例えば、それぞれが異なる日付範囲を担当するもの)を並列に実行することで、利用可能な CPU コア数に比例して処理時間を短縮できます(ただし、データベースやファイルシステムがボトルネックにならないことが前提です)。

投稿の添付ファイル処理が行われる際、これらの投稿に関する他の処理に対応するために複数の Sidekiq ジョブが起動されているようです。その結果、8 コア搭載のサーバーであっても、添付ファイルのインポートを 1 つのプロセスで処理しているだけでも、サーバーの負荷平均が徐々に 40 を超えてしまいます(負荷に対応するため Sidekiq ワーカーの数を増やしました)。

インポートが完了するまで Unicorn サービスを停止することも可能ですが、それは単に負荷を後方にシフトしているに過ぎません。どうやら、この処理は何らかの方法で行わなければならないようです。

それは根本的な真実です。