Gfarm

第2回 Gfarm を効率よく使う方法

2013.08.19

Gfarm の性能に関して、大きく分類すると 3 種類あります。メタデータ取得性能、メタデータ更新性能、ファイルの読み書き性能です。

それらの性能を考慮して、サーバの設定や構成を変えたり、クライアントからのアクセスパターンを変えることで、効率よく Gfarm を利用できます。

多数クライアントからの同時アクセス

多数のクライアントが同時に Gfarm にアクセスすることで、全体としてファイル読み書きの効率が良くなります。

クライアントが一つの場合、たくさん gfsd があったとしても、ほとんどの gfsd にはアクセスされないからです。複数のクライアントが同時にアクセスすれば、gfsd へファイルの読み書きアクセスを分散できます。

メタデータ取得と更新についても、一つのクライアントに比べて複数のクライアントが同時にアクセスするほうが、全体の効率が少し良いです。

マスター gfmd は一つですが、gfmd がクライアントへ応答中に、別のクライアントからの要求を受け付けて処理できるようになっているからです。また、一般的なアプリケーションは、ファイルアクセス以外の処理もしているはずだからです。

ジャーナルファイルの書き込み性能

gfmd は、専用のジャーナルファイルを利用していて、そこにメタデータ更新情報を一時的に保存します。(そのあと非同期でデータベースに保存します。)

メタデータ更新の性能を良くするには、ジャーナルファイル保存場所として、なるべく性能が良いストレージを指定します。

特に、小さいサイズのファイルを大量に保存する場合は、この性能が影響します。

gfmd.conf の metadb_journal_dir で保存場所を変更できます。

ライトキャッシュメモリとバッテリバックアップを持つ RAID コントローラを使用すれば、特にメタデータ更新性能が良くなります。

/dev/shm などの RAMDISK 領域にジャーナルファイルを置いてもメタデータ更新性能が良くなりますが、サーバマシンの停電などで情報を失ってしまいます。

ジャーナルファイル書き込み時に fdatasync() 命令が使われています。fdatasync() の性能が良いと、Gfarm のメタデータの更新性能も良くなります。

dd コマンドを使って、fdatasync() 相当の性能を調査できます。

1 秒あたりの fdatasync() 相当の実行回数を測定する方法(例):

$ cd /ジャーナルファイルを置く予定のディレクトリ(ストレージ)
$ dd if=/dev/zero of=testfile oflag=dsync count=30000 bs=512
30000+0 records in
30000+0 records out
15360000 bytes (15 MB) copied, 3.03969 s, 5.1 MB/s
$ rm testfile
$ bc -l
30000/3.03969
9869.42747451220354707223

この値が大きければ、Gfarm のメタデータ更新性能が良いことになります。

同期スレーブ gfmd の有無

メタデータ更新性能に影響するのは、ジャーナルファイル保存場所の性能だけでなく、同期スレーブ gfmd の有無も関係します。

マスター gfmd とスレーブ gfmd 間のメタデータ転送方法として、同期にするか、非同期にするかどうかを指定できます。gfmdhost コマンドの -C オプションでクラスタ名を指定し、マスター gfmd と同じクラスタ名のスレーブ gfmd が同期スレーブ gfmd になります。マスター gfmd は、同期スレーブ gfmd にメタデータ情報の転送が成功してからクライアントへ応答するので、メタデータ更新性能に影響します。

同期スレーブ gfmd が必要な場合は、マスター gfmd と、ネットワーク的になるべく近い位置に置きます。

同期スレーブ gfmd を設置しなければ、性能を重視できます。

同期スレーブ gfmd が無い場合には、メタデータを定期的にバックアップしておく必要があります。マスター gfmd のメタデータを保存しているディスクが故障した場合は、バックアップデータから復旧することになります。

非同期スレーブ gfmd を設置しても、メタデータ更新性能に影響ありません。

メタデータをバックアップするには、RAID によるミラーリングや、非同期スレーブ gfmd のメタデータを使うか、gfdump.postgresql コマンドで定期的に別ディスクや別のサーバへダンプします。

アクセス頻度

Gfarm に対するアクセスが多すぎる場合は、アプリケーションからGfarm 上ファイルへのアクセス頻度を必要十分に減らすことを検討してください。

例えば、頻繁に読むファイルが今後更新されないことがわかっていれば、何度も Gfarm 上のファイルを読みにいかないようにします。

例えば、一時ファイルを Gfarm 上に作成するのは無駄です。

例えば、大量の小さなファイルを一つのファイルにまとめてから Gfarm へ書き込めば、メタデータ更新回数が減ります。

ローカル I/O を使う

ファイル実体が保存されている gfsd と同じホスト上の Gfarm クライアントを使ってファイルを読み書きすると「ローカル I/O」となり、ネットワークで通信せずに読み書きできます。そうでなければ、通信して読み書きする「リモート I/O」となります。

特に、ファイルがとても大きい場合は、ファイルを持ってくるより、実行ファイル (アプリケーション自体) を、目的のファイル実体が保存されたホストへ転送し、そこで実行したほうが効率が良いということがわかります。

ローカル I/O を利用するには、全ての gfsd ホストで、Gfarm コマンドや gfarm2fs などの Gfarm クライアントを利用できるようにしておきます。あらかじめ gfarm2fs でマウントしておくか、ジョブ投入時にマウントするようにします。

gfsched コマンドを使えば、読み書きするのに効率が良いホスト名が推奨されます。

ファイルを読む場合
$ gfsched -f ファイル名

ファイルに書く場合
$ gfsched -w -f ファイル名

新規にファイルを作成する場合
$ gfsched -w

gfsched によって推奨されたホストに対して ssh などでアプリケーションをリモート実行することで (さらにそれを並列に実行することで)、効率良く読み書きできます。

gfmd とクライアントとの距離

gfmd とクライアントが距離的に離れていると、メタデータの取得性能と更新性能が低下します。

クライアントと gfmd との距離が原因でメタデータアクセス性能がネックとなっていて、意図的にクライアントの位置を変えことができるのであれば、なるべく gfmd に近いクライアントを利用すると、性能を改善できるかもしれません。

メタデータアクセスよりも、ファイル読み書き時の通信がネックとなっている場合は、前述のローカル I/O を使用します。

gfpcopy コマンドを使う

ローカル I/O を使えない場合や、多数のファイルをコピーする場合は、gfpcopy コマンドを使えば、gfarm2fs 上でファイルを cp するよりも高速にコピーできます。

gfpcopy は、Gfarm からローカルファイルシステムにコピーすることも、ローカルファイルシステムから Gfarm にコピーすることもできます。単一ファイルのコピー、または指定したディレクトリをまるごとコピーできます。

gfpcopy は並列処理を行っています。並列にメタデータを取得したり、ファイルごとに別々の gfsd に同時に読み書きします。-j オプションで並列度を変更できます。

しかし、gfpcopy で Gfarm にコピーする場合は、空き容量が大きい gfsd ホストへ優先的に書き込むので、クライアントから遠くの gfsd にコピーする可能性があります。

遠くの gfsd にコピーしてしまい、コピー性能が気になる場合には、gfpcopy に -D や -H オプションを使用して、近い gfsd ホスト群を指定します。-D オプションを指定せずに、gfarm2.conf のwrite_target_domain にドメイン名を指定することもできます。

Gfarm API (libgfarm) を直接使ってプログラムを記述

たくさんの Gfarm コマンドをシェルスクリプトなどで組み合わせて利用すると、動作がとても遅くなることがあります。各 Gfarm コマンドは、コマンドを実行するたびに、ユーザ認証などの初期化処理を行いますが、それが高コストだからです。

また、gfarm2fs 上でファイル操作を行うと、FUSE の仕組みがファイルアクセス性能のネックとなることがあります。

そこで、Gfarm API を直接利用してアプリケーションを作成すれば、効率よく Gfarm にアクセスできます。

Gfarm API は、各 Gfarm コマンドや、gfarm2fs で使われています。

gfarm2fs に FUSE の kernel_cache オプション

一旦作成したファイルの内容が更新されないことが前提であれば、FUSE の kernel_cache オプションを gfarm2fs に指定することができます。kernel_cache オプションを使用すると、ファイルの同じ位置を二回以上読む場合に、キャッシュの効果があれば、高速に読むことができます。

著者プロフィール

takuya

プログラミングが好きです。でも、ラーメンのほうがもっと好きです。

記事一覧Index