更新直後の検索クエリの結果が不整合になる


(Skane) #1

Elasticsearchにノード数4、シャード数8、レプリカ1で設定されたIndexに対して、以下のような現象が発生しました。

■事象

  1. APIで新しい上記のIndexにドキュメントを作成し更新
  2. _searchクエリから検索を行い結果を取得。1のドキュメントも結果に含まれている
  3. _searchクエリから検索を行い結果を取得。1のドキュメントが結果に含まれず
  4. _searchクエリから検索を行い結果を取得。1のドキュメントも結果に含まれている

■事象の詳細
・2〜4は一つのプロセスで2から順番に処理が流れている。
・多少クエリの内容が違いますが、1の結果は取得できるようなクエリになっている。
・1のみ非同期で処理が走っており、2の処理開始とほぼ同時に1の処理が完了していた。
・期待値としては、2〜4のクエリ結果に1が含まれて欲しい
・数分後に同じ処理を流したが期待通り2〜4の結果に1のドキュメントが含まれてた。
・1〜4を時系列に並べると全て1s以内での処理になっている
・refresh_intervalはデフォルトの1sのままである

ここで質問ですが、
上記の事象が起きた原因としては、
2と4のクエリは書き込まれが反映されているたプライマリシャードを読みにいき、
1の更新結果がレプリカに反映されていない状態で、3のクエリがレプリカシャードを読みにいったということでしょうか?

また、今後同じような事象を避けたいのですが、方法としては1のAPIで強制リフレッシュするのがよいのでしょうか?

もしかしたら基本的な内容に対する質問かもしれませんが、何卒よろしくお願いいたします。


(Makoto Nozawa) #2

refreshに関しては、1. のデータ投入時にrefresh=trueもしくはrefresh=wait_forのパラメータをつけるのが良いと思います。
https://www.elastic.co/guide/en/elasticsearch/reference/master/docs-refresh.html

ただ、1の完了を待たずに2が動くことがあるのなら、結局「データ投入が(完全に)終わる前に検索しに行く」ケースは残りそうに思います。


(Skane) #3

ご回答ありがとうございます

ただ、1の完了を待たずに2が動くことがあるのなら、結局「データ投入が(完全に)終わる前に検索しに行く」ケースは残りそうに思います。

説明不足で申し訳ありませんが、
データ投入が完全に終わる前に2の検索クエリで引っかからない場合は、
以降の処理はスキップされ、数秒後、2から再処理が始まる仕組みになっておりますので、
問題が起こらないようになっているのですが、
2の検索クエリで引っかかったのに3の検索で引っかからなかったことが問題となっております。
そういった事が有り得るということでしょうか?

一応、補足になりますが、クエリに指定してあるsizeかもと思いましたが、
クエリの結果取得件数は指定したsizeよりも少なかったため、クエリのsize指定が原因ではなさそうです。

後申し訳ございませんが、
Elasticsearchのバージョンを書き忘れておりましたが、5.6.8になります


(Makoto Nozawa) #4

これなら大丈夫そうですね、失礼しました。

相当古いバージョンではありますが、検索のたびに特定のデータが見えたり見えなかったりするケースはわたしも経験があります。そのときは原因までは突き止めていませんが、前述の通りなんらかの形で検索前にrefreshが走るように工夫すると解消するかもしれません。


(Skane) #5

1年以上動かしていた処理で一度しか発生していないので、
今後同じことが発生するか分かりませんが、
事象が発生してしまった場合、アプリケーション側で何らか対策取る方法を探ろうと思います。
回答ありがとうございました


(system) closed #6

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.