elasticSearch內(nèi)存介紹
在使用elasticSearch過程中或者elasticSearch需要配置升級的時候,elasticSearch內(nèi)存的分配問題就繞不開了抄腔,應(yīng)該設(shè)置多少的堆內(nèi)存合理仔引?這個問題想必難倒一大批開發(fā)者吧,雖然官方給出的建議是堆內(nèi)存設(shè)置機器內(nèi)存的一半疏之,但畢竟是官方的萬金油設(shè)置,如果想要更極致的性能應(yīng)該如何調(diào)優(yōu)呢?本文結(jié)合經(jīng)驗和實際淺談一下這個內(nèi)存分配的問題
elasticSearch使用的內(nèi)存種類
elasticSearch使用的內(nèi)存種類主要分三種:
- 堆內(nèi)存:即java啟動配置的堆大小
- 堆外內(nèi)存:主要是mmap
- Buffer Cache:系統(tǒng)緩存內(nèi)存
堆內(nèi)存在elasticSearch中的作用
堆內(nèi)存主要用于存儲ES進(jìn)程中的數(shù)據(jù)結(jié)構(gòu)拘悦、文檔信息、緩存以及執(zhí)行搜索操作等萨螺。堆內(nèi)存的大小會直接影響ES的性能窄做,較大的堆內(nèi)存能夠容納更多的數(shù)據(jù)和查詢,提高搜索性能慰技。然而椭盏,過大的堆內(nèi)存可能導(dǎo)致JVM垃圾回收的開銷增大,因此需要在設(shè)置時進(jìn)行權(quán)衡吻商。同時Lucene也會使用堆內(nèi)內(nèi)存來管理數(shù)據(jù)結(jié)構(gòu)和索引操作掏颊。在es搜索數(shù)據(jù)的時候,es會從根據(jù)搜索把相應(yīng)索引的分片加載到堆內(nèi)存里艾帐。同時elasticSearch的緩存也是存儲在堆內(nèi)內(nèi)存里乌叶,主要有字段數(shù)據(jù)緩存、字段數(shù)據(jù)緩存柒爸、字段數(shù)據(jù)緩存准浴、節(jié)點級別的緩存、分布式緩存捎稚,這些緩存的作用是應(yīng)用級別的提速乐横。相當(dāng)于多次重復(fù)條件或者重復(fù)的某一個層面的操作會被緩存來提高速度和吞吐量。
堆外內(nèi)存在elasticSearch中的作用
Elasticsearch的堆外內(nèi)存主要用于存儲直接內(nèi)存今野,這是一種在Java應(yīng)用程序中繞過Java堆而直接與操作系統(tǒng)通信的內(nèi)存分配方式葡公。堆外內(nèi)存在ES中的主要作用包括:
- 存儲內(nèi)存映射文件:Elasticsearch使用內(nèi)存映射文件(mmap)來加速對磁盤上的索引數(shù)據(jù)的讀取。這些內(nèi)存映射文件通常存儲在堆外內(nèi)存中条霜,而不是Java堆內(nèi)存中催什。通過使用內(nèi)存映射文:ES可以實現(xiàn)高效的數(shù)據(jù)讀取,因為它允許將文件的一部分映射到內(nèi)存中宰睡,而不是將整個文件讀入堆內(nèi)存蒲凶。
- 網(wǎng)絡(luò)通信緩沖區(qū):堆外內(nèi)存也用于存儲網(wǎng)絡(luò)通信的緩沖區(qū)气筋。在處理大量網(wǎng)絡(luò)請求時,使用堆外內(nèi)存可以減少垃圾回收的開銷豹爹,提高網(wǎng)絡(luò)通信的效率裆悄。
- 直接內(nèi)存池:Elasticsearch使用堆外內(nèi)存池來管理直接內(nèi)存的分配和釋放。這可以幫助降低垃圾回收的頻率臂聋,因為直接內(nèi)存不受Java堆內(nèi)存管理的影響光稼。
- 零拷貝操作:堆外內(nèi)存支持零拷貝操作,這意味著數(shù)據(jù)可以直接在堆外內(nèi)存中進(jìn)行傳輸孩等,而不需要在Java堆和堆外內(nèi)存之間進(jìn)行額外的拷貝操作艾君。這對于高性能的I/O操作非常重要。
Buffer Cache在elasticSearch中的作用
Buffer Cache 是操作系統(tǒng)級別的緩存肄方,用于存儲磁盤上的文件數(shù)據(jù)塊冰垄,以減少對物理存儲介質(zhì)的訪問。當(dāng)系統(tǒng)讀取文件時权她,讀取的數(shù)據(jù)塊會被緩存到內(nèi)存中虹茶,如果再次訪問相同的數(shù)據(jù)塊,系統(tǒng)可以直接從內(nèi)存中獲取隅要,而不需要再次從磁盤讀取蝴罪。這種緩存機制有助于提高文件的讀取性能。在elasticSearch中當(dāng)需要吧索引加載到堆內(nèi)存的時候就需要使用到系統(tǒng)緩存步清。
內(nèi)存分配與調(diào)優(yōu)
在介紹完es中各種內(nèi)存的作用后要门,那就涉及如何調(diào)優(yōu)內(nèi)存相關(guān)的了,首先官方推薦的1:1是適合絕大部分場景的萬金油配置廓啊。但是結(jié)合實際的業(yè)務(wù)還是會有調(diào)優(yōu)的空間欢搜。
我們es的機器配置是16g內(nèi)存,在我們的es機器上執(zhí)行top命令
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
4826 esuser 20 0 21.2g 11.5g 2.6g S 9.0 75.2 48086:32 java
可以看到虛擬內(nèi)存用了21.2g谴轮,實際內(nèi)存使用了11.5g炒瘟,而我們的jvm配置是配置8g的堆。
執(zhí)行free -h
total used free shared buff/cache available
Mem: 15G 9.3G 179M 444K 5.8G 5.7G
Swap: 0B 0B 0B
這臺機器就只安裝了es第步,所以根據(jù)這些數(shù)據(jù)我們可以推算出這個實例的內(nèi)存占用比例:
- 堆內(nèi)存:8g
- 堆外內(nèi)存:1.3g(9.3g-8g)
- es使用的buff cache: 2.2g(11.5g-9.3g)
就這個實例來說總體而言可以發(fā)現(xiàn)疮装,內(nèi)存其實是寬裕的沒有出現(xiàn)很擁擠的情況,如果是內(nèi)存比較擁擠雌续,es使用的buff cache會占比很大斩个,因為使用頻率的因素胯杭,會迅速淘汰其他的系統(tǒng)內(nèi)存驯杜。而實際情況也是如此,堆內(nèi)存罩住了全量的數(shù)據(jù)做个,這使得查詢很絲滑鸽心。
上面是一個比較良好的環(huán)境滚局,那當(dāng)內(nèi)存不太夠用的時候要怎么優(yōu)化?
結(jié)合業(yè)務(wù)實際優(yōu)化內(nèi)存比例
堆內(nèi)存就是存一些索引然后存一些緩存顽频,當(dāng)你的總索引大小很小藤肢,但是請求量很大的時候,可以適當(dāng)增加堆內(nèi)存的比例糯景,就像我上面的例子嘁圈,es使用的buff cache(2.2g)占總buff cache(5.8g)的比例很小(這臺只部署了es),這時候說明es從磁盤加載索引的壓力很小蟀淮,想要提高吞吐最住,可以增加堆內(nèi)存,這樣的話緩存和磁盤交換就會更加的少了怠惶,可以提高很多qps涨缚。
但是如果上面的情況是這樣的:es使用的buff cache占總buff cache很大,那說明從磁盤加載索引壓力比較大策治,這時候如果請求的并發(fā)量不高脓魏,適當(dāng)?shù)目s減堆內(nèi)存的大小是可以提高請求的響應(yīng)速度。但是如果是高并發(fā)的話通惫,就得考慮增加機器總內(nèi)存了茂翔。具體可以調(diào)整后測試,堆內(nèi)存是會緩存索引的讽膏,buffcache也是會緩存索引的檩电,所以增加哪一個,都不一定會有效果府树,還是得具體測俐末。當(dāng)然如果在內(nèi)存夠用的情況下想要提高吞吐,那就優(yōu)先增加堆內(nèi)存奄侠。堆內(nèi)存高了吞吐不一定高卓箫,但是堆內(nèi)存小了,吞吐一定上不去垄潮。
以上的優(yōu)化角度是建立在都是簡單查詢的情況烹卒。如果業(yè)務(wù)是很多復(fù)雜查詢涉及很多merge操作或者聚合操作的,那堆內(nèi)存的比例就要高于1/2了弯洗。
總結(jié)
第一次使用或者暫時沒有性能壓力的情況旅急,堆內(nèi)存配置系統(tǒng)內(nèi)存的一半。
高并發(fā)場景要提高堆內(nèi)存占比
復(fù)雜查詢場景要提高堆內(nèi)存占比
題外
堆內(nèi)存需要緩存索引牡整,堆外內(nèi)存也要緩存磁盤上的索引藐吮。在es上內(nèi)存是很珍貴的,所以緩存的命中率很重要。比如es里面存了2g的商品數(shù)據(jù)和100g的日志數(shù)據(jù)谣辞,那商品數(shù)據(jù)的查詢性能就要和100g的日志平均競爭緩存了迫摔,在有限的內(nèi)存下,只要查詢幾次日志數(shù)據(jù)泥从,就會極大拉低商品的查詢性能句占,所以es是最需要冷熱分離的數(shù)據(jù)庫,查詢頻率低的數(shù)據(jù)統(tǒng)統(tǒng)放到冷節(jié)點躯嫉,查詢頻率高的放熱節(jié)點纱烘。最重要的還是要了解原理,才能知道優(yōu)化方向