Elasticsearch重要文章之二:堆內存的大小和swapping

Elasticsearch默認安裝後設置的內存是1GB,對於任何一個業務部署來講,這個都過小了。若是你正在使用這些默認堆內存配置,你的集羣配置可能有點問題。java

這裏有兩種方式修改Elasticsearch的堆內存(下面就說內存好了),最簡單的一個方法就是指定ES_HEAP_SIZE環境變量。服務進程在啓動時候會讀取這個變量,並相應的設置堆的大小。舉例,你能夠用下面的命令設置它node

export ES_HEAP_SIZE=10gbootstrap

此外,你也能夠經過命令行參數的形式,在程序啓動的時候把內存大小傳遞給它:緩存

./bin/elasticsearch -Xmx10g -Xms10g服務器

備註:確保Xmx和Xms的大小是相同的,防止程序在運行時改變大小,這個是很廢的。app

通常來講設置ES_HEAP_SIZE環境變量,比直接寫-Xmx10g -Xms10g更好一點。jvm

把你的內存的一半給Luceneelasticsearch

一個常見的問題是配置一個大內存,假設你有一個64G內存的機器,個人天,你想把64G內存給Elasticsearch嗎? 越大越好!性能

固然,內存對於Elasticsearch來講絕對是重要的,用於更多的內存數據提供更快的操做。並且還有一個內存消耗大戶-Lucene編碼

Lucene的設計目的是把底層OS裏的數據緩存到內存中。Lucene的段是分別存儲到單個文件中的,這些文件都是不會變化的,因此很利於緩存,同時操做系統也會把這些段文件緩存起來,以便更快的訪問。

Lucene的性能取決於和OS的交互,若是你把全部的內存都分配給Elasticsearch,不留一點給Lucene,那你的全文檢索性能會不好的。

最後標準的建議是把50%的內存給elasticsearch,剩下的50%也不會沒有用處的,Lucene會很快吞噬剩下的這部份內存。

不要超過32G

這裏有另一個緣由不分配大內存給Elasticsearch,事實上jvm在內存小於32G的時候會採用一個內存對象指針壓縮技術。

在java中,全部的對象都分配在堆上,而後有一個指針引用它。指向這些對象的指針大小一般是CPU的字長的大小,不是32bit就是64bit,這取決於你的處理器,指針指向了你的值的精確位置。

對於32位系統,你的內存最大可以使用4G。對於64系統可使用更大的內存。可是64位的指針意味着更大的浪費,由於你的指針自己大了。浪費內存不算,更糟糕的是,更大的指針在主內存和緩存器(例如LLC, L1等)之間移動數據的時候,會佔用更多的帶寬。

java 使用一個叫內存指針壓縮的技術來解決這個問題。它的指針再也不表示對象在內存中的精確位置,而是表示偏移量。這意味着32位的指針能夠引用40億個對象,而不是40億個字節。最終,也就是說堆內存長到32G的物理內存,也能夠用32bit的指針表示。

一旦你越過那個神奇的30-32G的邊界,指針就會切回普通對象的指針,每一個對象的指針都變長了,就會使用更多的CPU內存帶寬,也就是說你實際上失去了更多的內存。事實上當內存到達40-50GB的時候,有效內存才至關於使用內存對象指針壓縮技術時候的32G內存。

這段描述的意思就是說:即使你有足夠的內存,也儘可能不要超過32G,由於它浪費了內存,下降了CPU的性能,還要讓GC應對大內存。

*我有一個1TB內存的機器
這個32GB的線是很很重要的,那若是你的機器有很大的內存怎麼辦呢?如今的機器內存廣泛增加,你如今均可以看到有300-500GB內存的機器。
首先,咱們建議編碼使用這樣的大型機
其次,若是你已經有了這樣的機器,你有兩個可選項:
>你主要作全文檢索嗎?考慮給Elasticsearch 32G內存,剩下的交給Lucene用做操做系統的文件系統緩存,全部的segment都緩存起來,會加快全文檢索。
>你須要更多的排序和聚合?你但願更大的堆內存。你能夠考慮一臺機器上建立兩個或者更多ES節點,而不要部署一個使用32+GB內存的節點。仍然要堅持50%原則,假設 你有個機器有128G內存,你能夠建立兩個node,使用32G內存。也就是說64G內存給ES的堆內存,剩下的64G給Lucene。
若是你選擇第二種,你須要配置cluster.routing.allocation.same_shard.host:true。這會防止同一個shard的主副本存在同一個物理機上(由於若是存在一個機器上,副本的高可用性就沒有了)。

swapping是性能的墳墓

這是顯而易見的,可是仍是有必要說的更清楚一點,內存交換到磁盤對服務器性能來講是致命的。想一想看一個內存的操做必須是快速的。

若是內存交換到磁盤上,一個100微秒的操做可能變成10毫秒,再想一想那麼多10微秒的操做時延累加起來。不難看出swapping對於性能是多麼可怕。

最好的辦法就是在你的操做系統中徹底禁用swapping。這樣能夠暫時禁用:
sudo swapoff -a

爲了永久禁用它,你可能須要修改/etc/fstab文件,這要參考你的操做系統相關文檔。

若是徹底禁用swap,對你來講是不可行的。你能夠下降swappiness 的值,這個值決定操做系統交換內存的頻率。這能夠預防正常狀況下發生交換。但仍容許os在緊急狀況下發生交換。

對於大部分Linux操做系統,能夠在sysctl 中這樣配置:
vm.swappiness = 1
備註:swappiness設置爲1比設置爲0要好,由於在一些內核版本,swappness=0會引起OOM(內存溢出)

最後,若是上面的方法都不能作到,你須要打開配置文件中的mlockall開關,它的做用就是運行JVM鎖住內存,禁止OS交換出去。在elasticsearch.yml配置以下: bootstrap.mlockall: true

相關文章
相關標籤/搜索