Asakusa FrameworkのDirect I/Oの チューニングに関するメモ。
AsakusaFWにはトランザクションの考え(処理が成功したときだけファイルが出力され、失敗したときはファイルを出力しない(一部のファイルだけ出力されるというような中途半端な状態にしない))があり、出力ファイルは一旦一時ディレクトリーに保存し、最後に目的の場所へ移動させる仕組みになっている。
もし一時ディレクトリーと最終格納場所が異なるファイルシステムだったりすると、ファイルの移動に時間がかかってしまう。
MapRクラスターに出力するバッチで、以下のようなメッセージが出てファイル出力が遅くなることがあった。
16/12/10 20:47:04 INFO fs.MapRFileSystem: Cannot rename across volumes, falling back on copy/delete semantics
ファイル名を変更する(ファイルを移動する)処理だが、ボリュームが異なるのでcopy/deleteするよ、という事らしい。
MapRクラスターのデフォルトでは、全ての(ユーザー)データは同一ボリューム上に出力される。
が、ファイル数が多くなるとボリュームのメタデータが肥大化し、1台のサーバー上に保存できなくなるようだ(苦笑)
そこで、適当な単位でボリュームを分けるのだが、異なるボリュームへのファイル移動はcopy/deleteになるらしい。
AsakusaFWのDirect
I/Oでは、一時ディレクトリーはASAKUSA_HOME/core/conf/asakusa-resources.xmlのcom.asakusafw.directio.データソース.fs.tempdir
で指定する。
これが指定されていない場合、com.asakusafw.directio.データソース.fs.path
で指定されている場所の下の_directio_tempというディレクトリーになる。
例えばrootというデータソースを使って以下のような定義をしている場合、
asakusa-resources.xml | Exporter |
---|---|
<property> |
@Override |
Exporterの「root/result/category」という論理パスは、実際のパスは「/user/hishidama/data/result/category」になり、
トランザクション用の一時ディレクトリーは「/user/hishidama/data/_directio_temp」になる。
ここで、もし「/user/hishidama/data/_directio_temp」と「/user/hishidama/data/result」が別ボリュームだと、ファイルの移動はcopy/deleteになる。
なので、一時ディレクトリーを作成する場所をresultと同じ場所にしてやれば、同一ボリュームになるのでファイルの移動が速くなる。
一時ディレクトリーの場所を指定する方法 | <property> |
---|---|
論理パスを増やす方法 | <property> |
前者の方法だと、Exporterでresult以外の場所を指定したときに対処できなくなるので、後者の方法が良いと思う。
AsakusaFWにはトランザクションの考えがあり、出力ファイルは一旦ステージング領域に保存し、最後に目的の場所へ移動させる仕組みになっている。[2021-05-17]
しかし、例えば出力先がAmazon S3だと、ファイルの移動に時間がかかってしまう。
このため、ステージング領域に出力せず、最終出力先に直接ファイルを作ることも出来るようになっている。
<!-- Direct I/O settings for S3 --> <property> <name>com.asakusafw.directio.root.output.staging</name> <value>false</value> </property>
参考: Direct I/O ユーザーガイドのトランザクションの設定