本文重要是解说了Elasticsearch数据库的优化,大家可以看一下。因为当时实操中涉及了6版本和7版本的一起优化,所以内容上大家自行区分一下。
一、底子设置
1. jvm.options参数详解 差别版本java设置会不一样
-Xms12g
-Xmx12g
说明:
- 将 Xms 和 Xmx 设置成一样大 避免JVM堆的动态调解给应用进程带来"不稳定",详细内存利用大小盘算,参数上述盘算法则。
- 但是需要预留充足的内存空间给page cache。假设一台32GB内存的机器,设置16GB内存给ES进程利用,另外16GB给page cache,而不是将 xmx
设置成32GB。因为还是预留给lucene
-XX:+AlwaysPreTouch
- 设置JVM参数:-XX:+AlwaysPreTouch 淘汰新生代晋升到老年代时停顿。
JDK官方文档关于 AlwaysPreTouch 的表明是
在启动时就把参数里说好了的内存全部都分配了,会使得启动慢上一点,但后面访问时会更流畅,比如页面会连续分配,比如不会在晋升新生代到老生代时才去访问页面,导致GC停顿时间加长。
4. 我想说一下Linux内存分配、Linux OOM Killer、内存交换vm.swappiness参数 之间的一些理解:当ES进程向操作体系MMU申请分配内存时,操作体系内核分配的是假造内存,比如指定 -Xms=16G
那么只是告诉内核这个ES进程在启动的时候最需要16G内存,但是ES进程在启动后并不是立即就用了16G的内存。因此,随着ES的运行,ES进程访问假造内存时产生缺页错误(page
fault),然后内核为之分配实际的物理页面(这个过程也是需要开销的)。而如果在JVM启动时指定了AlwaysPreTouch,就会分配实际的物理内存,这样在发生YGC的时候,新生代对象晋升到老年代,淘汰老年代空间分配产生的缺页非常,从而淘汰YGC停顿时间。
-XX:CMSInitiatingOccupancyFraction 设置成75
- 重要是因为CMS是并发网络,垃圾采取线程和用户线程同时运行,用户线程运行时大概继续无用的垃圾对象,如果到90%再去采取就太晚了。老年代利用到75%就采取可淘汰OOM非常发生的概率。
-XX:MaxTenuringThreshold 设置成6
- 这个值默以为15,即Survivor区对象履历15次Young GC后才进入老年代,设置成6就只需6次YGC就晋升到老年代了。默认情况下ES新生代采用 -XX:+UseParNewGC,老年代采用CMS垃圾采取器。
-Xss 设置为1M。
- 线程占用栈内存,默认每条线程为1M。从这个参数可看出一个进程下可创建的线程数量是有限制的,可视为创建线程的开销。
2. Swapping内存交换设置
2.1 禁用内存交换(/proc/sys/vm/swappiness),表明为什么要禁用内存交换:
内存交换到磁盘对服务器性能来说是致命的。想想看一个内存的操作必须是快速的。如果内存交换到磁盘上,一个100微秒的操作大概变成10毫秒,再想想那么多10微秒的操作时延累加起来。不难看出swapping对于性能是多么可怕。 最好的办法就是在你的操作体系中完全禁用swapping
- 第一步:禁用操作体系swapping
- 暂时禁用:sudo swapoff -a
- 永世禁用:修改参数的方法是修改/etc/sysctl.conf文件,加入vm.swappiness=xxx,并重起体系。这个操作相当于是修改假造体系中的/proc/sys/vm/swappiness文件,将值改为XXX数值。
如果不想重起,可以通过sysctl -p动态加载/etc/sysctl.conf文件,但建议这样做之前先清空swap。
- 第二步:以上体系参数设置完成,还要修改elasticsearch.yml设置:
bootstrap.memory_lock : true 锁定内存,防止举行内存的交换利用swapping
- 第三步:对于体系也要一些设置,否则大概无法启动。修改完需要重新启动机器。
- 修改文件/etc/security/limits.conf,末了添加以下内容。
- * hard memlock unlimited
- * soft memlock unlimited
复制代码
- 修改文件 /etc/systemd/system.conf ,分别修改以下内容。
- DefaultLimitNOFILE=65536
- DefaultLimitNPROC=32000
- DefaultLimitMEMLOCK=infinity
复制代码 3. elasticsearch.yml设置
3.1 index设置
index 缓冲区大小 ,默以为整个堆空间的10%
- indices.memory.index_buffer_size: 20%
复制代码 3.2 搜索设置
数据检索和计数请求线程池设置它的类型默以为fixed,size默以为(可用处理器的数量* 3) / 2) + 1,
- thread_pool.search.size: 5
复制代码 数据检索和计数请求线程池队列,队列的size默以为1000。
- thread_pool.search.queue_size: 1000
复制代码 3.3 写入设置
⚠️这个参数慎用!强制修改cpu核数,以突破写线程数限制
如果CPU性能开销有余,可以设置为摆设机器的CPU核数
- # processors: 16
- # Bulk pool
- thread_pool.bulk.size: 16 es6写法
- thread_pool.write.size: 16 es7写法
复制代码 4.其他设置
4.1 集群熔断内存比例设置
- PUT /_cluster/settings
- {
- "persistent" : {
- "indices.breaker.fielddata.limit": "60%",
- "indices.breaker.request.limit": "40%",
- "indices.breaker.total.limit": "70%"
- 。。。
- }
复制代码 在elasticsearch.yml中也可以设置
⚠️谨慎设置,会影响查询和插入,产生错误
-
- {
- "statusCode": 429,
- "error": "Too Many Requests",
- "message": "[circuit_breaking_exception]
- [parent] Data too large, data for [<http_request>] would be [2087772160/1.9gb],
- which is larger than the limit of [1503238553/1.3gb],
- real usage: [2087772160/1.9gb],
- new bytes reserved: [0/0b],
- usages [request=0/0b, fielddata=1219/1.1kb, in_flight_requests=0/0b, accounting=605971/591.7kb],
- with { bytes_wanted=2087772160 & bytes_limit=1503238553 & durability="PERMANENT" }"
- }
复制代码
- 紧张解决办法
关闭circuit查抄:
indices.breaker.type: none
4.1.1 fielddata内存限制设置
indices.breaker.fielddata.limit:fielddata的内存限制,默认60%?? 7.0版本默认是 40%
- 参数 indices.fielddata.cache.size 控制有多少堆内存是分配给fielddata。当你执行一个查询需要访问新的字段值的时候,将会把值加载到内存,然后试着把它们加入到fielddata。如果效果的fielddata大小凌驾指定的大小 ,为了腾出空间,别的值就会被驱逐出去。
- 默认情况下,这个参数设置的是无穷制 — Elasticsearch将永远不会把数据从fielddata里替换出去。
- 这个默认值是故意选择的:fielddata不是临时的cache。它是一个在内存里为了快速执行必须能被访问的数据结构,而且构建它代价非常昂贵。如果你每个请求都要重新加载数据,性能就会很差。
4.1.2 request内存限制设置
查询本身也会对相应的延迟产生重大影响。为了在查询时不触发熔断并导致Elasticsearch集群处于不稳定状态,
indices.breaker.request.limit:执行聚合的内存限制,默认40% 7.0版本默认是 60%
4.1.3 总体内存限制设置
可以根据查询的复杂性将indices.breaker.total.limit设置为适合您的JVM堆大小。此设置的默认值是JVM堆的70%。
indices.breaker.total.limit:综合上面两个,限制在70%以内 7.0版本默认是 90%
4.2 避免脑裂
网络非常大概会导致集群中节点分别出多个地区,地区发现没有 Master 节点的时候,会推举出了自己地区内 Maste 节点,导致一个集群被分裂为多个集群,使集群之间的数据无法同步,我们称这种征象为脑裂。
为了防止脑裂,我们需要在 Master 节点的设置文件中添加如下参数:
discovery.zen.minimum_master_nodes=(master_eligible_nodes/2)+1 //默认值为1
- 此中 master_eligible_nodes 为 Master 集群中的节点数。这样做可以避免脑裂的征象都出现,最大限度地提拔集群的高可用性。
- 只要不少于 discovery.zen.minimum_master_nodes 个候选节点存活,推举工作就可以顺遂举行。
二、优化篇
1、写入速率优化
1.1 设置持久化异步延时提交
- XPUT http://xxxx:9200/m_pd_cu_id_gps_2es_inc_hi_out/_settings -d '
- {
- "index.translog.durability" : "async",
- "index.translog.sync_interval" : "30s",
- "index.translog.flush_threshold_size" : "1024mb"
- }
-
复制代码 说明:
- (1)加大 Translog Flush ,目标是低沉 Iops、Writeblock。
默认情况下,将 index.translog.durability 设置为 request ,这意味着 Elasticsearch 仅在成功对主分片和每个已分配副本举行事件同步并提交事件后,才将索引、删除、更新或批量请求的成功报告给客户端。
如果将 index.translog.durability 设置为 async ,则 Elasticsearch 同步和提交事件日记仅在每个 index.translog.sync_interval 时执行,这意味着当节点规复时,在瓦解之前执行的任何操作都大概会丢失。
- (2)增加 Index Refresh 隔断,目标是淘汰 Segment Merge 的次数。
“index.translog.sync_interval” : “30s” 结合业务对于数据及时性要求,及时性要求不高的,可以设置更大。
将 Translog 多长时间同步到磁盘并提交一次。默以为5s。不允许小于100ms的值。
- (3)加大 Flush 设置
重要目标是把文件缓存体系中的段持久化到硬盘,当Translog的数据量到达 512MB 或者 30 分钟时,会触发一次 Flush。
“index.translog.flush_threshold_size” : “1024mb”
事件日记存储尚未安全地持久化在 Lucene 中的全部操作(即不是 Lucene 提交点的一部门)。只管可以读取这些操作,但是如果分片已制止并且必须规复,则需要重播它们。此设置控制这些操作的最大总大小,以防止规复泯灭太长时间。一旦到达最大大小,将举行刷新,从而生成新的 Lucene 提交点。默以为 512mb 。
1.2设置写入并发数,调解 Bulk 线程池和队列
修改elasticsearch.yml
- thread_pool.bulk.size: 16 //es6写法
- thread_pool.write.size: 16 //es7写法
复制代码 1.3 段归并优化
(1) 归并线程的速率优化:
⚠️ 7.0版本不再支持
Lucene 以段的情势存储数据。当有新的数据写入索引时,Lucene 就会主动创建一个新的段。随着数据量的变革,段的数量会越来越多,消耗的多文件句柄数及 CPU 就越多,查询服从就会降落。
由于 Lucene 段归并的盘算量巨大,会消耗大量的 I/O,所以 ES 默认采用较守旧的计谋,让配景定期举行段归并,如下所述:
- 索引写入服从降落:当段归并的速率掉队于索引写入的速率时,ES 会把索引的线程数量淘汰到 1。这样可以避免出现堆积的段数量发作,同时在日记中打印出“now throttling indexing”INFO 级别的“告诫”信息。
- 提拔段归并速率:ES 默认对段归并的速率是 20m/s,如果利用了 SSD,我们可以通过以下的命令将这个归并的速率增加到 100m/s。对大日记数据ELK Stack应用, 建议将其调大到100MB或更高. 可以通过API设置, 也可以写在设置文件中:
- PUT _cluster/settings
- {
- "persistent" : {
- "indices.store.throttle.max_bytes_per_sec" : "100mb"
- }
- }
复制代码 // 相应效果如下:
- {
- "acknowledged": true,
- "persistent": {
- "indices": {
- "store": {
- "throttle": {
- "max_bytes_per_sec": "100mb"
- }
- }
- }
- },
- "transient": {}
- }
复制代码 (2) 归并线程的数量:
保举设置为CPU焦点数的一半, 如果磁盘性能较差, 可以适当低沉设置, 避免发生磁盘IO堵塞:
- PUT employee/_settings
- {
- "index.merge.scheduler.max_thread_count" : 8
- }
复制代码 也可以在elasticsearch.yml 设置:
- index.merge.schedule`Ω`r.max_thread_count: 1
复制代码 说明:
- index.merge.scheduler.max_thread_count默认设置为Math.max(1, Math.min(4, Runtime.getRuntime().availableProcessors() / 2))但这适用于SSD设置。
- 对于HDD,应将其设置为1。机械磁盘在并发 I/O 支持方面比较差,所以我们需要低沉每个索引并发访问磁盘的线程数。这个设置允许 max_thread_count + 2 个线程同时举行磁盘操作,也就是设置为 1 允许三个线程。
(3) 归并计谋:目前大概用不到,高版本不再支持
merge计谋index.merge.policy有三种:
tiered(默认计谋);log_byete_size; log_doc。
- # 优先归并小于此值的segment, 默认是2MB:
- index.merge.policy.floor_segment
-
- # 一次最多归并多少个segment, 默认是10个:
- index.merge.policy.max_merge_at_once
-
- # 一次直接归并多少个segment, 默认是30个
- index.merge.policy.max_merge_at_once_explicit
-
- # 大于此值的segment不参与归并, 默认是5GB. optimize操作不受影响
- index.merge.policy.max_merged_segment
复制代码 (4)重并发缓存加大
设置索引缓冲buffer,最大512m,默认值是jvm的10%;
elasticsearch.yml :
- indices.memory.index_buffer_size : 20%
- indices.memory.min_index_buffer_size: 96mb
复制代码
- index buffer 的大小是全部的 shard 公用的对于每个 shard 来说,最多给 512mb,因为再大性能就没什么提拔了。ES 会将这个设置作为每个 shard 共享的 index buffer,那些特别活跃的 shard 会更多的利用这个 buffer。默认这个参数的值是 10%,也就是 jvm heap 的 10%。
- 已经索引好的文档会先存放在内存缓存中,等待被写到到段(segment)中。缓存满的时候会触发段刷盘(吃i/o和cpu的操作)。默认最小缓存大小为48m,不太够,最大为堆内存的10%。对于大量写入的场景也显得有点小。
2、查询速率优化
2.1 特定搜索场景,增加搜索线程池设置
默认情况下,Elasticsearch将重要用例是搜索。在需要增加检索并发性的情况下,可以增加用于搜索设置的线程池,与此同时,可以根据节点上的CPU中的焦点数量多少斟酌淘汰用于索引的线程池。
举例:更改设置文件elasticsearch.yml增加如下内容:
- thread_pool.search.queue_size: 500
复制代码 #queue_size允许控制没有线程执行它们的挂起请求队列的初始大小。
2.2 低沉刷新频率设置
- 10.10.60.15:9200/str/_settings -d
- {
- "refresh_interval": "5s"
- }
复制代码
- 刷新频率由 refresh_interval 参数控制,默认每 1 秒发生一次。也就是说,新插入的文档在刷新到段(内存中)之前,是不能被搜索到的。
- 关于是否需要及时刷新:
- 如果新插入的数据需要近乎及时的搜索功能,则需要频仍刷新。
- 如果对最新数据的检索相应没有及时性要求,则应增加刷新隔断,以提高数据写入的服从,从而应释放资源辅助提高查询性能。
- 关于刷新频率对查询性能的影响:
- 由于每刷新一次都会生成一个 Lucene 段,刷新频率越小就意味着同样时间隔断,生成的段越多。每个段都要消耗句柄和内存。
- 每次查询请求都需要轮询每个段,轮询完毕后再对效果举行归并。
- 也就意味着:refresh_interval 越小,产生的段越多,搜索反而会越慢;反过来说,加大 refresh_interval,会相对提拔搜索性能。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |