<a href="http://www.cnblogs.com/jiu0821/p/5650027.html" target="_blank">Elasticsearch記憶體配置設定設定詳解</a>
Elasticsearch預設安裝後設定的記憶體是1GB,對于任何一個現實業務來說,這個設定都太小了。如果你正在使用這個預設堆記憶體配置,你的叢集配置可能會很快發生問題。
這裡有兩種方式修改Elasticsearch的堆記憶體(下面就說記憶體好了),最簡單的一個方法就是指定ES_HEAP_SIZE環境變量。服務程序在啟動時候會讀取這個變量,并相應的設定堆的大小。設定指令如下:
此外,你也可以通過指令行參數的形式,在程式啟動的時候把記憶體大小傳遞給它:
備注: 確定Xmx和Xms的大小是相同的,其目的是為了能夠在java垃圾回收機制清理完堆區後不需要重新分隔計算堆區的大小而浪費資源,可以減輕伸縮堆大小帶來的壓力。
一般來說設定ES_HEAP_SIZE環境變量,比直接寫-Xmx10g -Xms10g更好一點。
把記憶體的一半給Lucene
一個常見的問題是配置一個大記憶體,假設你有一個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是ES一個記憶體設定限制,那如果你的機器有很大的記憶體怎麼辦呢?現在的機器記憶體普遍增長,你現在都可以看到有300-500GB記憶體的機器。
首先,我們建議編碼使用這樣的大型機
其次,如果你已經有了這樣的機器,你有兩個可選項:
你主要做全文檢索嗎?考慮給Elasticsearch 32G記憶體,剩下的交給Lucene用作作業系統的檔案系統緩存,所有的segment都緩存起來,會加快全文檢索。
你需要更多的排序和聚合?你希望更大的堆記憶體。你可以考慮一台機器上建立兩個或者更多ES節點,而不要部署一個使用32+GB記憶體的節點。仍然要堅持50%原則,假設你有個機器有128G記憶體,你可以建立兩個node,使用32G記憶體。也就是說64G記憶體給ES的堆記憶體,剩下的64G給Lucene。
swapping是性能的墳墓
這是顯而易見的,但是還是有必要說的更清楚一點,記憶體交換到磁盤對伺服器性能來說是緻命的。想想看一個記憶體的操作必須是快速的。
如果記憶體交換到磁盤上,一個100微秒的操作可能變成10毫秒,再想想那麼多10微秒的操作時延累加起來。不難看出swapping對于性能是多麼可怕。
最好的辦法就是在你的作業系統中完全禁用swapping。這樣可以暫時禁用:
為了永久禁用它,你可能需要修改/etc/fstab檔案,這要參考你的作業系統相關文檔。
如果完全禁用swap,對你來說是不可行的。你可以降低swappiness 的值,這個值決定作業系統交換記憶體的頻率。這可以預防正常情況下發生交換。但仍允許os在緊急情況下發生交換。
對于大部分Linux作業系統,可以在sysctl中這樣配置:
備注:swappiness設定為1比設定為0要好,因為在一些核心版本,swappness=0會引發OOM(記憶體溢出)
簡單地說這個參數定義了系統對swap的使用傾向,預設值為60,值越大表示越傾向于使用swap。可以設為0,這樣做并不會禁止對swap的使用,隻是最大限度地降低了使用swap的可能性。
通過sysctl -q vm.swappiness可以檢視參數的目前設定。
修改參數的方法是修改/etc/sysctl.conf檔案,加入vm.swappiness=xxx,并重起系統。這個操作相當于是修改虛拟系統中的/proc/sys/vm/swappiness檔案,将值改為XXX數值。
如果不想重起,可以通過sysctl -p動态加載/etc/sysctl.conf檔案,但建議這樣做之前先清空swap。
最後,如果上面的方法都不能做到,你需要打開配置檔案中的mlockall開關,它的作用就是運作JVM鎖住記憶體,禁止OS交換出去。在elasticsearch.yml配置如下: