100 万を超えるページ (シーケンス ID で終わる URL) をダウンロードしようとしています。設定可能な数のダウンロード スレッドと 1 つの処理スレッドを備えた一種の多目的ダウンロード マネージャーを実装しました。ダウンローダーはファイルをバッチでダウンロードします。
curl = Curl::Easy.new
batch_urls.each { |url_info|
curl.url = url_info[:url]
curl.perform
file = File.new(url_info[:file], "wb")
file << curl.body_str
file.close
# ... some other stuff
}
8000ページのサンプルをダウンロードしようとしました。上記のコードを使用すると、2 分で 1000 が得られます。すべての URL をファイルに書き込んでシェルで実行すると、次のようになります。
cat list | xargs curl
8000 ページすべてを 2 分で作成しました。
他の監視および処理コードがあるため、ルビーコードでそれを含める必要があります。
私が試してみました:
- Curl::Multi - なんとなく高速ですが、ファイルの 50 ~ 90% が失われます (ファイルをダウンロードせず、理由/コードも提供しません)。
- Curl::Easy を使用した複数のスレッド - シングル スレッドとほぼ同じ速度
再利用された Curl::Easy が後続のコマンド ラインの curl 呼び出しよりも遅いのはなぜですか? どうすれば高速化できますか? または、私が間違っていることは何ですか?
この場合、別の方法でダウンロードを行うよりも、ダウンロード マネージャーのコードを修正したいと考えています。
この前は、URL のリストを含むファイルを提供するコマンドライン wget を呼び出していました。ただし、すべてのエラーが処理されたわけではなく、URL リストを使用する場合、URL ごとに個別に出力ファイルを指定することもできませんでした。
「curl」コマンドへのシステムコールで複数のスレッドを使用するのが最善の方法であるように思えます。しかし、Ruby で直接 Curl を使用できるのに、なぜでしょうか?
ダウンロード マネージャーのコードはここにあります。ダウンロード マネージャー(タイムアウトをさまざまな値に設定しないことから試してみましたが、役に立たなかったようです)
ヒントをいただければ幸いです。