[WYSIWYGԽ]

Solaris で擬似ファイルシステムをつくろう/其の3(HDFSファイルシステム)

目次

ご注意

ここで紹介しているプログラムは、カーネルモジュールを含んでいます。そのため、プログラム上に問題があった場合(可能性大)にはシステムが PANIC し、場合によってはファイルシステムに重大な障害を引き起こす可能性があります。以下のプログラムはテストプログラムで、十分な検証を行ってはいません。したがってあくまで個人の検証ためにお使いいただき、重要なシステム上では動作させないでください。本プログラムの使用により発生したトラブルなど、いかなる損害についても一切の責任を負いかねます。ご利用は自己責任にてお願いいたします。

概要

HadoopHDFS を Solaris 上でマウント可能にする Solaris 用のファイルシステム・モジュールとユーザモードプログラムです。
NFS の様に HDFS をマウントすることができ、一度マウントしてしまえば HDFS 上のディレクトリを cd コマンドで行き来したり、HDFS 上のファイルをローカルファイルの様にオープンして読み込んだり、実行可能ファイルを実行したりできます。また新規ファイルの作成と、追加書き込みもサポートしています。

※ 同様のことが行える FUSE (Filesystem in userland) というものがあります。本気で HDFS をマウントして活用したい!と思っている方はこちらを試したほうが良いかもしれません。(安全と言う意味で)・・・しかしながら、自分の環境ではビルドできなかったので私自身は試せてません(泣)うまくいった方がいたら教えてください。速度比較してみたいです。

ソースファイルとダウンロード

管理の利便性からソースコードはGithub に移動いたしました。
今後はこちらにアップデートしていきます。ソースコードもこちらからご参照いただけます。(最終更新日 2011/06/08)

ファイルシステムモジュールのソースファイルのダウンロード
iumfs.tar.gz
ユーザモードデーモンプログラムのソースファイルのダウンロード
iumfs-hdfs.tar.gz
ソースコードの参照
http://github.com/kaizawa/iumfs
http://github.com/kaizawa/iumfs-hdfs

Github へのコードの配置にともない文字コードを UTF-8 に切り替えました

動作確認済み Solaris バージョン及びプラットフォーム

このプログラムの動作確認状況は以下のようになっています。

プラットフォーム
Solarisバージョン
Sparc
(32bit)
Sparc
(64bit)
x86x64
Solaris10-??
OpenSolaris-?
OpenIndiana 148-??
Solaris11 express-??
Solaris11-??

○:動作確認済み ×:動作不可 ?:未確認 -:該当なし

プログラムの解説

基本的な考え方は「Solaris で擬似ファイルシステムをつくろう/其の2」の FTP ファイルシステムと同じで、このプログラムはカーネルモジュールであるファイルシステムモジュール兼仮想デバイスドライバと、Java のユーザモードプログラムで構成されています。

iumfs ファイルシステムモジュール

ファイルシステムとしての基本的な枠組みは「Solaris で擬似ファイルシステムをつくろう/其の2」と同じです。
モジュールのファイル名は「iumfs」ですが、カーネルに登録するファイルシステムの名称は「hdfs」です。

iumfscntl デバイスドライバ

こちらも基本的には「Solaris で擬似ファイルシステムをつくろう/其の2」と同じです。
ただ、今回は Java プログラムからアクセスされることを考えて mmap(2) を使ったデータのやりとりをやめ、read(2)、 write(2) だけでデータのやり取りができるように変更しています。また、Java プログラムとのデータの受け渡しが容易になるように、構造体を簡素化し、各メンバのサイズを8の倍数バイトとしています。

hdfsd ユーザモードデーモンプログラム

hadoop の API を使って HDFS の各データノードからファイルデータを読み込む java で書かれたプログラムです。
このプログラムは起動時に /dev/iumfscntl デバイスをオープンして、カーネル上のファイルシステムモジュールからのリクエストを待ちます。デバイスドライバを通じてファイルデータや属性情報の読み込み要求がくると、hadoop の API を使って HDFS 上のファイルデータや属性情報を取ってきます。取得したデータは再度 /dev/iumfscntl デバイスを通じてファイルシステムモジュールに渡します。この Java プログラムは nio の ByteBuffer を使って /dev/iumfscntl デバイスのからのデータの読み書きを実現しています。JNI は使ってません。(ちょっとこだわり)

iumfs ファイルシステム用 mount コマンド

iumfs ファイルシステム専用の mount コマンドです。
其の2とほぼ同じでものです。mount(1M) コマンドが自動的にこのコマンドを見つけて呼び出してくれるため、ユーザはこの iumfs 専用の mount コマンドの存在を意識する必要はありません。ただ -F オプションに「iumfs」を渡し、ファイルシステムを指定すればよいだけです。

実行環境の要件

このプログラムのコンパイル、及び実行時には以下の要件が満たされている必要があります。

  1. Solaris/OpenSolaris(動作確認済み Solaris バージョン)
  2. JDK6 がインストールされている(JRE5.0以前は動作確認してません)
  3. hadoop 0.21.0(以降)がインストールされていて、正常に動作している(※)
  4. HADOOP_HOME 環境変数に Hadoop のインストールディレクトリがセットされている

(※)ここでは説明しきれないので Hadoop のセットアップ方法や動作確認方法は他のサイトの情報をご活用ください。

インストール

コンパイル&インストール

カーネルモジュールと mount コマンド

ファイルシステムモジュールのダウンロードファイルを解凍し、configure, make を実行すると環境に応じて 64bit/32bit のファイルシステムモジュール兼、擬似デバイスドライバであるiumfs モジュールと、mount コマンドが作成されます。コンパイル終了後、make install にてファイルのコピーと、ファイルシステムモジュールのカーネルへのロードが行われます。
OpenSolaris での実行例:

$ cd kaizawa-iumfs-4f1da99
$ ./configure
checking for gcc... no
checking for cc... cc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C compiler... no
checking whether cc accepts -g... yes
checking for cc option to accept ISO C89... none needed
checking for a BSD-compatible install... /usr/bin/ginstall -c
checking for isainfo... yes
configure: creating ./config.status
config.status: creating Makefile
$ make
cd module ; make
gcc -c -DPACKAGE_NAME="IUMFS" -DPACKAGE_TARNAME="iumfs" -DPACKAGE_VERSION="0.1" -DPACKAGE_STRING="IUMFS 0.1.2" 
-DPACKAGE_BUGREPORT="admin2@whiteboard.ne.jp" -g -O2 -Wall -DOPENSOLARIS -DSOL10 -m64 -mcmodel=kernel 
-mno-red-zone -D_KERNEL -I. iumfs_vfsops.c -o iumfs_vfsops.o
gcc -c -DPACKAGE_NAME="IUMFS" -DPACKAGE_TARNAME="iumfs" -DPACKAGE_VERSION="0.1" -DPACKAGE_STRING="IUMFS 0.1.2"
 -DPACKAGE_BUGREPORT="admin2@whiteboard.ne.jp" -g -O2 -Wall -DOPENSOLARIS -DSOL10 -m64 -mcmodel=kernel
 -mno-red-zone -D_KERNEL -I. iumfs_vnops.c -o iumfs_vnops.o
:

※ 表示の都合上、一部改行してるところがあります

# make install
cd module ; make install
/bin/ginstall -c -m 0644 -o root -g sys iumfs /kernel/fs/amd64
/bin/ginstall -c -m 0644 -o root -g sys iumfs.conf /usr/kernel/drv
 :	

※ ここだけ root 権限が必要です!

ユーザモードデーモン

ユーザモードデーモンプログラムのダウンロードファイルにはユーザモードデーモンである hdfsd.jar ファイルが含まれていますので、そのままでも実行することができます。もし、Java コードに変更等を行って再コンパイルしたい場合には "cmd" ディレクトリで ant を実行すると Java のプログラムがコンパイルされ jar ファイルが作成されます。なお、ant 実行の際には HADOOP_HOME 環境変数が設定されている必要があります。$HADOOP_HOME は hadoop がインストールされているディレクトリです。

$ export HADOOP_HOME=/usr/local/hadoop
$ export JAVA_HOME=/usr/java
$ cd cmd
$ ant
Buildfile: build.xml

compile:
   [javac] Compiling 12 source files to /var/tmp/hdfs/cmd/build

dist:
     [jar] Building jar: /var/tmp/hdfs/cmd/hdfsd.jar

BUILD SUCCESSFUL
Total time: 2 seconds			  						  

アンインストール

ファイルシステムモジュールおよびコマンドのアンインストールは make uninstall で行います。
もし、インストール時に利用した Makefile がすでに無い場合も、以下のログを参考に各コマンドをマニュアルで実行していただければ同じ結果を得られます。

# make uninstall

※ root 権限が必要です

hdfs ファイルシステムが利用中(マウントされている)の場合、ファイルの削除は可能ですが、モジュールのアンロードは失敗します。この場合システムのリブート後に完全に削除されます。

使い方

hdfs ファイルシステムの利用方法についてご説明します。

※ hadoop のネームノード、データノードは予め起動されている必要があります!!

既存ファイルへの追記(Append)を有効にするためには ${HADOOP_HOME}/conf/hdfs-site.xml ファイルに以下のように dfs.support.append プロパティを追記して HDFS を再起動する必要があります。

<property>
    <name>dfs.support.append</name>
    <value>true</value>
</property>

 このプロパティを設定しないで書き込み操作をすると I/O エラー(EIO)が返されて失敗してしまいます。

$ echo aaa >> hoge
-ksh: echo: write to 1 failed [I/O error

hdfsd デーモンの起動

hadoop 各データノードと通信を行う hdfsd デーモンを起動します。
実際にはこのデーモンの起動と、後述のファイルシステムのマウントの順番は逆でも大丈夫ですが、デーモンを起動していない状態でファイルシステムのマウントしたとしても HDFS 上のファイルは参照できませんし、cd コマンドや ls コマンドは待たされることになります。(現実装ではタイムアウトを設けてませんので、デーモンが起動されるまでずーと待ち続けます。もちろんコマンドをキャンセルすることはできます)
起動方法:
ユーザモードデーモンプログラムのダウンロードファイルを展開したディレクトリにある start-hdfsd.sh シェルスクリプトを実行します。

$ ./start-hdfsd.sh

若しくは、直接 hadoop コマンドを使って hdfsd を実行することもできます。

% ${HADOOP_HOME}/bin/hadoop -cp ${CLASSPATH} iumfs.hdfs.Main

$HADOO_HOME は Hadoop がインストールされているディレクトリです。
$CLASSPATH には最低でも以下の4つをパスを指定する必要があります。

  1. hdfsd.jar ファイルスのパス(ダウンロードファイルに含まれるデーモンプログラム)
  2. iumfs-daemon-core-xx.jar (ダウンロードファイルに含まれるライブラリ)
  3. hadoop-core-xxx.jar ファイルのパス ファイル(hadoop のメイン jar ファイル)
  4. hadoop の設定ファイルが置いてあるディレクトリ のパス

実行例:

$ hadoop -cp "./cmd/hdfsd.jar:./cmd/lib/iumfs-daemon-core-0.2.0.jar:/usr/local/hadoop/conf:\
/usr/local/hadoop/hadoop-core-1.0.2.jar" iumfs.hdfs.Main

※ 一般ユーザでも起動できるはずですが、もし権限不足で iumfscntl デバイスのオープンに失敗してしまったら、root ユーザで /devices/pseudo/iumfs@0:iumfscntl に読み込み権を与えてください。

また、java.util.Logger設定ファイルを用意して、起動時に java.util.logging.config.file プロパティでファイルパスを指定すればデバッグ出力が得られます。Hadoop API 自体のデバッグ情報に加え、hdfsd のデバッグ情報も得られます。

デバッグ実行例:

$ hadoop  -Djava.util.logging.config.file=cmd/log.prop -cp "./cmd/hdfsd.jar:./cmd/lib/iumfs-daemon-core-0.2.0.jar:\
/usr/local/hadoop/conf:/usr/local/hadoop/hadoop-core-1.0.2.jar" iumfs.hdfs.Main
2012/04/30 12:10:50 iumfs.ControlDevicePollingThread run
詳細レベル (低): Successfully open device.
2012/04/30 12:10:50 iumfs.ControlDevicePollingThread run
詳細レベル (低): Started
2012/04/30 12:10:50 iumfs.ControlDevicePollingThread run
詳細レベル (低): Successfully open device.
2012/04/30 12:10:50 iumfs.ControlDevicePollingThread run
詳細レベル (低): Started
2012/04/30 12:10:50 iumfs.ControlDevicePollingThread run
詳細レベル (低): Successfully open device.
2012/04/30 12:10:50 iumfs.ControlDevicePollingThread run
詳細レベル (低): Started
2012/04/30 12:10:50 iumfs.ControlDevicePollingThread run
詳細レベル (低): Successfully open device.
2012/04/30 12:10:50 iumfs.ControlDevicePollingThread run
詳細レベル (低): Started
:

※ 表示の都合上、途中で改行しています。

ファイルシステムのマウント

iumfs ファイルシステムのマウントには通常の mount(1M) コマンドを利用します。
マウント時にはファイルシステムタイプとして iumfs を指定し、NameNode 名とマウントを行う HDFS 上の元となるディレクトリ(ベースディレクトリ)と、マウントポイントを指定します。

使い方:

# /usr/sbin/mount -F iumfs hdfs://name_node/base_path mount_point
name_node
NameNode のホスト名
base_path
マウントをする HDFS 上のディレクトリのパスです。(「/」だけでもかまいません)
mount_point
hdfs ファイルシステムをマウントするローカルのマウントポイント

※ root 権限が必要です

以下に /mnt ディレクトリに HDFS (NameNode はnamenode.example.com) 上の /user/myname ディレクトリをマウントする例を示します。

# /usr/sbin/mount -F iumfs hdfs://namenode.example.com/user/myname  /mnt
                                 ^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^  ^^^^
                                 NameNode             ベース        マウントポイント

マウントの確認:

# /usr/sbin/mount
 :
 :
/mnt on hdfs://namenode.example.com/user/myname read/write/setuid/devices/dev=91c0004 on Wed Jun  8 00:41:35 2011

可能なファイル操作

ディレクトリの移動、ディレクトリエントリの参照

$ cd /mnt/
$ /bin/ls
inputs

各ファイルの属性情報の参照

$ /bin/ls -l
total 3
drwxr-xr-x   1 root     root           0 May 21 23:03 ./
drwxr-xr-x   1 root     root           0 May 21 23:03 ../
drwxr-xr-x   1 root     root           0 May 21 23:03 inputs/

ファイル属性のうち、ファイルタイプ、ファイルサイズ、ファイルの最終変更日時、あとパーミッションはオリジナルファイルの情報がそのまま反映されますが、ファイルのオーナー情報だけはリモートホスト側の実際のオーナーに関わらず常にroot:rootと表示されます。

ファイルの読み込み

$ cd inputs
$ cat file1
this is file1
this is file1
this is file1
this is file1
$

ファイルのコピー

HDFS からローカルディスクへ

$ cp file1 /var/tmp
$

ローカルディスクから HDFSへ

$ cp /etc/hosts /mnt

不可能な操作

open,creat,read,write,mkdir,rmdir,getdent,ulink,stat 以外のファイル操作はできません。hdfs ファイルシステム上のファイルに対してこれら以外の操作を行った場合はエラーが返されるか、全く無視されます。

ファイルのアクセス権の変更

$ chmod 777 file1
$ <-- エラーにはなりませんがアクセス権は変更されません

ファイルの更新日時を変更

$ <-- エラーにはなりませんがファイルの更新日は変更になりません

ファイルのオーナーを変更

$ chown nobody file1
$ <-- エラーにはなりませんがオーナーは root のママです。

ファイルシステムのアンマウント

hdfs ファイルシステムのアンマウントには通常の umount(1M) コマンドを利用します。

Usage: umount mount_point

    mount_point : ファイルシステムがマウントされているマウントポイント

他のファイルシステムでもおなじですが、だれかがそのファイルシステム上のファイルを利用中の場合には BUSY が返り、umount(1M) は失敗します。

アンマウントの成功例)

# umount /mnt
#

ファイルシステムが利用中である為にアンマウントが失敗する例)

# pwd
/mnt
# umount /mnt
umount: /mnt 使用中です。

今後の課題

  1. パフォーマンスの向上
    最初の読み込み時に dfs の copyToLocal と同程度の転送速度が出せるのが目標。(今回の変更でパフォーマンスが向上)

トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2022-01-03 (月) 20:23:26