関口宏司のLuceneブログ

OSS検索ライブラリのLuceneおよびそのサブプロジェクト(Solr/Tika/Mahoutなど)について
<< Solrを使って専門用語抽出 | main | 日本語Wikipediaからの類義語辞書の自動生成 >>
Lucene コミット時の動作(翻訳)
Lucene インデックスのコミット時の動作について詳述されたメール(原文)を見つけたのでその翻訳を掲載しよう。メールそのものは、Lucene コミッターの Uwe 氏が最近の Java 9 のコミットによってディレクトリへの fsync() 動作がうまくいかなくなったことについて最近の Lucene コミュニティの状況について説明し、さらにはコミュニティに解決方法を問うたものとなっている。

最近の Java 9 のコミット (e5b66323ae45) がディレクトリへの fsync を破壊した件について

こんにちは。

Apache Lucene コミッターを代表して投稿します。Apache Lucene/SolrとElasticsearchの両方を先ごろテストしたところHotspotまわりを中心に問題が見つかったことはご存知かと思います。そこで、JDK 9のプレビュー版ビルド40を利用するよう自分たちのテストインフラを先日アップデートしました。これは主にJigsawまわりの問題を確認することが目的でしたが、いくら頑張ってもこのビルドでは問題が発生しないのです。

ところが残念ながらOpenJDK 9の最近のコミットでは問題が発生しており(http://hg.openjdk.java.net/jdk9/jdk9/jdk/rev/e5b66323ae45)、それに相当するのがhttps://bugs.openjdk.java.net/browse/JDK-8066915です。この問題に関連し、自分たちでもhttps://issues.apache.org/jira/browse/LUCENE-6169というスレッドを立てました。

まず現状を説明します。Apache Luceneは write once アプローチ(すべてのファイルで一度だけ書き込みが行われる)を使っています。Luceneの所定の「コミットポイント」で「コミット」する場合は一時的なファイル名に書き込み、それからこのファイル(およびすべての関連ファイル)でfsyncを実行する形になります。これはファイルチャネルではfc.force()をコールするだけ簡単です。このコミットの最終的な「パブリッシュ」は「Files.move(Path, Path, StandardCopyOption.ATOMIC_MOVE)」を使ったアトムのリネームで行われます。

この方法は停電のような大きな問題でもない限りうまくいきますが、そのような問題が発生すると、POSIX OSではリネーム処理が全く見えなくなる可能性があります。LinuxのMANページ(http://linux.die.net/man/2/fsync)にはすべてに以下の記述があります。

「fsync() のコールはファイルのあるディレクトリ内のエントリがディスクに書き込まれたことを必ずしも保証するものではない。そのため、ディレクトリのファイル記述子にも fsync() を明示する必要がある。」

基本的に、現在はApache Luceneでも以下の手順で同じことをしています。ディレクトリ上でFileChannel (READ用)をオープンし、 fc.force() をコールします。もちろん、(動作することは以前から分かっているものの)実際にはJava APIにこの記述がないため、われわれは「有利な推測」に基づいてこれを行うことになります。Windowsではうまくいかないなど(*)、IOExceptionの例外は必ず発生します。

そこで問題になるのが、前述のコミットではこのアプローチがOpenJDK 9のFileSystemExceptionでうまくいかないことです。FileSystemExceptionはディレクトリです。社外のLuceneリリースは(前述のように)例外をすべて受け入れるため大丈夫なのですが、テストインフラでは、少なくともLinuxとMacOSXでは動いてしまうのです。

最新のコードはhttp://goo.gl/vKhtsWにあります。

どうしてもサポートされているOSのディレクトリでfsyncができるようにしておきたいのです。前述のコミットを8u40や7u80のリリースには戻したくないのです。Java 9なら代替案を検討できるのですが。

  • Java 7やJava 8の既存のセマンティクスを残し、どうしてもFileChannelからREAD/WRITEをしたい場合は単純にエラーを発生させるのでしょうか?基盤OSとlibcはこのようにして処理を行っています。 ファイル、ディレクトリ、デバイスなど、ファイル記述子はどこでもオープンできますが、この記述子ではできない処理もあり、例外やエラーが発生する場合もあります。
  • ディレクトリをfsyncするための新しいAPIを追加する(どのファイルタイプでもおそらく可能)。Files.fsync(Path)のようにでしょうか? Windowsではディレクトリではこれがうまくいかないのでしょうか?上記のリンクにあるIOUtils.fsync()のような形です。

意見や対応方法に関するアドバイスを下さい。

Uwe

*)ただ、このファイルシステムのセマンティクスはファイルが確実に見えるようにしているため、実際のところは問題ではありません。話がちょっとそれます(ディレクトリを読み込み用に開くと「Access Denied」がJava IOExceptionにマッピングされますが、これは全く問題ありません)。

| 関口宏司 | Luceneクラス解説 | 10:27 | comments(0) | trackbacks(0) |









http://lucene.jugem.jp/trackback/481
+ Solrによるブログ内検索
+ PROFILE
   1234
567891011
12131415161718
19202122232425
262728    
<< February 2017 >>
+ LINKS
検索エンジン製品 - 比較のポイント
商用検索エンジンを購入した企業担当者は読まないでください。ショックを受けますから・・・
>>製品比較 10のポイント
+ Lucene&Solrデモ
+ ThinkIT記事
+ RECOMMEND
Apache Solr入門 ―オープンソース全文検索エンジン
Apache Solr入門 ―オープンソース全文検索エンジン (JUGEMレビュー »)
関口 宏司,三部 靖夫,武田 光平,中野 猛,大谷 純
+ RECOMMEND
Lucene in Action
Lucene in Action (JUGEMレビュー »)
Erik Hatcher,Otis Gospodnetic,Mike McCandless
FastVectorHighlighterについて解説記事を寄稿しました。
+ RECOMMEND
+ SELECTED ENTRIES
+ RECENT COMMENTS
+ RECENT TRACKBACK
+ CATEGORIES
+ ARCHIVES
+ MOBILE
qrcode
+ SPONSORED LINKS