🌐
WebHDFSのファイル作成とHadoop HA
ドキュメントに(多分)書いていない挙動を見つけたのでメモです。
tl;dr
- WebHDFSのファイル作成(op=CREATE)は、StandbyのNameNodeにもリクエストできるよ
- ファイル読み取り(op=OPEN)や一覧(op=LISTSTATUS)はActiveにリクエストする必要があるよ
WebHDFSとは
HDFSに対し、REST(-ful)なAPIでアクセスするインターフェイスです。
HAとは
HA時のWebHDFSの挙動
AWS EMR(emr-6.4.0、Hadoop 3.2.1)を「複数のマスターノード」で起動し、試してみました。
他の操作
ファイル読み取り(等)はActiveに投げる必要があります。
アクティブに投げた時
curl "http://[アクティブNameNode]:9870/webhdfs/v1/?op=LISTSTATUS"
{"FileStatuses":{"FileStatus":[
{"accessTime":0,"blockSize":0,"childrenNum":1,"fileId":16386,"group":"hdfsadmingroup","length":0,"modificationTime":1636195142276,"owner":"hdfs","pathSuffix":"apps","permission":"755","replication":0,"storagePolicy":0,"type":"DIRECTORY"},
{"accessTime":0,"blockSize":0,"childrenNum":2,"fileId":16388,"group":"hdfsadmingroup","length":0,"modificationTime":1636195142452,"owner":"hdfs","pathSuffix":"tmp","permission":"1777","replication":0,"storagePolicy":0,"type":"DIRECTORY"},
{"accessTime":0,"blockSize":0,"childrenNum":3,"fileId":16395,"group":"hdfsadmingroup","length":0,"modificationTime":1636195142536,"owner":"hdfs","pathSuffix":"user","permission":"755","replication":0,"storagePolicy":0,"type":"DIRECTORY"},
{"accessTime":0,"blockSize":0,"childrenNum":1,"fileId":16399,"group":"hdfsadmingroup","length":0,"modificationTime":1636195142549,"owner":"hdfs","pathSuffix":"var","permission":"755","replication":0,"storagePolicy":0,"type":"DIRECTORY"}
]}}
スタンドバイに投げた時
curl "http://[スタンドバイNameNode]:9870/webhdfs/v1/?op=LISTSTATUS"
{"RemoteException":{"exception":"StandbyException","javaClassName":"org.apache.hadoop.ipc.StandbyException","message":"Operation category READ is not supported in state standby. Visit https://s.apache.org/sbnn-error"}}
ファイル作成(op=create)
ファイル作成はStandbyに投げても受理されます。
curl -v -X PUT -L "http://[スタンドバイNameNode]:9870/webhdfs/v1/tmp/webhdfs_test_file?op=CREATE" -t test_file
* Trying 172.31.0.41:9870...
* Connected to [スタンドバイNameNode] (172.31.0.41) port 9870 (#0)
> PUT /webhdfs/v1/tmp/webhdfs_test_file?op=CREATE HTTP/1.1
> Host: ec2-54-174-138-73.compute-1.amazonaws.com:9870
> User-Agent: curl/7.76.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 307 Temporary Redirect
< Date: Sat, 06 Nov 2021 10:59:12 GMT
< Cache-Control: no-cache
< Expires: Sat, 06 Nov 2021 10:59:12 GMT
< Date: Sat, 06 Nov 2021 10:59:12 GMT
< Pragma: no-cache
< X-Content-Type-Options: nosniff
< X-FRAME-OPTIONS: SAMEORIGIN
< X-XSS-Protection: 1; mode=block
< Location: http://ip-172-31-0-150.ec2.internal:9864/webhdfs/v1/tmp/webhdfs_test_file?op=CREATE&namenoderpcaddress=ha-nn-uri&createflag=&createparent=true&overwrite=false
< Content-Type: application/octet-stream
< Content-Length: 0
<
* Connection #0 to host ec2-54-174-138-73.compute-1.amazonaws.com left intact
* Issue another request to this URL: 'http://ip-172-31-0-150.ec2.internal:9864/webhdfs/v1/tmp/webhdfs_test_file?op=CREATE&namenoderpcaddress=ha-nn-uri&createflag=&createparent=true&overwrite=false'
* Trying 172.31.0.150:9864...
* Connected to ip-172-31-0-150.ec2.internal (172.31.0.150) port 9864 (#1)
> PUT /webhdfs/v1/tmp/webhdfs_test_file?op=CREATE&namenoderpcaddress=ha-nn-uri&createflag=&createparent=true&overwrite=false HTTP/1.1
> Host: ip-172-31-0-150.ec2.internal:9864
> User-Agent: curl/7.76.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 100 Continue
* Mark bundle as not supporting multiuse
< HTTP/1.1 201 Created
< Location: hdfs://ha-nn-uri/tmp/webhdfs_test_file
< Content-Length: 0
< Access-Control-Allow-Origin: *
< Connection: close
<
* Closing connection 1
ActiveのNameNode・DataNodeにはログがあります(StandbyのDataNodeにはない)
NameNode
grep "webhdfs_test_file" /var/log/hadoop-hdfs/*
/var/log/hadoop-hdfs/hadoop-hdfs-namenode-ip-172-31-0-7.log:2021-11-06 10:59:12,181 INFO org.apache.hadoop.hdfs.StateChange (IPC Server handler 19 on default port 8020): DIR* completeFile: /tmp/webhdfs_test_file is closed by DFSClient_NONMAPREDUCE_-1106891656_40
DataNode
grep webhdfs_test_file /var/log/hadoop-hdfs/*
/var/log/hadoop-hdfs/hadoop-hdfs-datanode-ip-172-31-0-150.log:2021-11-06 10:59:12,181 INFO datanode.webhdfs (nioEventLoopGroup-3-3): 172.31.0.7 PUT /webhdfs/v1/tmp/webhdfs_test_file?op=CREATE&namenoderpcaddress=ha-nn-uri&createflag=&createparent=true&overwrite=false 201
ファイル作成ではStandbyにリクエストできるわけ
ファイル作成の場合、最初にリクエストを受け付けたNameNodeでは処理をせず、以下の流れで処理を行います。
この時、クライアントが最初にリクエストするNameNodeと、DataNodeが通知するNameNodeが異なっても良いため、最初にリクエストするNameNodeはActiveでなくても良いようです。
- (クライアント)NameNodeにリクエスト
- (NameNode)適当なDataNodeを選び、そのURLをリダイレクトレスポンスとして返す
- (クライアント)リダイレクトに従い、DataNodeにリクエスト
- (DataNode)ファイルの作成
- (DataNode)作成したファイルの情報をNameNodeに通知
- (NameNode)作成したファイルの情報を記録
コード
- NameNodeのop=CREATE受付
- DataNodeのop=CREATE
-
DFSClient#createを経由して、DFSOutPutStream#newStreamForCreateでNameNodeのcreateを呼び出し
- (なお、この呼出はWebHDFSではなくRPCです)
- データを書き込み
-
closeImplとcompleteFile
経由して、NameNodeのcompleteを呼び出し
Discussion