# Elasticsearch系列 - 性能優化

本文主要介紹一些能夠提升ES性能的優化手段,以及一些防坑措施,請大家參考。

內存設置

由於ES構建基於lucene, 而lucene設計強大之處在於lucene能夠很好的利用操作系統內存來緩存索引數據,以提供快速的查詢性能。lucene的索引文件segements是存儲在單文件中的,並且不可變,對於OS來說,能夠很友好地將索引文件保持在cache中,以便快速訪問;因此,我們很有必要將一半的物理內存留給lucene ; 另一半的物理內存留給ES(JVM heap)。所以,在ES內存設置方面,可以遵循以下原則:

  • 1.當機器內存小於64G時,遵循通用的原則,50%給ES,50%留給lucene。
  • 2.當機器內存大於64G時,遵循以下原則:
    • a.如果主要的使用場景是全文檢索,那麼建議給ES Heap分配 4~32G的內存即可;其它內存留給操作系統, 供lucene使用(segments cache), 以提供更快的查詢性能。
    • b.如果主要的使用場景是聚合或排序,並且大多數是numerics, dates, geo_points 以及not_analyzed的字符類型,建議分配給ES Heap分配 4~32G的內存即可,其它內存留給操作系統,供lucene使用(doc values cache),提供快速的基於文檔的聚類、排序性能。
    • c.如果使用場景是聚合或排序,並且都是基於 analyzed 字符數據,這時需要更多的 heap size, 建議機器上運行多ES實例,每個實例保持不超過50%的ES heap設置(但不超過32G,堆內存設置32G以下時,JVM使用對象指標壓縮技巧節省空間),50%以上留給lucene。
  • 3.對於數據量比較大,無法把全部數據都緩存到os cache,儘量保證整個集羣,所有機器os cache內存總和,超過整個存儲容量的一般以上,這樣才能提高性能,實在不行,只能採取其他措施,比如:
    • a.數據預熱,在後臺做一個系統,定時查詢熱點數據,緩存到os cache中,下次用戶訪問熱點數據時,就會直接從os cache中獲取,不需要再查詢磁盤了
    • b.冷熱分離,對於一條索引中,有些字段檢索比較頻繁,即爲熱字段,有些字段檢索比較少,即爲冷字段,對於這種情況,把一個索引拆分爲兩條索引,熱字段一條,冷字段一條
    • 這樣經常檢索的索引就會被緩存os cache,大部分時間冷索引就會在磁盤,提高內存利用率
  • 4.禁止swap,一旦允許內存與磁盤的交換,會引起致命的性能問題。通過在 elasticsearch.ymlbootstrap.memory_lock: true,以保持JVM鎖定內存,保證ES的性能。

分片設置

ES一旦創建好索引後,就無法調整分片的設置,而在ES中,一個分片實際上對應一個lucene索引,而lucene索引的讀寫會佔用很多的系統資源,因此,分片數不能設置過大;所以,在創建索引時,合理配置分片數是非常重要的。一般來說,我們遵循一些原則:

  • 1.控制每個分片佔用的硬盤容量不超過ES的最大JVM的堆空間設置(一般設置不超過32G),因此,如果索引的總容量在500G左右,那分片大小在16個左右即可;當然,最好同時考慮原則2。
  • 2.考慮一下node數量,一般一個節點有時候就是一臺物理機,如果分片數過多,大大超過了節點數,很可能會導致一個節點上存在多個分片,一旦該節點故障,即使保持了1個以上的副本,同樣有可能會導致數據丟失,集羣無法恢復。所以,一般都設置分片數不超過節點數的3倍。

索引設置

  • 我們知道,es內存比較寶貴,所以在我們設計索引的時候就需要進行處理,只把需要檢索的字段存入,其他不需要檢索的字段,存儲到mysql或hbase中,提高es內存利用率
  • 設計索引模型的時候,對於需要join等操作的場景,儘量在入es的時候處理好,即多個表合爲一張寬索引,避免查詢時使用join等操作

參考文章

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章