所属していないクラスタに対してDispCpやhdfs dfsを使う場合のTips
この記事は Distributed computing (Apache Spark, Hadoop, Kafka, ...) Advent Calendar 2020 の11日目の記事です。
クラスタ間でHDFSファイルを移動したいというのは割とよくある話です。 そこでHDFSファイルを大量に移動する際は、DistCpを使うことになります。
ただ、移動元も移動先にも所属していないクライアントから通常DistCpは使えません(クラスタの設定情報がないので)。
設定をどうにかして渡せば、多分出来るだろうなぁと思いつつも「まぁ移動先のクラスタクライアントにSSHしたらいいか。」で後回しにしてましたが、自分のPCからDocker使ってやりたいなぁって事で調べました。
DistCpそのものについては、以下の最高の記事があるのでそこを参照下さい。 shiumachi.hatenablog.com
前提
以下のCloudera Enterpriseが対象です。
所属していないクラスタに対してDispCpを実施したい場合
例:クラスタAのクライアントから、クラスタB(source)→クラスタC(target)に対してDistCpを実行したい
# クライアント $ hadoop version Hadoop 2.6.0-cdh5.15.0 Subversion http://github.com/cloudera/hadoop -r e3cb23a1cb2b89d074171b44e71f207c3d6ffa50 Compiled by jenkins on 2018-05-24T11:19Z Compiled with protoc 2.5.0 From source with checksum 2efeda2e2d6b27ecf59ab56fffd9881 This command was run using /usr/lib/hadoop/hadoop-common-2.6.0-cdh5.15.0.jar # Source $ hadoop version Hadoop 2.6.0-cdh5.14.0 Subversion http://github.com/cloudera/hadoop -r 9b197d35839383c798c618ba917ccaa196a17699 Compiled by jenkins on 2018-01-06T21:38Z Compiled with protoc 2.5.0 From source with checksum f4ddee45985a34faa91db2aad8731f This command was run using /opt/cloudera/parcels/CDH-5.14.0-1.cdh5.14.0.p0.24/jars/hadoop-common-2.6.0-cdh5.14.0.jar # Target $ hadoop version Hadoop 3.0.0-cdh6.3.2 Source code repository http://github.com/cloudera/hadoop -r 9aff20de3b5ecccf3c19d57f71b214fb4d37ee89 Compiled by jenkins on 2019-11-08T13:49Z Compiled with protoc 2.5.0 From source with checksum f539c87da37534aad732f2a7ddcc59 This command was run using /opt/cloudera/parcels/CDH-6.3.2-1.cdh6.3.2.p0.1605554/jars/hadoop-common-3.0.0-cdh6.3.2.jar
以下のコマンドを使う
ソースとターゲットのHadoopのメジャーバージョンが変わらない場合
hadoop --config <target_conf_dir> distcp [DistCpオプション郡] \ hdfs://<source_nameservice>/<source_hdfs_path> \ hdfs://<target_nameservice>/<target_hdfs_path>
ソースとターゲットのHadoopのメジャーバージョンが異なる場合
hadoop --config <target_conf_dir> distcp [DistCpオプション郡] \ webhdfs://<source_nameservice>/<source_hdfs_path> \ hdfs://<target_nameservice>/<target_hdfs_path>
パラメータ | 説明 | 今回(クラスタB→クラスタC)の場合 |
---|---|---|
[DistCpオプション郡] |
-overwrite、 -pbなどのdistcpのオプション | (必要に応じて指定) |
--config target_conf_dir |
target側クラスタの hdfs-site.xml があるディレクトリへのフルパス ※ <target directory> が自分のクラスタ内なら不要 |
/etc/hadoop/conf.claster-c/ (予めクラスタCのクライアント設定を入れておく) |
<source_nameservice> |
以下のいずれか * source側サービス名 * source側のNNのFQDN:NN のポート番号 |
cluster-b cluster-b-namenode.example.com:50070 |
<target_nameservice> |
以下のいずれか * target側サービス名 * target側のNNのFQDN:NNのポート番号 |
cluster-c cluster-c-namenode.example.com:50070 |
※NN=NameNode
※サービス名=hdfs-site.xmlのプロパティdfs.nameservices
の値
今回(クラスタB→クラスタC)の場合の具体例
$ sudo -u user1 hadoop --config /etc/hadoop/conf.claster-c/ distcp -overwrite -pb \ hdfs://cluster-b/hoge_db/hoge_table/dt=20201210/ \ hdfs://cluster-c/hoge_db/hoge_table/dt=20201210/ $ sudo -u user1 hadoop --config /etc/hadoop/conf.claster-c/ distcp -overwrite -pb \ hdfs://cluster-b/hoge_db/hoge_table/dt=20201210/ \ webhdfs://cluster-c/hoge_db/hoge_table/dt=20201210/
注意点
hadoopコマンドを実行したユーザが、DistCpでターゲット側に生成されるファイルの所有権になるので注意
所属していないクラスタに対してhdfs dfsを使いたい場合
DistCpの場合とほぼ同じ。
クラスタAのクライアントから、クラスタCを参照したい場合は以下の様にする。
hdfs --config /etc/hadoop/conf.claster-c/ dfs -ls \ hdfs://cluster-c/hoge_db/hoge_table/dt=20201210/
※ /etc/hadoop/conf.claster-c/
にクラスタCの core-site.xml
が必要
さいごに
以上が出来るだろうなぁって放置してたTipsでした。
つまり、これを使えば、手元のPCからDocker使って、hadoopやhdfsコマンドを使ってリモートのクラスタの操作を行うことが出来ます。 今回の話は私が探した範囲では、ドキュメントには明示的に書いて無くて、CLIのヘルプにconfのオプションがあるくらいでそこから推測出来る程度の情報しか探せなかった。
# hadoop --help Usage: hadoop [OPTIONS] SUBCOMMAND [SUBCOMMAND OPTIONS] or hadoop [OPTIONS] CLASSNAME [CLASSNAME OPTIONS] where CLASSNAME is a user-provided Java class OPTIONS is none or any of: --config dir Hadoop config directory : # hdfs --help Usage: hdfs [OPTIONS] SUBCOMMAND [SUBCOMMAND OPTIONS] OPTIONS is none or any of: --buildpaths attempt to add class files from build tree --config dir Hadoop config directory :
以上、小ネタでした。