LoginSignup
5
7

More than 5 years have passed since last update.

HDFSに接続してみる

Last updated at Posted at 2015-09-23

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へ各種インストール

terminal
# 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側で作った同じユーザー名だったら接続できたりする?)
そのため、特定フォルダの編集権限を変える必要がある。

namenode_terminal
# 今回は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

client_terminal
./hadoop-2.5.2/bin/hdfs dfs -put .bash_logout /testDir

こんな感じで通る。

確認は-lsでもいいし、WebUIから見てもいい。

JavaCode

こちらに用意してみた。
https://github.com/uryyyyyyy/hadoopSample/tree/master/hdfsClient

client_terminal
# 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の操作は普通のファイル操作と同じようにできるので覚えやすい。

5
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
7