こんばんは。Hadoopによくパッチを投稿してる@ajis_kaです。早速ですがHDFS findコマンドについて紹介します。
Hadoop 2.6.0以前では使えない
現状の最新リリース(2.6.0)ではfindコマンドは存在せず、HDFS内のファイルを検索するためにはSolrを使う必要がありました。(参考:Cloudera Search HDFSFindTool)
Hadoop 2.7.0以降で使えるようになる
しかし、Hadoopの次のバージョン(2.7.0)からは、HDFS findコマンドが標準で使えるようになります。HADOOP-8989で開発されていましたが、チケットが登録されてから6年以上かかってようやくコミットされました。(自分でビルドしたtrunkの)ドキュメントによると、現時点では-name
, -iname
, -print
, -print0
オプションしか使えませんが、その他のオプションも追加されていく予定です。
- 正確に言うと、追加できるように開発がんばります。
Hadoop 2.6.0で使うための手順
Hadoop 2.7.0は今年中か、来年頭にリリースされると思いますが、待ちきれないせっかちな人のために、既にリリース済のHadoop 2.6.0にパッチを当てる手順を紹介します。(追記: Hadoop 2.5.2でも同じ手順でパッチ適用可能です)
- Downloadにアクセスして、hadoop-2.6.0-src.tar.gzをダウンロード、解凍して適当なディレクトリに配置する
- BUILDING.txtに従って、必要なライブラリをインストールする。Hadoop Wikiも参考にするとよい。
- パッチをダウンロードする。
- ダウンロードしてきたパッチを適用し、ビルドする。
$ cd hadoop-2.6.0-src
$ patch -p0 < /path/to/HADOOP-8989.patch
patching file hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/Command.java
Hunk #1 succeeded at 64 (offset -1 lines).
Hunk #2 succeeded at 122 (offset -1 lines).
Hunk #3 succeeded at 315 (offset -4 lines).
Hunk #4 succeeded at 326 (offset -4 lines).
patching file hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/CommandFactory.java
patching file hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/FsCommand.java
patching file hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/find/And.java
patching file hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/find/BaseExpression.java
patching file hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/find/Expression.java
patching file hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/find/ExpressionFactory.java
patching file hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/find/FilterExpression.java
patching file hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/find/Find.java
patching file hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/find/FindOptions.java
patching file hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/find/Name.java
patching file hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/find/Print.java
patching file hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/find/Result.java
patching file hadoop-common-project/hadoop-common/src/site/apt/FileSystemShell.apt.vm
Hunk #1 succeeded at 232 (offset 2 lines).
patching file hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/MockFileSystem.java
patching file hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestAnd.java
patching file hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestFilterExpression.java
patching file hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestFind.java
patching file hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestHelper.java
patching file hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestIname.java
patching file hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestName.java
patching file hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestPrint.java
patching file hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestPrint0.java
patching file hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/shell/find/TestResult.java
patching file hadoop-common-project/hadoop-common/src/test/resources/testConf.xml
Hunk #1 succeeded at 964 (offset 16 lines).
patching file hadoop-hdfs-project/hadoop-hdfs/src/test/resources/testHDFSConf.xml
$ mvn package -Pdist,native -Dtar -DskipTests
(以下略)
-
-Pdist,native
の部分は、-Pdist
のみでもよいです。(Native Libraryをビルドするかどうかの違い)
うまくいけば、hadoop-dist/target
配下にhadoop-2.6.0.tar.gz
が配置されているはずです。
-
だめだったら、必要な正しいバージョンのライブラリがインストールされているか確認しましょう。
-
Hint:
- Apache Mavenは3.0系ですか?
- Protocol Buffersは2.5.0ですか?
あとは、(今年になって書き直した)公式のマニュアルを見るか、昨年のAdvent Calendarの記事を参考にセットアップしてください。すると、あら不思議! findコマンドが使えるようになっているはずです。
# hadoop version
Hadoop 2.6.0
Subversion Unknown -r Unknown
Compiled by aajisaka on 2014-12-04T10:39Z
Compiled with protoc 2.5.0
From source with checksum e62c297fa67acce70172b70aa8d4f5a
This command was run using /usr/local/hadoop-2.6.0/share/hadoop/common/hadoop-common-2.6.0.jar
# hdfs dfs -ls .
Found 11 items
drwxr-xr-x - root supergroup 0 2014-11-13 00:17 .hiveJars
-rw-r--r-- 1 root supergroup 30 2014-11-12 22:54 airport.txt
drwxr-xr-x - root supergroup 0 2014-06-05 09:35 child
drwxr-xr-x - root supergroup 0 2014-06-05 09:35 child2
drwxr-xr-x - root supergroup 0 2014-06-06 02:18 dir1
drwxr-xr-x - root supergroup 0 2014-06-05 09:09 dir2
drwxr-xr-x - root supergroup 0 2014-06-06 03:31 dirToAggregate
-rw-r--r-- 1 root supergroup 284 2014-11-12 22:54 flight.txt
drwxr-xr-x - root supergroup 0 2014-06-17 11:39 sbin
-rw-r--r--+ 1 root supergroup 1749 2014-06-17 11:39 test
-rw-r-xr--+ 1 root supergroup 1749 2014-06-19 09:03 test2
# hdfs dfs -find / -name "dir*"
/user/root/dir1
/user/root/dir2
/user/root/dirToAggregate
相対パス指定だと、相対パスで出力されます。
# hdfs dfs -find . -name "dir*"
dir1
dir2
dirToAggregate
さらに、Hadoop 2.5.0から追加された、OfflineImageViewerのWebHDFS read-only REST APIと連携してみます。
# hdfs oiv -i fsimage_0000000000000004494
14/12/04 23:53:28 INFO offlineImageViewer.FSImageHandler: Loading 3 strings
14/12/04 23:53:28 INFO offlineImageViewer.FSImageHandler: Loading 171 inodes.
14/12/04 23:53:28 INFO offlineImageViewer.FSImageHandler: Loading inode references
14/12/04 23:53:28 INFO offlineImageViewer.FSImageHandler: Loaded 0 inode references
14/12/04 23:53:28 INFO offlineImageViewer.FSImageHandler: Loading inode directory section
14/12/04 23:53:28 INFO offlineImageViewer.FSImageHandler: Loaded 53 directories
14/12/04 23:53:28 INFO offlineImageViewer.WebImageViewer: WebImageViewer started. Listening on /127.0.0.1:5978. Press Ctrl+C to stop the viewer.
別ウィンドウを立ち上げて、findコマンドを実行してみます。
# hdfs dfs -find webhdfs://127.0.0.1:5978/ -name "dir*"
webhdfs://127.0.0.1:5978/user/root/dir1
webhdfs://127.0.0.1:5978/user/root/dir2
webhdfs://127.0.0.1:5978/user/root/dirToAggregate
なんと、起動しているNameNodeに全く負荷を与えることなく、検索することができました。