ElasticSearch 海量數據查詢性能優化

ES 接收到查詢請求後,會轉發給所有相關的 Shard 分片,每個 Shard 在自己這塊兒進行搜索,各自的結果彙總後再返回給客戶端。

這個過程有 2 個核心性能關鍵點:

所以,我們就要從這兩個角度進行優化。

  1. 儘量讓 ES 的查詢動作簡單,避免進行復雜的查詢計算。

  2. 儘量提升 I/O 效率,也就是用好文件系統緩存(從 ES 寫入流程可以知道文件緩存有很大的作用)

  3. 儘量讓查詢計算簡單


這就涉及到 ES 中的數據建模方式。

例如關係數據庫有兩張表:

查詢訂單時,需要對兩張表進行關聯查詢。

這在關係數據庫中很正常,因爲關係數據庫是根據實體及其關係來建模的。

但在 ES 中最好就不要這麼定義數據結構了,ES 是搜索引擎,要以搜索的角度來規劃數據,怎麼便於搜索怎麼來。

例如直接把這兩張表的數據放在一個 Document 中,一個簡單查詢就完事兒了,不用讓 ES 進行 Document 的關聯查詢。

  1. 最大化使用操作系統的文件緩存

操作系統喜歡用文件緩存,只要內存充足,讀取 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