ElasticSearch 海量數據查詢性能優化
ES 接收到查詢請求後,會轉發給所有相關的 Shard 分片,每個 Shard 在自己這塊兒進行搜索,各自的結果彙總後再返回給客戶端。
這個過程有 2 個核心性能關鍵點:
-
Shard 執行查詢計算的耗時
-
Shard 讀取各個 Segment 文件的 I/O 耗時
所以,我們就要從這兩個角度進行優化。
-
儘量讓 ES 的查詢動作簡單,避免進行復雜的查詢計算。
-
儘量提升 I/O 效率,也就是用好文件系統緩存(從 ES 寫入流程可以知道文件緩存有很大的作用)
-
儘量讓查詢計算簡單
這就涉及到 ES 中的數據建模方式。
例如關係數據庫有兩張表:
-
訂單表(編號、總金額、用戶、日期)
-
訂單詳情表(訂單編號、商品信息)
查詢訂單時,需要對兩張表進行關聯查詢。
這在關係數據庫中很正常,因爲關係數據庫是根據實體及其關係來建模的。
但在 ES 中最好就不要這麼定義數據結構了,ES 是搜索引擎,要以搜索的角度來規劃數據,怎麼便於搜索怎麼來。
例如直接把這兩張表的數據放在一個 Document 中,一個簡單查詢就完事兒了,不用讓 ES 進行 Document 的關聯查詢。
- 最大化使用操作系統的文件緩存
操作系統喜歡用文件緩存,只要內存充足,讀取 Segment 文件的時候,就會將其內容一直放在緩存中,直到內存不夠用了。
比如讀 Segment 01 這個文件的時候,先加載到文件緩存。
如果緩存空間足夠,就直接加載進來。
否則,就會移除一部分緩存的文件,騰出空間後再加載進來。
例如,你的 ES 數據量是 1000G,集羣有 3 個節點,每個節點上面就是 300 多個 G。
假設,每個節點中操作系統可以使用內存爲 16G,那麼,搜索的時候,直接讀文件緩存的最大概率也只有 5% 左右,絕大部分的數據都要讀物理文件,一起爭用那一點文件緩存空間,性能自然很差。
優化方向有 2 個:
1)增加內存
2)減少 ES 中的數據量
2.1 增加內存
增加內存很簡單,只要有錢就行。
那麼需要增加到多少呢?
建議:操作系統可用內存 > 本節點數據量的 50%
這樣數據命中緩存的概率就比較高了。如果不差錢,內存越大越好。
2.2 減少 ES 中的數據量
再強調一次 ES 是搜索引擎,是用來幹搜索的。
很多人喜歡把數據全都放 ES 裏,感覺它是分佈式的,多放幾臺服務器,硬盤大點,很能裝。
比如一個表有上百個字段,真正搜索的時候,都會用到嗎?不一定吧。
那麼,搜索用不到的數據儘量別放在 ES 裏。
ES 服務於搜索,不是服務於存儲。
所以,ES 中應該放與搜索相關的數據,不應該放全量數據。
全量數據的存儲應該使用專業的存儲系統,例如 HBASE。
在大數據環境中,有幾個 T 的數據很正常,如果都放在 ES 裏面,並且想要保障查詢性能,內存要多大呢?
如果經濟實力不允許,內存不是很充足,那麼查詢性能就很悲催了,每次查詢花費幾秒鐘很正常。
如果 ES 中只放搜索相關的少量數據,把全量數據放在 HBASE,性能就會快很多。
先從 ES 中查詢出結果數據集,其中只包含核心字段,然後根據結果集中各條數據的 Key 到 HBASE 中進行精準查詢,再把結果進行整合。
雖然是兩次查詢,但因爲每部分都很快,所以整體下來也很快。
2.3 思路擴展
- 冷熱分離
數據通常有冷熱之分,有一部分數據的使用頻率明顯高於其他數據。
如果文件系統的緩存不是很充足,那麼數據就需要輪流呆在緩存中。
熱數據自然呆的時間長,但是當加載冷數據時,就會把熱數據擠出緩存了。那麼下次就需要從磁盤重新加載。
所以,最好讓熱數據走一部分 Shard,冷數據走其他 Shard,防止沖刷緩存。
- 數據預加載
還是基於熱數據的角度,可以事先調用一下,使其提前進入文件緩存。
這樣,客戶第一次查詢的時候也會很快。
小結
想要 ES 查詢速度快,需要使查詢動作儘量簡單,這需要在數據建模上多花些心思。
最重要的是要利用好文件緩存。
增加內存是簡單、粗暴、有效的方法。
還有就是儘量縮減 ES 中的數據量,不要存放與搜索需求無關的數據。可以配合 HBASE 這類的專業海量數據存儲系統一起使用。
另外,冷熱數據分離、數據預加載,也是比較有效的小技巧。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/zgfoMBAizRtQFyjqBt4APA