個別のURLと希望するファイル名を持つ約1百万個のjpgファイルからなるデータをダウンロードしようとしています。画像の平均ファイルサイズは約120KBで、範囲は1KBから1MBです。 Rを使って画像をダウンロードしたいと思います。Rで100万枚の画像を効率的にダウンロードし、コンピュータ/ネットワークリソースをフルに活用する方法
私はいくつかのことを試してみたところ、3時間以内に100万枚の画像をダウンロードできる方法を見つけました。私の現在の戦略はうまくいきますが、もう一度使用したくないというやや不合理な解決策です。なぜそれが機能するのか、私は困惑しています。私は何が起こっているのかを理解し、同じ結果を達成するためのよりエレガントで効率的な方法を探したいと思います。
私はmapplyとdownload.file()で始めましたが、これは1秒あたり2画像の割合しか管理しませんでした。次に、このプロセスをパラレルパッケージと並列化しました。これは非常に効果的で、1秒間に9枚の画像に改善されました。それが私が達成できる最大のものだと思っていましたが、私の控えめなラップトップで使用されていたリソースは、どこにもありませんでした。かなりのディスクやネットワークアクセスのボトルネックがないことを確認しましたが、確かに、どちらも容量の10%以上を経験していませんでした。
URL情報を分割して新しいRコンソールウィンドウを開き、データの別のセグメントで同じスクリプトの2番目のインスタンスを実行して、1秒あたり18枚の画像を実現しました。それから、私はもっと多くのインスタンスを開き続け、それぞれにURLの完全なリストのユニークなセクションを与えました。遅くなるというヒントがあったのは、私が12回開いた時までだった。各インスタンスは、実際には1秒あたりのダウンロード数がほぼ直線的に増加しました。メモリ管理によっては、最大ダウン速度が13 MB /秒に近づきました。
は、私は非常に驚くべきこの結果を見つけ、これを可能にすべき理由私はかなり理解していない10 simultaneous instances of R were running.
ながら、私のリソースモニタのスクリーンショットで示すグラフを添付しています。個々のスクリプトの実行速度が遅いのはなぜですか?コンピュータがこのコードのインスタンスを12回実行することができれば、リターンはほとんどまたはまったく減りません。全く新しいR環境を開かなくても同じことを達成する方法はありますか?
ここに私が具体的に求めているコードがあります。残念ながら、私は元のURLを公開することはできませんが、スクリプトは私が使用しているものとほぼ同じです。私は自分のデータをウィキメディアのいくつかのCCイメージで置き換えました。レプリケーションを改善するには、そのようなものにアクセスできる場合は、「画像」を大きなURLリストに置き換えてください。要約すると
library(parallel)
library(data.table)
images <-
data.table(
file = c(
"Otter.jpg",
"Ocean_Ferret.jpg",
"Aquatic_Cat.jpg",
"Amphibious_Snake_Dog.jpg"
),
url = c(
"https://upload.wikimedia.org/wikipedia/commons/thumb/3/3d/Otter_and_Bamboo_Wall_%2822222758789%29.jpg/640px-Otter_and_Bamboo_Wall_%2822222758789%29.jpg",
"https://upload.wikimedia.org/wikipedia/commons/thumb/f/f7/Otter_Looking_Back_%2817939094316%29.jpg/640px-Otter_Looking_Back_%2817939094316%29.jpg",
"https://upload.wikimedia.org/wikipedia/commons/thumb/2/2a/Otter1_%2814995327039%29.jpg/563px-Otter1_%2814995327039%29.jpg",
"https://upload.wikimedia.org/wikipedia/commons/thumb/8/84/Otter_Profile_%2817962452452%29.jpg/640px-Otter_Profile_%2817962452452%29.jpg"
) #full URL's are redundant and unnecessary but I kept them in case there was some performance advantage over nesting a function inside download.file that combines strings.
)
#Download with Mapply (just for benchmarking, not actually used in the script)
system.time(
mapply(
function(x, y)
download.file(x, y, mode = 'wb', quiet = TRUE),
x = images$url,
y = images$file,
SIMPLIFY = "vector",
USE.NAMES = FALSE
)
)
#Parallel Download with clusterMap (this is what each instance is running. I give each instance a different portion of the images data table)
cl <- makeCluster(detectCores())
system.time(
clusterMap(
cl,
download.file,
url = images$url,
destfile = images$file,
quiet = TRUE,
mode = 'wb',
.scheduling = 'dynamic',
SIMPLIFY = 'vector',
USE.NAMES = FALSE
)
)
、私が求めています質問は以下のとおりです。
1)なぜ私の解決策はこのように動作していますか?具体的には、1つのスクリプトが自分のコンピュータのリソースを完全に利用していないのはなぜですか?
2)Rを使用して以下を達成するより良い方法は、3時間以内にURLを介して100万枚のJPEG画像から直接120GBをダウンロードすることです。
ありがとうございます。
ありがとうございました。これですべてが簡単になりました。どのノードで各ノードのダウンロードプロセスを遅くしておくのがいいですか? – ZNR