Hadoopクラスタ間でデータを移動するdistcpについては実はHadoop2系で新しくなっており*1、いろいろ機能が増えている。
たとえば以下のようなコマンドが実行できる。
hadoop distcp -i -m 20 -pb -bandwidth 2 webhdfs://cluster.old.local/path/of/data/dir hdfs://cluster.new.local/path/of/data/dir
このコマンドラインには、従来のdistcpでは不可能だったふたつの変更が含まれている。
bandwidth
前は指定できなかったが、今は mapper あたりが使う帯域をMB/sec単位で指定できる。べんり。
webhdfs://
前はバージョンの異なるHadoopクラスタ間でdistcpする場合、新しいクラスタでdistcpを実行し、古いクラスタ(source側)のパスは hftp:// で指定しろ、というのが普通であった。
Hadoop2だとwebhdfsが使えるようになっているはずなので、これを使うがよい、ということになっているようだ。
なおいつものようにoza先生に教えてもらった。
@choplin @tagomoris “distcp webhdfs://secureCluster webhdfs://insecureCluster “ ができるようになってるはずです URL
2014-11-27 17:32:56 via YoruFukurou to @choplin
@tagomoris @choplin わたしの記憶が確かなら,昔は HftpFileSystem 経由でしか DistCp できなかったのですが,WebHdfsFileSystem が入ったおかげで HftpFileSystem はその役目を終えたという記憶があります.
2014-11-27 17:34:42 via YoruFukurou to @tagomoris
source側のデータ総量が大きくなっていると以下のような例外が出て失敗する状況になっており、大変困っていた。oza先生によるとhftpのglobのバグのように見える、とのことだった。
14/11/27 15:59:44 ERROR tools.DistCp: Exception encountered java.lang.NumberFormatException: For input string: "p" at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) at java.lang.Integer.parseInt(Integer.java:580) at java.lang.Short.parseShort(Short.java:118) at java.lang.Short.valueOf(Short.java:174) at java.lang.Short.valueOf(Short.java:200) at org.apache.hadoop.hdfs.web.HftpFileSystem$LsParser.startElement(HftpFileSystem.java:437) at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:509) at com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(AbstractXMLDocumentParser.java:182)
これが webhdfs:// を使うと何の問題もなく動いた。すばらしい。グレート。
*1:なおHadoop1系でも distcp2 と指定すれば使えるケースがあるようだ