🐘

HDFSのcpの話

2021/06/06に公開

tl;dr

  • WebHDFSにはcpないよ
  • hadoopコマンドのcpでは、クライアントで読み取り・書き込みをしているよ

WebHDFS

ファイルをローカルからアップロード・ローカルにダウンロードするAPIはありますが、HDFS->HDFSのコピーのAPIはないようです。
StackOverflowの質問でも、「ないよ」の回答。)

hadoopコマンド

hadoop fsコマンドには-cpがあり、HDFS内のコピーに使えます。

hadoop fsコマンドのcpは何をしているか

  1. コピー元からデータを読み取り
  2. (一時ファイルに)書き込み
  3. 書き込み終了後、改名

をしているっぽいです。

メタデータのコピーだけかなーと思っていたのですが、実データを移動しているのは意外でした(障害の影響を抑えるためとかでしょうか)。

コードから見る

  • hadoop fs -cpに対応するのは、Cpクラス
  • 具体的な処理は親クラスのCommandWithDestinationcopyFileToTargetと、そこから呼ばれるcopyStreamToTarget
  • このメソッドでは前述の処理をしている
    • 入力のファイルを開く
    • ストリームで送り先(一時ファイル)に書き込み
    • 改名

ログから見る

HADOOP_ROOT_LOGGER環境変数を設定すると、クライアントの詳細が見れます

 HADOOP_ROOT_LOGGER=hadoop.root.logger=DEBUG,console hadoop fs -cp /hoge /dir1/

全部載せると結構長いのでそれっぽい箇所だけ載せます。

書き込み先の(一時)ファイル作成っぽいログ。

2021-06-06 21:46:54,123 DEBUG hdfs.DFSClient: /dir1/hoge._COPYING_: masked={ masked: rw-r--r--, unmasked: rw-rw-rw- }
2021-06-06 21:46:54,132 DEBUG ipc.Client: IPC Client (1118078504) connection to localhost/127.0.0.1:9000 from m-kimura sending #5 org.apache.hadoop.hdfs.protocol.ClientProtocol.create

データを送っているっぽいログ。

2021-06-06 21:46:54,275 DEBUG hdfs.DFSClient: WriteChunk allocating new packet seqno=0, src=/dir1/hoge._COPYING_, packetSize=65016, chunksPerPacket=126, bytesCurBlock=0, DFSOutputStream:block==null
2021-06-06 21:46:54,275 DEBUG hdfs.DataStreamer: Queued packet seqno: 0 offsetInBlock: 0 lastPacketInBlock: false lastByteOffsetInBlock: 5, block==null
2021-06-06 21:46:54,275 DEBUG hdfs.DataStreamer: Queued packet seqno: 1 offsetInBlock: 5 lastPacketInBlock: true lastByteOffsetInBlock: 5, block==null
2021-06-06 21:46:54,275 DEBUG hdfs.DataStreamer: block==null waiting for ack for: 1
2021-06-06 21:46:54,275 DEBUG hdfs.DataStreamer: stage=PIPELINE_SETUP_CREATE, block==null
2021-06-06 21:46:54,275 DEBUG hdfs.DataStreamer: Allocating new block: block==null
2021-06-06 21:46:54,285 DEBUG ipc.Client: IPC Client (1118078504) connection to localhost/127.0.0.1:9000 from m-kimura sending #7 org.apache.hadoop.hdfs.protocol.ClientProtocol.addBlock
2021-06-06 21:46:54,287 DEBUG ipc.Client: IPC Client (1118078504) connection to localhost/127.0.0.1:9000 from m-kimura got value #7
2021-06-06 21:46:54,287 DEBUG ipc.ProtobufRpcEngine2: Call: addBlock took 2ms
2021-06-06 21:46:54,290 DEBUG hdfs.DataStreamer: pipeline = [DatanodeInfoWithStorage[127.0.0.1:9866,DS-6d805980-8386-4e8c-b208-350ddb724092,DISK]], blk_1073741826_1002
2021-06-06 21:46:54,290 DEBUG hdfs.DataStreamer: Connecting to datanode 127.0.0.1:9866
2021-06-06 21:46:54,291 DEBUG hdfs.DataStreamer: Send buf size 146988

改名しているっぽい箇所。

2021-06-06 21:46:54,378 DEBUG ipc.Client: IPC Client (1118078504) connection to localhost/127.0.0.1:9000 from m-kimura sending #10 org.apache.hadoop.hdfs.protocol.ClientProtocol.rename

コピー前後のブロック

元ファイルとコピー先のファイルで、違うブロックになってそうです。

元ファイルのブロック(BP-385112196-127.0.0.1-1622983489754:blk_1073741825_1001)

hdfs fsck /hoge  -files -blocks -locations                                 
(略)
/hoge 5 bytes, replicated: replication=1, 1 block(s):  OK
0. BP-385112196-127.0.0.1-1622983489754:blk_1073741825_1001 len=5 Live_repl=1  [DatanodeInfoWithStorage[127.0.0.1:9866,DS-6d805980-8386-4e8c-b208-350ddb724092,DISK]]
(略)

コピー先のファイルのブロック(BP-385112196-127.0.0.1-1622983489754:blk_1073741826_1002)

hdfs fsck /dir1/hoge  -files -blocks -locations                       
(略)
/dir1/hoge 5 bytes, replicated: replication=1, 1 block(s):  OK
0. BP-385112196-127.0.0.1-1622983489754:blk_1073741826_1002 len=5 Live_repl=1  [DatanodeInfoWithStorage[127.0.0.1:9866,DS-6d805980-8386-4e8c-b208-350ddb724092,DISK]]
(略)

Discussion