elasticsearch性能調優
集群規划
- 獨立的master節點,不存儲數據, 數量不少於2
- 數據節點(Data Node)
- 查詢節點(Query Node),起到負載均衡的作用
Linux系統參數配置
文件句柄
Linux中,每個進程默認打開的最大文件句柄數是1000,對於服務器進程來說,顯然太小,通過修改/etc/security/limits.conf來增大打開最大句柄數
* - nofile 65535
虛擬內存設置
max_map_count定義了進程能擁有的最多內存區域
sysctl -w vm.max_map_count=262144
修改/etc/elasticsearch/elasticsearch.yml
bootstrap.mlockall: true
修改/etc/security/limits.conf, 在limits.conf中添加如下內容
* soft memlock unlimited
* hard memlock unlimited
memlock 最大鎖定內存地址空間, 要使limits.conf文件配置生效,必須要確保pam_limits.so文件被加入到啟動文件中。
確保/etc/pam.d/login文件中有如下內容
session required /lib/security/pam_limits.so
驗證是否生效
curl localhost:9200/_nodes/stats/process?pretty
磁盤緩存相關參數
vm.dirty_background_ratio 這個參數指定了當文件系統緩存臟頁數量達到系統內存百分之多少時(如5%)就會觸發pdflush/flush/kdmflush等后台回寫進程運行,將一定緩存的臟頁異步地刷入外存;
vm.dirty_ratio
-
該參數則指定了當文件系統緩存臟頁數量達到系統內存百分之多少時(如10%),系統不得不開始處理緩存臟頁(因為此時臟頁數量已經比較多,為了避免數據丟失需要將一定臟頁刷入外存);在此過程中很多應用進程可能會因為系統轉而處理文件IO而阻塞。
-
把該參數適當調小,原理通(1)類似。如果cached的臟數據所占比例(這里是占MemTotal的比例)超過這個設置,系統會停止所有的應用層的IO寫操作,等待刷完數據后恢復IO。所以萬一觸發了系統的這個操作,對於用戶來說影響非常大的。
sysctl -w vm.dirty_ratio=10
sysctl -w vm.dirty_background_ratio=5
為了將設置永久保存,將上述配置項寫入/etc/sysctl.conf文件中
vm.dirty_ratio = 10
vm.dirty_background_ratio = 5
swap調優
swap空間是一塊磁盤空間,操作系統使用這塊空間保存從內存中換出的操作系統不常用page數據,這樣可以分配出更多的內存做page cache。這樣通常會提升系統的吞吐量和IO性能,但同樣會產生很多問題。頁面頻繁換入換出會產生IO讀寫、操作系統中斷,這些都很影響系統的性能。這個值越大操作系統就會更加積極的使用swap空間。
調節swappniess方法如下
sudo sh -c 'echo "0">/proc/sys/vm/swappiness'
io sched
如果集群中使用的是SSD磁盤,那么可以將默認的io sched由cfq設置為noop
sudo sh -c 'echo "noop">/sys/block/sda/queue/scheduler'
JVM參數設置
在/etc/sysconfig/elasticsearch中設置最大堆內存,該值不應超過32G
ES_HEAP_SIZE=32g
ES_JAVA_OPTS="-Xms32g"
MAX_LOCKED_MEMORY=unlimited
MAX_OPEN_FILES=65535
indice參數調優
以創建demo_logs模板為例,說明可以調優的參數及其數值設定原因。
PUT _template/demo_logs
{
"order": 6,
"template": "demo-*",
"settings": {
"index.merge.policy.segments_per_tier": "25",
"index.mapping._source.compress": "true",
"index.mapping._all.enabled": "false",
"index.warmer.enabled": "false",
"index.merge.policy.min_merge_size": "10mb",
"index.refresh_interval": "60s",
"index.number_of_shards": "7",
"index.translog.durability": "async",
"index.store.type": "mmapfs",
"index.merge.policy.floor_segment": "100mb",
"index.merge.scheduler.max_thread_count": "1",
"index.translog.translog.flush_threshold_size": "1g",
"index.merge.policy.merge_factor": "15",
"index.translog.translog.flush_threshold_period": "100m",
"index.translog.sync_interval": "5s",
"index.number_of_replicas": "1",
"index.indices.store.throttle.max_bytes_per_sec": "50mb",
"index.routing.allocation.total_shards_per_node": "2",
"index.translog.flush_threshold_ops": "1000000"
},
"mappings": {
"_default_": {
"dynamic_templates": [
{
"string_template": {
"mapping": {
"index": "not_analyzed",
"ignore_above": "10915",
"type": "string"
},
"match_mapping_type": "string"
}
},
{
"level_fields": {
"mapping": {
"index": "no",
"type": "string"
},
"match": "Level*Exception*"
}
}
]
}
}
"aliases": {}
}
replica數目
為了讓創建的es index在每台datanode上均勻分布,同一個datanode上同一個index的shard數目不應超過3個。
計算公式: (number_of_shard * (1+number_of_replicas)) < 3*number_of_datanodes
每台機器上分配的shard數目
"index.routing.allocation.total_shards_per_node": "2",
refresh時間間隔
默認的刷新時間間隔是1s,對於寫入量很大的場景,這樣的配置會導致寫入吞吐量很低,適當提高刷新間隔,可以提升寫入量,代價就是讓新寫入的數據在60s之后可以被搜索,新數據可見的及時性有所下降。
"index.refresh_interval": "60s"
translog
降低數據flush到磁盤的頻率。如果對數據丟失有一定的容忍,可以打開async模式。
"index.translog.flush_threshold_ops": "1000000",
"index.translog.durability": "async",
merge相關參數
"index.merge.policy.floor_segment": "100mb",
"index.merge.scheduler.max_thread_count": "1",
"index.merge.policy.min_merge_size": "10mb"
mapping設置
對於不參與搜索的字段(fields), 將其index方法設置為no, 如果對分詞沒有需求,對參與搜索的字段,其index方法設置為not_analyzed
多使用dynamic_template
集群參數調優
{
"persistent": {
"cluster": {
"routing": {
"allocation": {
"enable": "new_primaries",
"cluster_concurrent_rebalance": "8",
"allow_rebalance": "indices_primaries_active",
"node_concurrent_recoveries": "8"
}
}
},
"indices": {
"breaker": {
"fielddata": {
"limit": "30%"
},
"request": {
"limit": "30%"
}
},
"recovery": {
"concurrent_streams": "10",
"max_bytes_per_sec": "200mb"
}
}
},
"transient": {
"indices": {
"store": {
"throttle": {
"type": "merge",
"max_bytes_per_sec": "50mb"
}
},
"recovery": {
"concurrent_streams": "8"
}
},
"threadpool": {
"bulk": {
"type": "fixed"
"queue_size": "1000",
"size": "30"
},
"index": {
"type": "fixed",
"queue_size": "1200",
"size": "30"
}
},
"cluster": {
"routing": {
"allocation": {
"enable": "all",
"cluster_concurrent_rebalance": "8",
"node_concurrent_recoveries": "15"
}
}
}
}
}
避免shard的頻繁rebalance,將allocation的類型設置為new_primaries, 將默認並行rebalance由2設置為更大的一些的值
避免每次更新mapping, 針對2.x以下的版本
"indices.cluster.send_refresh_mapping": false
調整threadpool, size不要超過core數目,否則線程之間的context switching會消耗掉大量的cpu時間,導致load過高。 如果沒有把握,那就不要去調整。
定期清理cache
為避免fields data占用大量的jvm內存,可以通過定期清理的方式來釋放緩存的數據。釋放的內容包括field data, filter cache, query cache
curl -XPOST "localhost:9200/_cache/clear"
其它
- marvel: 安裝marvel插件,多觀察系統資源占用情況,包括內存,cpu
- 日志: 對es的運行日志要經常查看,檢查index配置是否合理,以及入庫數據是否存在異常
調優之后的運行效果
寫入量穩定在30K/s