web-dev-qa-db-ja.com

2TB(10 milファイル+ディレクトリ)を移動すると、私のボトルネックは何ですか?

バックグラウンド

I スペースが不足しています/home/dataで、/home/data/repo/home/data2に転送する必要があります。

/home/data/repoには100万個のディレクトリが含まれ、それぞれに11個のディレクトリと10個のファイルが含まれています。合計2TBです。

/home/dataは、dir_indexが有効になっているext3上にあります。 /home/data2はext4にあります。 CentOS6.4の実行。

repo/のすぐ下に100万個のディレクトリがあるため、これらのアプローチは遅いと思います。


試行1:mvは高速ですが、中断されます

これが終了した場合、私は行うことができます:

/home/data> mv repo ../data2

しかし、1.5TBが転送された後、中断されました。約1GB /分で書いていました。

試行2:ファイルリストを作成してから8時間後にrsyncがクロールする

/home/data> rsync --ignore-existing -rv repo ../data2

「インクリメンタルファイルリスト」の作成には数時間かかり、その後100MB /分で転送されます。

より速いアプローチを試みるためにそれをキャンセルします。

試行3a:mv不平

サブディレクトリでテストする:

/home/data/repo> mv -f foobar ../../data2/repo/
mv: inter-device move failed: '(foobar)' to '../../data2/repo/foobar'; unable to remove target: Is a directory

これが何のエラーなのかはわかりませんが、おそらくcpが私を救済できるかもしれません。

試行3b:cpは8時間後に何も起こりません

/home/data> cp -nr repo ../data2

8時間ディスクを読み取り、キャンセルしてrsyncに戻ることにしました。

試行4:ファイルリストを作成してから8時間後にrsyncがクロールする

/home/data> rsync --ignore-existing --remove-source-files -rv repo ../data2

--remove-source-filesを使用して、今すぐクリーンアップを開始すると高速になる可能性があると考えました。

ファイルリストの作成には少なくとも6時間かかり、その後100〜200 MB /分で転送されます。

しかし、サーバーは一晩の負担があり、私の接続は閉じられました。

試行5:移動するのに300GBしか残っていない理由IS THIS SO PAINFUL

/home/data> rsync --ignore-existing --remove-source-files -rvW repo ../data2

再び中断されました。 -Wは、「増分ファイルリストの送信」を高速化するように見えましたが、私の理解では意味がありません。とにかく、転送はひどく遅いので、私はこれをあきらめています。

試行6:tar

/home/data> Nohup tar cf - . |(cd ../data2; tar xvfk -)

基本的にすべてを再コピーしようとしますが、既存のファイルは無視します。 1.7TBの既存のファイルを通り抜ける必要がありますが、少なくとも1.2GB /分で読み取っています。

これまでのところ、これは即座に満足を与える唯一のコマンドです。

更新:Nohupを使用しても、どういうわけか、再び中断されました。

試み7:切腹

まだこれを議論している

試行8:スクリプト化された「マージ」とmv

宛先ディレクトリには約12万の空のディレクトリがあったので、実行しました

/home/data2/repo> find . -type d -empty -exec rmdir {} \;

Rubyスクリプト:

SRC  = "/home/data/repo"
DEST = "/home/data2/repo"

`ls #{SRC}  --color=never > lst1.tmp`
`ls #{DEST} --color=never > lst2.tmp`
`diff lst1.tmp lst2.tmp | grep '<' > /home/data/missing.tmp`

t = `cat /home/data/missing.tmp | wc -l`.to_i
puts "Todo: #{t}"

# Manually `mv` each missing directory
File.open('missing.tmp').each do |line|
  dir = line.strip.gsub('< ', '')
  puts `mv #{SRC}/#{dir} #{DEST}/`
end

完了

21
Tim

大きなタスクを小さなタスクに分割することを聞いたことがありますか?

/ home/data/repoには100万のdirが含まれ、各dirには11のdirと10のファイルが含まれます。合計2TBです。

rsync -a /source/1/ /destination/1/
rsync -a /source/2/ /destination/2/
rsync -a /source/3/ /destination/3/
rsync -a /source/4/ /destination/4/
rsync -a /source/5/ /destination/5/
rsync -a /source/6/ /destination/6/
rsync -a /source/7/ /destination/7/
rsync -a /source/8/ /destination/8/
rsync -a /source/9/ /destination/9/
rsync -a /source/10/ /destination/10/
rsync -a /source/11/ /destination/11/

(...)

コーヒー休憩時間。

これが起こっていることです:

  • 最初にrsyncはファイルのリストを作成します。
  • ファイルリストの最初の並べ替えのため、このリストの作成は非常に低速です。
  • これは、ls -f -1を使用してxargsと組み合わせて、rsyncが使用するファイルのセットを構築するか、ファイルリストを使用して出力をファイルにリダイレクトすることで回避できます。
  • このリストをフォルダーではなくrsyncに渡すと、rsyncがすぐに機能し始めます。
  • 何百万ものファイルを含むフォルダに対するls -f -1のトリックは、この記事で完全に説明されています。 http://unixetc.co.uk/2012/05/20/large-directory-causes-ls-to -hang /
4
maki

Rsyncが遅い場合でも(なぜ遅いのですか?多分-zで解決します)、多くのファイルを移動したように聞こえるので、試してみてください:

--remove-source-filesを使用した場合は、空のディレクトリを削除してフォローアップできます。 --remove-source-filesはすべてのファイルを削除しますが、ディレクトリはそこに残します。

DO NOTを確認してください--remote-source-filesを--deleteとともに使用して複数のパスを実行します。

また、速度を上げるには、-inplaceを使用できます

サーバー上でこれをリモートで実行しようとしているために追い出されている場合は、「スクリーン」セッション内で実行してください。少なくともそうすれば、実行させることができます。

1
Angelo