🐘
HDFSのcpの話
tl;dr
- WebHDFSにはcpないよ
- hadoopコマンドのcpでは、クライアントで読み取り・書き込みをしているよ
WebHDFS
ファイルをローカルからアップロード・ローカルにダウンロードするAPIはありますが、HDFS->HDFSのコピーのAPIはないようです。
(StackOverflowの質問でも、「ないよ」の回答。)
hadoopコマンド
hadoop fsコマンドには-cpがあり、HDFS内のコピーに使えます。
hadoop fsコマンドのcpは何をしているか
- コピー元からデータを読み取り
- (一時ファイルに)書き込み
- 書き込み終了後、改名
をしているっぽいです。
メタデータのコピーだけかなーと思っていたのですが、実データを移動しているのは意外でした(障害の影響を抑えるためとかでしょうか)。
コードから見る
- hadoop fs -cpに対応するのは、Cpクラス
- 具体的な処理は親クラスのCommandWithDestinationのcopyFileToTargetと、そこから呼ばれる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