非同期I/Oの謎
<非同期I/Oの謎>
ペンネーム: ベロ
明けましておめでとうございます。
今回は、以前のメルマガの補足検証となります。(どうしてもメルマガにて公開しておき
たかったので、無理を言って公開させてもらいました)
以前、弊社メルマガ(ASMLibに関する検証 その6 *1)にてASMLibの非同期I/Oに関する検証
を行っていました。そこで、各プロセスがファイルをオープンする際のモードおよび
ファイルの読み込み、書き込みのファンクションをトレースしています。また、検証用の
簡単なCのコードも掲載していました。
*1) https://old.insight-tec.com/mailmagazine/ora3/vol421.html
一部、読者の方から「この検証結果では分かりづらい」「そもそも非同期I/Oとは?」など
ご意見を頂きましたので、振り返って、Oracleの非同期I/Oの動作について再検証を行い
ました。
検証環境は以下の通りです。
OS: Oracle Enterprise Linux 5.5 (64bit)
Oracle: Oracle 11.2.0.1 Enterprise Edition (64bit)
* 今回の検証はLinux限定の検証です
まず、OS(libaioライブラリを含む)による非同期I/Oがどのように動作しているか簡単な
コードで確認します。
今回確認用に使用したソースはLinux Foundationにあるaiocp(*2)を使用しました。
*2) http://devresources.linuxfoundation.org/daniel/AIO/aiocp.c
aiocpの処理内容はざっと以下の通りです。
1. コピー元ファイルのopen 2. コピー先ファイルのopen 3. 1に対してreadを非同期I/Oで要求し、その完了をコールバック関数で待ち受ける 4. 3のread要求が完了した場合、コールバック関数が呼ばれ、さらに2に対して非同期で write要求が発行される 5. write要求も完了時にはコールバック関数が呼ばれる 6. 全てのread/writeの要求が発行された場合、その完了を待って終了
* libaio経由のI/Oはio_submit(2)とio_getevents(2)となります
つまり、処理の重いwriteの間に処理の軽いreadを多く発行させて、全体のスループット
を上げることを期待したサンプルと言えます。以下、本当にそうなっているか確認して
みます。
1. aiocpのソースを取得してコンパイルします。
$ wget http://devresources.linuxfoundation.org/daniel/AIO/aiocp.c $ gcc -laio -o aiocp aiocp.c
2. コピー元ファイルの作成
$ dd if=/dev/zero of=srcfile bs=1M count=10
* 今回は、10MBのファイルを別ファイルにコピーするテストを実施します。その際の ブロックサイズはOracleのブロックサイズと合わせ8KBとしました。
3. ファイルのオープンモードにO_SYNCとO_CREATを付与して実行
$ time ./aiocp -d -b 8K -f O_SYNC -f O_CREAT srcfile dstfile real 0m1.360s user 0m0.002s sys 0m0.123
4. ファイルのオープンモードにO_SYNC、O_DIRECTとO_CREATを付与して実行
$ time ./aiocp -d -b 8K -f O_SYNC -f O_DIRECT -f O_CREAT srcfile dstfile real 0m0.403s user 0m0.000s sys 0m0.061s
なぜ、2種類のテストを実施したかというと、libaioによる非同期I/OはO_DIRECTが付与
された場合のみ実行されます。なので、O_DIRECTオプションの有無でaiocpの実行速度
が異なっているわけです。
では、Oracleでは、このファイルのオープンモード(ファイルシステムに対して)とI/O
の制御はどこで行われているか?
これは、filesystemio_optionsで制御されています。(デフォルトはnoneとなっていま
す) filesystemio_optionsはnone|directio|asynch|setallから選択します。
none: ファイルのオープンモードは変更しない(かつlibaio経由のシステムコール を発行しない) directio: ファイルのオープンモードはO_DIRECTが付与される。libaio経由のシステム コールは発行しない asynch: ファイルのオープンモードはnoneと同一。libaio経由のシステムコールが 発行される setall: ファイルのオープンモードはO_DIRECTが付与される。かつlibaio経由のシス テムコールが発行される * 各オプションによるファイルのオープンモードやシステムコールの差異はstrace コマンドをdbwrプロセス等にかけてみることで確認できます。
以下のブログに詳細を記載しています。
http://kojishinkubo.blogspot.com/2010/09/unbreakable-enterprise-kernelio.html
ここで、最初にテストしたaiocpコマンドの結果を思い出してみましょう。
非同期I/Oが実行されるのはlibaio経由のシステムコール(io_submit(2)とio_getevents(2))
を使用する。かつファイルのオープンモードがO_DIRECTとなっていること。でした。
ということで、ファイルシステムを利用中で、dbwr/lgwrの書き込みスループットを上げ
たい場合には、filesystemio_optionsをsetallにしないと効果なしと言えそうです。
昨年からのもやもやが解消! 恵比寿より