私は数日間 distcp と格闘してきました。これが私のユースケースです:
使用事例
/hdfs/rootなどの特定の場所にメインフォルダーがあり、多くのサブディレクトリ(深さは固定されていません)とファイルがあります。
ボリューム: 200,000 ファイル ~= 30 GO
クライアントのサブセット ( /hdfs/rootなど) のみを別の場所 (たとえば /hdfs/dest) にコピーする必要があります。このサブセットは、時間の経過とともに更新できる絶対パスのリストによって定義されます。
ボリューム: 50,000 ファイル ~= 5 GO
hdfs dfs -cp /hdfs/root /hdfs dest
シンプルは最適化されておらず、すべてのファイルが必要であり、更新モードがないため、使用できないことを理解しています。
ソリューション POC
最終的に、次の 2 つの方法で hadoop distcp を使用しました。
Algo 1 (simplified):
# I start up to N distcp jobs in parallel for each subdir, with N=MAX_PROC (~30)
foreach subdir in mylist:
# mylist = /hdfs/root/dirX/file1 /hdfs/root/dirX/file2 ...
mylist = buildList(subdirs)
hadoop distcp -i -pct -update mylist /hdfs/dest/subdir &
と
Algo 2
# I start one distcp that has a blacklist
blacklist = buildBlackList()
hadoop distcp -numListstatusThread 10 -filters blacklist -pct -update /hdfs/root /hdfs/dest
Algo 2 も起動しません。ソースとブラックリストの差分を作成するのは彼には難しすぎるようです。そのため、Algo 1 を使用しましたが、うまくいきました。
OOZIE ワークフロー
Oozie ワークフローですべてのワークフローをスケジュールする必要があることを知っています。私はdistcpコマンドをたくさん持っていて、oozieで再帰やループをマスターしていないので、アルゴ2をシェルアクションに入れました。
開始してしばらくすると、次のエラーが表示されます: コンテナーが物理メモリの制限を超えて実行されています。現在の使用量: 16 GB の物理メモリのうち 17.2 GB を使用
それでは、メモリを追加します。
<configuration>
<property>
<name>oozie.launcher.mapreduce.map.memory.mb</name>
<value>32768</value>
</property>
<property>
<name>oozie.launcher.mapreduce.map.java.opts</name>
<value>-Xmx512m</value>
</property>
</configuration>
それでも、コンテナが物理メモリの制限を超えて実行されます。現在の使用量: 32 GB の物理メモリのうち 32.8 GB が使用されていますが、ジョブは前のジョブの 2 倍長く存続しました。
クラスターの RAM は無限ではないため、これ以上先に進むことはできません。ここに私の仮説があります:
- distcp ジョブがメモリを解放しない (JVM ガベージ コレクタ ?)
- Oozie は、すべての distcp ジョブの追加を現在のメモリ使用量として認識します。これはばかげています。
- これはこれを行う正しい方法ではありません(よく知っていますが、それでも)
また、メモリ管理について理解していないことがたくさんあります。かなり曖昧です (yarn、oozie、jvm、mapreduce)。
グーグルで調べていると、実際の distcp の使用例について話している人がほとんどいないことに気付きました。この投稿は 4 日前のものです。 htmlを参照し、私の場合は使用できないスナップショットの使用法について説明します。
http://atlas.incubator.apache.orgについても聞いたことがあります。これは、ファイルを「タグ付け」し、特定のユーザーにアクセスを許可することで最終的に問題を解決するため、特定の場所へのコピーを回避できます。私の管理チームはそれに取り組んでいますが、本番環境には反映されません。
私はかなり絶望的です。助けて。