Elasticsearch内存分配设置详解
Elasticsearch默認安裝后設(shè)置的內(nèi)存是1GB,對于任何一個現(xiàn)實業(yè)務來說,這個設(shè)置都太小了。如果你正在使用這個默認堆內(nèi)存配置,你的集群配置可能會很快發(fā)生問題。
?
這里有兩種方式修改Elasticsearch的堆內(nèi)存(下面就說內(nèi)存好了),最簡單的一個方法就是指定ES_HEAP_SIZE環(huán)境變量。服務進程在啟動時候會讀取這個變量,并相應的設(shè)置堆的大小。設(shè)置命令如下:
export ES_HEAP_SIZE=10g
此外,你也可以通過命令行參數(shù)的形式,在程序啟動的時候把內(nèi)存大小傳遞給它:
./bin/elasticsearch -Xmx10g -Xms10g
備注:確保Xmx和Xms的大小是相同的,其目的是為了能夠在java垃圾回收機制清理完堆區(qū)后不需要重新分隔計算堆區(qū)的大小而浪費資源,可以減輕伸縮堆大小帶來的壓力。
一般來說設(shè)置ES_HEAP_SIZE環(huán)境變量,比直接寫-Xmx10g ?-Xms10g更好一點。
把內(nèi)存的一半給Lucene
一個常見的問題是配置一個大內(nèi)存,假設(shè)你有一個64G內(nèi)存的機器,按照正常思維思考,你可能會認為把64G內(nèi)存都給Elasticsearch比較好,但現(xiàn)實是這樣嗎,?越大越好?
?
當然,內(nèi)存對于Elasticsearch來說絕對是重要的,用于更多的內(nèi)存數(shù)據(jù)提供更快的操作,而且還有一個內(nèi)存消耗大戶-Lucene。
?
Lucene的設(shè)計目的是把底層OS里的數(shù)據(jù)緩存到內(nèi)存中。Lucene的段是分別存儲到單個文件中的,這些文件都是不會變化的,所以很利于緩存,同時操作系統(tǒng)也會把這些段文件緩存起來,以便更快的訪問。
?
Lucene的性能取決于和OS的交互,如果你把所有的內(nèi)存都分配給Elasticsearch,不留一點給Lucene,那你的全文檢索性能會很差的。
?
最后標準的建議是把50%的內(nèi)存給elasticsearch,剩下的50%也不會沒有用處的,Lucene會很快吞噬剩下的這部分內(nèi)存用于文件緩存。
不要超過32G
這里有另外一個原因不分配大內(nèi)存給Elasticsearch,事實上jvm在內(nèi)存小于32G的時候會采用一個內(nèi)存對象指針壓縮技術(shù)。
?
在java中,所有的對象都分配在堆上,然后有一個指針引用它。指向這些對象的指針大小通常是CPU的字長的大小,不是32bit就是64bit,這取決于你的處理器,指針指向了你的值的精確位置。
?
對于32位系統(tǒng),你的內(nèi)存最大可使用4G。對于64系統(tǒng)可以使用更大的內(nèi)存。但是64位的指針意味著更大的浪費,因為你的指針本身大了。浪費內(nèi)存不算,更糟糕的是,更大的指針在主內(nèi)存和緩存器(例如LLC, L1等)之間移動數(shù)據(jù)的時候,會占用更多的帶寬。
?
Java 使用一個叫內(nèi)存指針壓縮的技術(shù)來解決這個問題。它的指針不再表示對象在內(nèi)存中的精確位置,而是表示偏移量。這意味著32位的指針可以引用40億個對象,而不是40億個字節(jié)。最終,也就是說堆內(nèi)存長到32G的物理內(nèi)存,也可以用32bit的指針表示。
?
一旦你越過那個神奇的30-32G的邊界,指針就會切回普通對象的指針,每個對象的指針都變長了,就會使用更多的CPU內(nèi)存帶寬,也就是說你實際上失去了更多的內(nèi)存。事實上當內(nèi)存到達40-50GB的時候,有效內(nèi)存才相當于使用內(nèi)存對象指針壓縮技術(shù)時候的32G內(nèi)存。
?
這段描述的意思就是說:即便你有足夠的內(nèi)存,也盡量不要超過32G,因為它浪費了內(nèi)存,降低了CPU的性能,還要讓GC應對大內(nèi)存。
1TB內(nèi)存的機器
32GB是ES一個內(nèi)存設(shè)置限制,那如果你的機器有很大的內(nèi)存怎么辦呢?現(xiàn)在的機器內(nèi)存普遍增長,你現(xiàn)在都可以看到有300-500GB內(nèi)存的機器。
首先,我們建議編碼使用這樣的大型機
其次,如果你已經(jīng)有了這樣的機器,你有兩個可選項:
-
你主要做全文檢索嗎?考慮給Elasticsearch 32G內(nèi)存,剩下的交給Lucene用作操作系統(tǒng)的文件系統(tǒng)緩存,所有的segment都緩存起來,會加快全文檢索。
-
你需要更多的排序和聚合?你希望更大的堆內(nèi)存。你可以考慮一臺機器上創(chuàng)建兩個或者更多ES節(jié)點,而不要部署一個使用32+GB內(nèi)存的節(jié)點。仍然要 堅持50%原則,假設(shè) 你有個機器有128G內(nèi)存,你可以創(chuàng)建兩個node,使用32G內(nèi)存。也就是說64G內(nèi)存給ES的堆內(nèi)存,剩下的64G給Lucene。
如果你選擇第二種,你需要配置cluster.routing.allocation.same_shard.host:true。這會防止同一個shard的主副本存在同一個物理機上(因為如果存在一個機器上,副本的高可用性就沒有了)。
?
swapping是性能的墳墓
這是顯而易見的,但是還是有必要說的更清楚一點,內(nèi)存交換到磁盤對服務器性能來說是致命的。想想看一個內(nèi)存的操作必須是快速的。
?
?
如果內(nèi)存交換到磁盤上,一個100微秒的操作可能變成10毫秒,再想想那么多10微秒的操作時延累加起來。不難看出swapping對于性能是多么可怕。
?
最好的辦法就是在你的操作系統(tǒng)中完全禁用swapping。這樣可以暫時禁用:
swapoff -a
為了永久禁用它,你可能需要修改/etc/fstab文件,這要參考你的操作系統(tǒng)相關(guān)文檔。
?
如果完全禁用swap,對你來說是不可行的。你可以降低swappiness 的值,這個值決定操作系統(tǒng)交換內(nèi)存的頻率。這可以預防正常情況下發(fā)生交換。但仍允許os在緊急情況下發(fā)生交換。
?
對于大部分Linux操作系統(tǒng),可以在sysctl 中這樣配置:
vm.swappiness = 1
備注:swappiness設(shè)置為1比設(shè)置為0要好,因為在一些內(nèi)核版本,swappness=0會引發(fā)OOM(內(nèi)存溢出)
簡單地說這個參數(shù)定義了系統(tǒng)對swap的使用傾向,默認值為60,值越大表示越傾向于使用swap。可以設(shè)為0,這樣做并不會禁止對swap的使用,只是最大限度地降低了使用swap的可能性。
通過sysctl?-q?vm.swappiness可以查看參數(shù)的當前設(shè)置。
修改參數(shù)的方法是修改/etc/sysctl.conf文件,加入vm.swappiness=xxx,并重起系統(tǒng)。這個操作相當于是修改虛擬系統(tǒng)中的/proc/sys/vm/swappiness文件,將值改為XXX數(shù)值。
如果不想重起,可以通過sysctl -p動態(tài)加載/etc/sysctl.conf文件,但建議這樣做之前先清空swap。
?
最后,如果上面的方法都不能做到,你需要打開配置文件中的mlockall開關(guān),它的作用就是運行JVM鎖住內(nèi)存,禁止OS交換出去。在elasticsearch.yml配置如下:
bootstrap.mlockall: true
轉(zhuǎn)載于:https://www.cnblogs.com/jiu0821/p/5650027.html
總結(jié)
以上是生活随笔為你收集整理的Elasticsearch内存分配设置详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 甩洛瑶!!!!
- 下一篇: 我的汽车的雨刷坏了 换一个 要多少钱 ?