ES03# Elasticsearch性能調(diào)優(yōu)點梳理
引言
本文主要梳理了Elasticsearch集群常見優(yōu)化點,就一些主要項能夠在實踐中指導(dǎo)使用,本文主要內(nèi)容有:
JVM參數(shù)調(diào)優(yōu) 系統(tǒng)參數(shù)調(diào)優(yōu) 寫性能調(diào)優(yōu)點 讀性能調(diào)優(yōu)點 分片均衡優(yōu)化案例
1.參數(shù)設(shè)置
修改jvm參數(shù)可以通過config/jvm.options.d/jvm.options調(diào)整,不建議直接修改config/jvm.options,通過-Xms和-Xmx設(shè)置。
-Xms15g
-Xmx15g
2.參數(shù)大小
設(shè)置JVM堆內(nèi)存配置機器內(nèi)存一半,JVM內(nèi)存配置不超過32G
備注:參見官方文檔
https://www.elastic.co/guide/en/elasticsearch/reference/current/advanced-configuration.html#set-jvm-options
1.文件描述符限制
1.1 設(shè)置最大文件數(shù)
設(shè)置用戶的打開的最多文件數(shù),將account換成實際用戶。
命令:vim /etc/security/limits.conf
內(nèi)容:如下修改
#?End?of?file
account?soft?nofile?65535
account?hard?nofile?65535
*?soft?nofile?65535
*?hard?nofile?65535
1.2 查看文件描述符
輸入:
GET?_nodes/stats/process?filter_path=**.max_file_descriptors
輸出:
{
??"nodes"?:?{
????"UsN0qcWUTC68THnK0N9wLA"?:?{
??????"process"?:?{
????????"max_file_descriptors"?:?1048576
??????}
????},
????//...
}
備注:參見官方文檔
https://www.elastic.co/guide/en/elasticsearch/reference/current/setting-system-settings.html
https://www.elastic.co/guide/en/elasticsearch/reference/current/file-descriptors.html
2.關(guān)閉系統(tǒng)交換區(qū)
2.1 執(zhí)行禁用命令
命令:sudo swapoff -a
2.2 設(shè)置swappiness
將swappiness設(shè)置為1,通常情況下不交換,只在緊急情況允許少量交換。
swappiness=0 ?僅在內(nèi)存不足的情況下,當剩余空閑內(nèi)存低于vm.min_free_kbytes limit時,使用交換空間 swappiness=1 ?內(nèi)核版本3.5及以上、Red Hat內(nèi)核版本2.6.32-303及以上,進行最少量的交換,而不禁用交換
修改vim /etc/sysctl.conf,添加如下內(nèi)容,添加后執(zhí)行sysctl -p讓其生效。
vm.swappiness=1
2.3 鎖定地址空間
為了提高數(shù)據(jù)訪問和操作效率,將進程使用的地址空間鎖定在物理內(nèi)存中,防止交換到swap空間。
1.開啟內(nèi)存鎖
修改config/elasticsearch.yml中的bootstrap.memory_lock參數(shù)
bootstrap.memory_lock:?true
2.檢查鎖是否開啟
輸入:
GET?_nodes?filter_path=**.mlockall
輸出:
{
??"nodes"?:?{
????"m8c-TdL1RbK1M7goGTCTUQ"?:?{
??????"process"?:?{
????????"mlockall"?:?true
??????}
????},
????"-3lP6pM8SHq1-ulpGQybWQ"?:?{
??????"process"?:?{
????????"mlockall"?:?true
??????}
????},
????"6HCT0tLPQ7uKoJPnYPlO1A"?:?{
??????"process"?:?{
????????"mlockall"?:?true
??????}
????}
??}
}
3.給ES用戶授權(quán)
修改/etc/security/limits.conf,添加如下內(nèi)容。
#?allow?user?'elasticsearch'?mlockall
elasticsearch?soft?memlock?unlimited
elasticsearch?hard?memlock?unlimited
備注:參見官方文檔
https://www.elastic.co/guide/en/elasticsearch/reference/current/setup-configuration-memory.html
3.虛擬內(nèi)存限制
系統(tǒng)參數(shù)max_map_count限制一個進程擁有的虛擬內(nèi)存數(shù)量,默認值為65536。
修改vim /etc/sysctl.conf,添加如下內(nèi)容,添加后執(zhí)行sysctl -p讓其生效。
vm.max_map_count=262144
備注:參見官方文檔
https://www.elastic.co/guide/en/elasticsearch/reference/current/vm-max-map-count.html
4.進程數(shù)量限制
操作系統(tǒng)對每個用戶創(chuàng)建進程的限制, 官方建議為Elasticsearch user至少設(shè)置4096,可以調(diào)整的更大一些
命令:ulimit -u 655350
或
修改 vim /etc/security/limits.conf
*?soft?nproc?655350
5.系統(tǒng)優(yōu)化其他點
文件系統(tǒng)緩存會緩存I/O操作,確保至少物理內(nèi)存的一半 使用好的硬件,例如:SSD硬盤 單節(jié)點數(shù)據(jù)建議控制在2TB,最大不超過5TB 搜索性能要求搞得盡可能SSD,按照1:10配置內(nèi)存磁盤
備注:參見官方文檔
https://www.elastic.co/guide/en/elasticsearch/reference/current/max-number-of-threads.html1.多線程批量請求
批量寫入: 具體一次寫入多少document,需要測試給出。例如:建一個索引,單節(jié)點單分片,不斷調(diào)整寫入數(shù)量測試100,200,800,1000...等
多線程: 需要關(guān)注服務(wù)端返回的TOO_MANY_REQUESTS (429) 異常
2.增加refresh_interval間隔
寫入過程:數(shù)據(jù)寫入時,先保存在Index buffer,滿足refresh_interval為間隔時長后,定期清空buffer,生成segment供檢索。
增加refresh_interval時長,比如:30秒,可以避免生成過多的segment。
{
??"index":?{
????"refresh_interval":?"30s",
}
3.增加indexing buffer緩存區(qū)
Indexing緩存區(qū)用于存儲新的document,當緩存區(qū)滿了后會寫入segment落盤,index_buffer_size默認為整個堆內(nèi)存的10%,min_index_buffer_size指定緩存區(qū)允許的最小值,默認為48mb。
修改elasticsearch.yml添加參數(shù)
indices.memory.index_buffer_size:?30%
indices.memory.min_index_buffer_size:?96mb
4.設(shè)置副數(shù)量為零
在初始化第一次加載的時候設(shè)置副本為0,加載完成后再調(diào)整副本數(shù)量。如果日志類場景可以考慮將副本設(shè)置為0,提升性能的同時會犧牲
可靠性。
{
??"index":?{
????"number_of_replicas":?"0"
??}
}
5.使用文檔自增ID
如果自己設(shè)置文檔ID,ElasticSearch會校驗在分片中是否重復(fù),避免不必要的校驗使用自增ID。
6.分區(qū)均衡
設(shè)置合理的分片數(shù)確保均勻分布到所有數(shù)據(jù)節(jié)點上,通過參數(shù)index.routing.allocation.total_share_per_node限定每個索引在每個節(jié)點上可分配的主分片數(shù),例如等于平均數(shù)或者略大于平均數(shù)。
{
??"index":?{
????"routing":?{
??????"allocation":?{
????????"total_shards_per_node":?"2"
??????}
????}
??}
}
7.Translog配置
降低寫磁盤的頻率
Index.translog.durability:事務(wù)日志,默認request每次請求都會落盤,修改為async,異步寫入 index.translog.sync_interval: 設(shè)置為60s,每分鐘執(zhí)行一次 Index.translog.flush_threshod_size: 默認512M,可以適當調(diào)大一些,當translog超過該值觸發(fā)flush
8.Bulk/線程池/隊列設(shè)置
客戶端設(shè)置
單個bulk請求體不要太大,官方建議5~15M 單個bulk請求超時足夠長,建議60s以上 寫入段盡量將數(shù)據(jù)輪訓(xùn)到不同的節(jié)點,使用負載均衡
服務(wù)端設(shè)置
服務(wù)端線程池設(shè)置為核數(shù)+1 隊列大小適當增加,也需要注意過大會成為 GC 的負擔(dān)
elasticsearch.yml配置
##?Threadpool?Settings?##
#?Search?pool
threadpool.search.type:?fixed
threadpool.search.size:?20
threadpool.search.queue_size:?100
#?Bulk?pool
threadpool.bulk.type:?fixed
threadpool.bulk.size:?60
threadpool.bulk.queue_size:?300
#?Index?pool
threadpool.index.type:?fixed
threadpool.index.size:?20
threadpool.index.queue_size:?100
#?Indices?settings
indices.memory.index_buffer_size:?30%
indices.memory.min_index_buffer_size:?96mb
#?Cache?Sizes
indices.fielddata.cache.size:?15%
indices.fielddata.cache.expire:?6h
indices.cache.filter.size:?15%
indices.cache.filter.expire:?6h
#?Indexing?Settings?for?Writes
index.refresh_interval:?30s
index.translog.flush_threshold_ops:?50000
9.額外優(yōu)化項
9.1 不檢索的字段
只聚合不搜索的字段,index設(shè)置為false。
{
??"mappings":?{
????"properties":?{
??????"foo":?{
????????"type":?"integer",
????????"index":?false
??????}
????}
??}
}
9.2 不適用dynamic mapping
對字符串不要使用默認的dynamic mapping,字段數(shù)量過多,對性能產(chǎn)生比較大的影響
{
??"mappings":?{
????"dynamic":?false,
????"properties":?{}
??}
}
9.3 關(guān)閉_source
關(guān)閉_source,減少IO操作
"mappings":?{??
????"_source":?{??
????????"enabled":?false??
????}
}?
10.索引示例
{
??"index":?{
????"lifecycle":?{
??????"name":?"xxx_log_store"
????},
????"routing":?{
??????"allocation":?{
????????"total_shards_per_node":?"2"
??????}
????},
????"refresh_interval":?"30s",
????"number_of_shards":?"30",
????"translog":?{
??????"sync_interval":?"60s",
??????"durability":?"async"
????},
????"number_of_replicas":?"0",
????"mappings":?{
??????"dynamic":?false,
??????"properties":?{}
????}
??}
}
備注:參見官方文檔
Indexing?buffer?setting
https://www.elastic.co/guide/en/elasticsearch/reference/current/indexing-buffer.html
Tune?for?indexing?speed
https://www.elastic.co/guide/en/elasticsearch/reference/current/tune-for-indexing-speed.html
Tune?for?disk?usage
https://www.elastic.co/guide/en/elasticsearch/reference/current/tune-for-disk-usage.html
1.文檔建模
避免嵌套類型的數(shù)據(jù),查詢速度會慢幾倍
避免父子類型的數(shù)據(jù),查詢速度慢幾百倍
2.禁用腳本
盡量將數(shù)據(jù)先行計算,然后保存到ElasticSearch中,避免使用查詢腳本Script,可以使用ingest Pipeline并入需要的字段
3.禁用通配符
禁止使用*開頭的通配符查詢,性能會很差
4.注意分片數(shù)量
一個查詢訪問每一個分片,分片過多,開銷增加
5.基于時間的索引
在索引的名字中增加時間信息,按照每天/每周/每月的方式進行劃分,將只讀的索引進行force merge減少segment的數(shù)量
6.使用Filter Context
盡量使用Filter Context,利用緩存機制,減少不必要的算分
備注:參見官方文檔
https://www.elastic.co/guide/en/elasticsearch/reference/current/tune-for-search-speed.html
下面案例中ES集群中有15個節(jié)點,索引只有30個主分片,沒有設(shè)置副本。通過設(shè)置total_shards_per_node(每個節(jié)點中最多分片數(shù))不同的值,觀察主分片在各個節(jié)點的均衡情況。
1.沒有設(shè)置total_shards_per_node

備注:上圖為沒有設(shè)置total_shards_per_node參數(shù),30個分片被分布在5個節(jié)點中,節(jié)點最多分片8,最少分片2,分片不均衡。
2.設(shè)置total_shards_per_node=3

備注:當設(shè)置total_shards_per_node=3時,30個分片被分布在14個節(jié)點中,節(jié)點最多分片數(shù)3,最少分片數(shù)2,分片比較均衡。
3.設(shè)置total_shards_per_node=2

備注:當設(shè)置total_shards_per_node=2時,30個分片被分布在15個節(jié)點中,每個節(jié)點分片數(shù)均為2,分片均衡。
4.性能情況

備注:當分片分配均衡時,寫入性能也非常高,下圖為28.5萬/秒。當嚴重不均衡時,性能不足其一半。
