ElasticSearch偶爾查詢不到數據
現象:每次insert之後,立刻查詢es的數據是有可能查不到的,因爲es從內存寫到磁盤需要時間
原因:es默認每1s執行一次refresh,因此文檔實時性被提高到1s,這也是es被稱爲近實時的原因
解決方法:寫的時候指定數據刷新策略, request().setRefreshPolicy(RefreshPolicy.IMMEDIATE);
枚舉org.elasticsearch.action.support.WriteRequest.RefreshPolicy定義了三種策略:
/** * Don't refresh after this request. The default. */ NONE, /** * Force a refresh as part of this request. This refresh policy does not scale for high indexing or search throughput but is useful * to present a consistent view to for indices with very low traffic. And it is wonderful for tests! */ IMMEDIATE, /** * Leave this request open until a refresh has made the contents of this request visible to search. This refresh policy is * compatible with high indexing and search throughput but it causes the request to wait to reply until a refresh occurs. */ WAIT_UNTIL;
每次查詢最大隻能查10000條
通過資料的查閱,發現默認值是10000,如果要查詢大於10000條,我們就需要修改es的max_result_window默認值
解決方法:
我們在創建索引的時候 設置:"index.max_result_window": "10000", 這個值默認一萬,我們可以改成自己想要的值
ES性能優化
1. 因爲ES不能改變分片數量,所以創建索引的時候要指定好分片數量
ES 默認爲一個索引創建 5 個主分片, 並分別爲每個分片創建一個副本分片。
解決辦法:合理的分片數量可以提高寫入性能和穩定性。
分片數可以理解爲MySQL中的分庫分表
ES查詢主要分爲兩類:單ID查詢以及分頁查詢。
分片數越大,集羣橫向擴容規模也更大,根據分片路由的單ID查詢吞吐量也能大大提升,但聚合的分頁查詢性能則將降低;
分片數越小,集羣橫向擴容規模也更小,單ID的查詢性能也會下降,但分頁查詢的性能將會提升。
2、避免深分頁查詢ES集羣的分頁查詢支持from和size參數,
查詢的時候,每個分片必須構造一個長度爲from+size的優先隊列,
然後回傳到網關節點,網關節點再對這些優先隊列進行排序找到正確的size個文檔。
假設在一個有6個主分片的索引中,from爲10000,size爲10,每個分片必須產生10010個結果,
在網關節點中匯聚合併60060個結果,最終找到符合要求的10個文檔。
由此可見,當from足夠大的時候,就算不發生OOM,也會影響到CPU和帶寬等,從而影響到整個集羣的性能。
所以應該避免深分頁查詢,儘量不去使用。
解決辦法:可以使用ES的Scroll滾動查詢
scroll 會一次性生成所有數據的快照,然後每次滑動向後翻頁就是通過遊標 scroll_id 移動,獲取下一頁,
性能會比上面說的分頁性能要高很多,基本上都是毫秒級的。
這個適合於那種類似微博下拉翻頁的,不能隨意跳到任何一頁的場景。