こんにちは
昨年10月からジョインさせて頂いてます卜部です
よろしくおねがいします
webアプリケーションから検索を伴うページが表示できず、タイトルのようなことが起きていたので調べた事をメモしておきます
まずはエラーログ
org.hibernate.search.exception.SearchException: HSEARCH400007: Elasticsearch request failed
ググった結論から言うと、アプリケーション側で特に指定しないまま(デフォルト)だとコネクション数2なので、10に指定するといいよという話のようです
Hibernate Search: concurrent timeout exception
Max_total_connection_per_route property
という事で、コネクション数が接続タイムアウトに対して効果があるのか検証してみました。
再現方法
アプリケーションからElasticSearchへのコネクション数を増やしながら、同じ方法でElasticSearchに対して負荷をかけます。
後述する項目についてデータを記録し、それを比較をしていきます。
コネクション数はプロパティに値を指定することで変更します。
spring.jpa.properties.hibernate.search.default.elasticsearch.max_total_connection_per_route=10
負荷の再現
現象が発生した時の条件を揃えるのは難しいので、バックアップを使って全データに対して再indexingすることで代用します
比較したい項目
アプリケーション設定の変更による他への影響も知りたかったので、こんな視点でチェックしてみます
- アプリケーションが全データ再indexingに要した時間
- アプリケーションとElasticSearch間でのデータ推移(時間と量)
- ElasticSearchのステータス
測定結果
※1AZ、1ノードの環境で検証
index再構成のログ
1コネクション:385秒 2020-01-31 15:40:47.987 INFO 6080 --- [nsport thread-2] o.h.s.b.i.SimpleIndexingProgressMonitor : HSEARCH000030: 260000 documents indexed in 385070 ms 2020-01-31 15:40:47.987 INFO 6080 --- [nsport thread-2] o.h.s.b.i.SimpleIndexingProgressMonitor : HSEARCH000031: Indexing speed: 675.201904 documents/second; progress: 100.00% 2020-01-31 15:40:48.396 INFO 6080 --- [h coordinator-1] o.h.s.b.i.SimpleIndexingProgressMonitor : HSEARCH000028: Reindexed 260012 entities 2コネクション(デフォルト):367秒 2020-01-31 17:26:47.338 INFO 9567 --- [nsport thread-2] o.h.s.b.i.SimpleIndexingProgressMonitor : HSEARCH000030: 260000 documents indexed in 367259 ms 2020-01-31 17:26:47.338 INFO 9567 --- [nsport thread-2] o.h.s.b.i.SimpleIndexingProgressMonitor : HSEARCH000031: Indexing speed: 707.947266 documents/second; progress: 100.00% 2020-01-31 17:26:47.803 INFO 9567 --- [h coordinator-1] o.h.s.b.i.SimpleIndexingProgressMonitor : HSEARCH000028: Reindexed 260012 entities 4コネクション:403秒 2020-01-31 12:17:49.336 INFO 30276 --- [nsport thread-2] o.h.s.b.i.SimpleIndexingProgressMonitor : HSEARCH000030: 260000 documents indexed in 403305 ms 2020-01-31 12:17:49.336 INFO 30276 --- [nsport thread-2] o.h.s.b.i.SimpleIndexingProgressMonitor : HSEARCH000031: Indexing speed: 644.673401 documents/second; progress: 100.00% 2020-01-31 12:17:49.748 INFO 30276 --- [h coordinator-1] o.h.s.b.i.SimpleIndexingProgressMonitor : HSEARCH000028: Reindexed 260012 entities 10コネクション:379秒 2020-01-31 14:53:18.370 INFO 1758 --- [nsport thread-2] o.h.s.b.i.SimpleIndexingProgressMonitor : HSEARCH000030: 260000 documents indexed in 379773 ms 2020-01-31 14:53:18.370 INFO 1758 --- [nsport thread-2] o.h.s.b.i.SimpleIndexingProgressMonitor : HSEARCH000031: Indexing speed: 684.619507 documents/second; progress: 100.00% 2020-01-31 14:53:18.850 INFO 1758 --- [h coordinator-1] o.h.s.b.i.SimpleIndexingProgressMonitor : HSEARCH000028: Reindexed 260012 entities 20コネクション:348秒 2020-01-31 20:41:20.533 INFO 17435 --- [nsport thread-2] o.h.s.b.i.SimpleIndexingProgressMonitor : HSEARCH000030: 260000 documents indexed in 348115 ms 2020-01-31 20:41:20.533 INFO 17435 --- [nsport thread-2] o.h.s.b.i.SimpleIndexingProgressMonitor : HSEARCH000031: Indexing speed: 746.879639 documents/second; progress: 100.00% 2020-01-31 20:41:21.023 INFO 17435 --- [h coordinator-1] o.h.s.b.i.SimpleIndexingProgressMonitor : HSEARCH000028: Reindexed 260012 entities
HibernateSearchのログでは秒数がバラバラで、少なくともコネクション数との相関関係は見られませんでした
アプリケーションサーバからのデータトラフィック量
見づらくて申し訳ないですが、グラフの山は左からそれぞれコネクション数4,10,1,2(デフォルト),20です
アプリケーションサーバから送信トラフィックが増え始め、0に収束するまでの時間は、先程のログで表記された時間とかなり違っています。
20、10コネクションはほぼログの時間と誤差無しですが、それ未満のコネクション数ではログの時間経過した後にもデータを送信し続けています。
アプリのログとの乖離が小さくなるため、これだけでも10コネクションに設定するメリットはありそうです。
ElasticSearchのステータス
画像を消してしまったので後日撮ったデータで申し訳ないですが、2(デフォルト)と10の比較です
インデックス作成、検索クエリのレイテンシー、バルクスレッドプールの低下も明らかです。
もちろん他にも検証すべき視点や調査も必用ですが、少なくともパフォーマンス改善に繋がりそうだと分かりました。
検証環境では1ノードだったので20コネクションが最もパフォーマンスが出ていましたが、トータル接続数の設定(デフォルトで20)は変更していないので、本番2ノードに適用するには10コネクションにしてみるのが良さそうです。
経過観察して、効果を報告できればと思います