Outline
HadoopのYARN上で色々なアプリを動かすことになったのでテスト環境を作ってみた。
今回はHDFSへのアクセスを、コマンドラインとJavaコードからの両方で実行してみる。
環境
メインマシン
実際に動かしているハード。
WebUIなどの動作確認に使う。
Client
OS: Ubuntu14.04 (AWS EC2)
Hadoop: 2.5.2
Java: 8
HDFSクラスタ
別記事を参照。
ここではNamenodeの必要な設定のみ記す。
OS: Ubuntu14.04 (AWS EC2)
ユーザー: ubuntu
IP: PublicIP, PrivateIP
Hadoop: 2.5.2
port: 全開放(22, 80, 8020, 8032, 8088, 50070が開いてればたぶん大丈夫)
ClientとHDFSクラスタは同じsubnetにいる。
事前準備
以下、clientでの操作を基本とする。
Clientへ各種インストール
# java
sudo add-apt-repository ppa:webupd8team/java -y
sudo apt-get update
sudo apt-get install oracle-java8-installer -y
# Hadoop
# めんどくさいのでHomeにそのまま置く
wget http://ftp.meisei-u.ac.jp/mirror/apache/dist/hadoop/common/hadoop-2.5.2/hadoop-2.5.2.tar.gz
tar zxvf hadoop-2.5.2.tar.gz
環境変数など設定
別記事の通りに、
- hadoop-env.sh
- /etc/profile
- core-site.xml
- hdfs-site.xml
を編集する。
HDFS側でのアクセス許可
そのままではクライアントに編集権限はない。(hdfs側で作った同じユーザー名だったら接続できたりする?)
そのため、特定フォルダの編集権限を変える必要がある。
# 今回はtestDirというところを操作する。
./hadoop-2.5.2/bin/hdfs dfs -mkdir /testDir
./hadoop-2.5.2/bin/hdfs dfs -chmod -R 777 /testDir
commandLine
コマンドはこちらを参照
http://hadoop.apache.org/docs/r2.5.2/hadoop-project-dist/hadoop-common/FileSystemShell.html
./hadoop-2.5.2/bin/hdfs dfs -put .bash_logout /testDir
こんな感じで通る。
確認は-ls
でもいいし、WebUIから見てもいい。
JavaCode
こちらに用意してみた。
https://github.com/uryyyyyyy/hadoopSample/tree/master/hdfsClient
# fatJarの生成
./activator assembly
# 実行
java -jar target/scala2.11/hdfsClient-assembly-1.0.jar hdfs://[PrivateIP]:8020/ /home/ubuntu/.profile /testDir/client.txt
で、該当フォルダを見るとファイルがアップロードされているはず。
コード解説
def getFileSystem(hdfsUrl: String):FileSystem = {
try {
val conf = new Configuration(false)
conf.set(CommonConfigurationKeysPublic.FS_DEFAULT_NAME_KEY, hdfsUrl)
conf.setInt(DFSConfigKeys.DFS_REPLICATION_KEY, 1)
FileSystem.get(URI.create(hdfsUrl), conf)
} catch {
case e:IOException => e.printStackTrace(); throw new RuntimeException()
}
}
Configurationインスタンスを作り、それに設定を入れていく(普通はcore-site.xmlとかをそのまま読み込ませると思う)
それ以外は見たらわかると思う。
ハマったところとか
メインマシンからだと繋がらない。
put: File /testDir/client.md._COPYING_ could only be replicated to 0 nodes instead of minReplication (=1). There are 1 datanode(s) running and 1 node(s) are excluded in this operation.
clientからだと繋がるから、
・ユーザーの問題(cleintはubuntu, メインマシンは自分用のユーザー)
・IPの問題(clientはPrivateIPで指定、メインマシンはPublicIPで指定)
だと思うけど、メインマシンは色々いじってるから調査する気にはなれなかった。
接続に失敗すると制御が返ってこない。
client側のnamenodeの接続先を間違えるとか、namenode、datanode間の通信が上手く行かない時に発生する。
60000㍉秒待たされたり、ひたすら再接続しに行ったりして、その間止めることが出来なかったりする。。。どうしようもなければterminalごと落としてるけど、いい方法あるのかな?
ファイル名はあるのにダウンロードできない
よく見ると該当ファイルの容量が0byteで中身が無かったりする。
これはnamenodeには届いたもののdatanodeに保存されなかった(replicationが足りないとか)の場合に起きるっぽい。
No FileSystem for scheme: hdfs
色々試した際に、Jar実行時にこのエラーが出た。
Exception in thread "main" java.io.IOException: No FileSystem for scheme: hdfs
fatJarを生成した際にhadoopのLibraryが不十分でhdfsの実装がないのが原因。hadoop-common
Libraryを入れると動くようになる。
まとめ
HDFSの操作は普通のファイル操作と同じようにできるので覚えやすい。