2009-06-03 2 views
12

私たちは企業Webアプリケーション用の検索アーキテクチャを設計しています。 Lucene.netを使用しています。インデックスは大きくない(約10万のドキュメント)が、検索サービスは常に最新であり、常に最新でなければならない。索引には常に新しい文書が追加され、同時検索が行われます。 検索システムの可用性が高くなければならないため、WCFサービスを公開して検索と索引付けを行うアプリケーションサーバーが2つあります(各サーバーでサービスのコピーが実行されています)。次に、サーバーはlucene.net APIを使用して索引にアクセスします。複数のアプリケーションサーバー間でLucene.netインデックスを同期させる

問題は、インデックスを常に同期させるのに最適な解決策は何でしょうか? インデックスがSMBを経由して第二のサーバへのアクセスを有するもの索引付けのためのサーバーと を使用していない

  • :我々はいくつかのオプションを検討してきた私たちは、障害 状況の単一のポイントを持っている ので、何を行うことができます。

  • すべてのインデックスを2度書きます。おそらく、パフォーマンスが悪く、たとえばデシンクの可能性があります。サーバー1はOKを索引付けし、サーバー2はディスクスペースを使い果たします。

  • SOLRまたはKATTAを使用してインデックスへのアクセスをラップする:いいえ、私たちはサーバー上でTomcatなどを実行することはできません。私たちはIISしか持っていません。

  • データベースにインデックスを格納する:これはLucene(JdbcDirectoryモジュール)のJavaバージョンで行うことができますが、Lucene.netと同様のものは見つかりませんでした。たとえそれがパフォーマンスの低下を意味していたとしても、同時性をきれいに解決し、問題をミニナム開発と同期させるため、このオプションを選択します。

  • Lucene.netを使用するDistributedSearch contribモジュール:私はこれに関するドキュメンテーションで1つのリンクを提出できませんでした。私はこのコードが何をしているのかを見ても分かりませんが、実際に私たちが望むものではない複数のマシンにインデックスを分割しているようです。

  • のrsyncや友人は、前後に2つのサーバー間でインデックスをコピー:これは、インデックスが大きな成長場合は、しばらく時間がかかるかもしれませんし、この期間中、我々は次のようになり、ハックとエラーが発生しやすい私たちに感じている、と壊れたデータまたは一貫性のないデータをクライアントに返すので、私たちはしたくない特別なロックポリシーを開発する必要があります。

これは複雑な問題だと私は理解していますが、以前は多くの人がそれに直面していました。どんな助けも歓迎です!

答えて

6

ベスト・ソリューションは、両方のサーバーの文書を独自の索引のコピーに索引付けすることです。

インデックス作成が1台のサーバーで成功し、もう1台で失敗することが心配されている場合は、各サーバーの成功/失敗を追跡して、問題が発生した後で失敗したドキュメントを再試行する必要があります解決されました。この追跡は、Luceneに索引付けされる文書を表示するために使用しているシステムであれば、Luceneの外部で行われます。インデックスの完全性がどの程度重要であるかによって、使用しているロードバランサから障害が発生したサーバーを、問題が修正され、未処理のドキュメントの再処理が行われるまで削除する必要があります。

+0

Sean、これは現在、私たちの候補オプションです。私はあなたとitsadokに同意します。また、JdbcDirectoryのソースを見つけて、.NET + SQLサーバーへの移植が可能かどうかを調べようとしています。 新しいアプローチが出てくるかどうかを確認するためにしばらく質問を開いたままにしてください。そうでない場合はこの回答を受け入れます。 –

+0

同じことを一度チェックしました。それは努力の価値があるように見えませんでした.DBトランザクション関連のものがたくさんあります.Netに移植するのは簡単ではありません。また、JDBCDirectoryを使用してスピードを落とすという苦情もありました。ソースはCompassプロジェクトにあります - http://svn.compass-project.org/svn/compass/trunk/src/main/src/org/apache/lucene/store/jdbc/ –

+2

いくつか考えた後、これは何ですか私は最も実行可能な解決策として見ています:インデックス/インデックス解除の要求を受け取ったときに、キューとして機能する共有dbテーブルに行を挿入します。両方のアプリケーションサーバーで実行され、X秒ごとにキューをポーリングし、コンテンツをローカルに索引付けする単純なwin32サービスを実装します。コンテンツが正常に索引付けされると、サービスはアイテムを処理済みとしてマークし、そうでない場合は試行を続けます。 –

1

+1 Sean Carpenterの答えです。両方のサーバーのインデックス作成は、最も安全で安全な選択のようです。

インデックス作成中のドキュメントが複雑(Word/PDFおよび並べ替え)の場合は、1つのサーバーでいくつかの前処理を実行してから、インデックスサーバーに渡して処理時間を節約できます。

これまで使用してきた解決策では、1つのサーバーにインデックスチャンクを作成し、rsyncを検索サーバーに送り込み、IndexWriter.AddIndexesNoOptimizeを使用して各インデックスにチャンクをマージします。新しいチャンクは5分ごとに作成することも、一定のサイズになるたびに作成することもできます。あなたが絶対に最新のインデックスを持っている必要がない場合、これはあなたのための解決策かもしれません。

1

Javaの世界では、インデックスの前にMQを置くことでこの問題を解決しました。キューから取り出したBeanが正常に完了したときにのみ挿入が完了しました。それ以外の場合は、保留中のドキュメントにマークされたアクションをロールバックして、後で再試行しました。

1

これは古い質問です。私はそれを見つけたばかりで、マルチサーバーの実装について助言を求める他の人のために2セントを提供したいと思っていました。

インデックスファイルを共有NASフォルダに保存しないのはなぜですか?あなたが熟考していたデータベースにインデックスを格納するのとどのように違いますか?高可用性のためにデータベースを複製することができるため、NASでも構いません!

ロードバランサの背後にある2つのアプリケーションサーバーを構成します。インデックス要求が到着すると、NAS上のマシン固有のフォルダにあるドキュメントのインデックスが作成されます。つまり、アプリケーションサーバと同じくらい多くのインデックスがNAS上に存在します。検索リクエストが来たら、Luceneを使ってマルチインデックス検索を行います。 Luceneはこれを行うための組み込み(MultiSearcher)を備えており、パフォーマンスはまだ優れています。

+0

これが真であるかどうかは検証されていませんが、「Luceneの主要な推奨事項の1つは、ネットワーク化されたファイルシステムを使用しないことです」との回答があります: http://stackoverflow.com/a/8562566/1145177 Lucerne FAQでは、「ローカルファイルシステムを使用します。遠隔ファイルシステムは、通常、検索にかなり遅くなります。インデックスをリモートにする必要がある場合は、リモートファイルシステムを読み取り専用マウントとしてマウントしてください」: http://wiki.apache.org/ lucene-java/ImproveSearchingSpeed –

0

Luceneの独自のコピーを持つそれぞれの負荷分散サーバーを同期させる方法は、負荷分散サーバーごとにインデックスを更新するように5分ごとに実行する別のサーバーでタスクを実行することです特定のタイムスタンプ

たとえば、負荷分散されたすべてのサーバーにタイムスタンプ'12/1/2013 12:35:02.423 'が送信されます(タスクは、負荷分散された各WebサイトのWebページにクエリ文字列を使用してタイムスタンプを送信しています) )、各サーバーはそのタイムスタンプを使用して、そのタイムスタンプまでの最後の更新以降に発生したすべての更新をデータベースに照会し、ローカルのLuceneインデックスを更新します。

各サーバーはタイムスタンプもdbに格納しているため、各サーバーが最後に更新された時期を知ることができます。したがって、サーバーがオフラインになったときにオンラインに戻ったときに、次にタイムスタンプコマンドを受信すると、サーバーはオフラインになったときに見逃したすべての更新を取得します。

関連する問題