性能优化

ES 集群性能优化-实战篇

2019-06-21  本文已影响0人  架构技术专栏

一、前情提要

1、version
es 6.4
jdk 8

2、 先说下背景,目前公司使用elk 作为日志收集报警一条龙服务,并且skywalking 的agent采集数据也进入相同的es集群,目前使用的表现为,随着数据量持续增大。kibana 有时候都打不开,skywalking查询更别提了,而且数据不全,发现很多数据存储失败。下面就来跟进排查下。

3、简单的看下架构图

image.png

概念解析:

4、影响elasticsearch性能的因素

image.png

二、性能优化-内存篇

入手点很简单,直接看kibana监控如下:

image.png

如上图可以看出,监控图表不连续啊,居然出现很多断点情况,而且这只是一个node的监控,看整体监控的话会发现整个集群基本处于无法提供服务的状态(虽然是绿色的)。

通过JVM heap 会感觉出整个内存回收的频率不对劲啊最大,貌似一直在进行FULL GC 啊,马上查看下 gc.log

image.png

果不其然,一直在进行FULL GC,直接查看es jvm.options 配置

-Xms16g
-Xmx16g
-XX:CMSInitiatingOccupancyFraction=70

结合上图会发现16G 明显不够用吗,查看了下机器内存发现居然有128G ,啧啧,这么小气,才给es配置16g,好吧,整个简单,我来加大下不就够用了。

在加大这个内存的时候要注意一点,对于最大内存官方建议是整体内存的50%,但是最大不要超过32G ,这里我们设置30G,原因如下:

因为涉及到一个JVM OOPS的优化策略

然后继续优化,将我们的内存加大到30

-Xms30g
-Xmx30g

重启节点,如图:

image.png

诶,貌似内存q曲线正常了,非常不错嘛,很简单吗,然而并不是这样,随着时间推移,内存又发生了变化

image.png

发现FULL GC 的频率越来越快,而且老年代的内存基数越来越大,系统随着时间推移会恢复到频繁FULL GC 的状态,这么看内存中有数据滞留啊,翻看了下官方文档发现几个很重要的概念:

GET _cat/nodes?v&h=id,ip,port,r,ramPercent,ramCurrent,heapMax,heapCurrent,fielddataMemory,queryCacheMemory,requestCacheMemory,segmentsMemory

ES 的熔断策略,ES 本身有对内存的保护策略,以防止OOM

详情可查看官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/6.4/circuit-breaker.html#fielddata-circuit-breaker

来看图说话(图片来源于网络,ES的JVM heap按使用场景分为可GC部分和常驻部分。 可GC部分内存会随着GC操作而被回收; 常驻部分不会被GC,通常使用LRU策略来进行淘汰)

image.png
image.png

common space(可GC)

image.png

综上所述:

segment memory 这是没办法通过参数配置释放的,通常跟index息息相关,close index、force merge均会释放部分空间.

综上所述,需要保证 segment memory 和 可gc的空间 +固定空间比不超过100%。由于熔断器是按整个heap大小来计算的,所以如果segment memory 过大,仍然可能会导致OOM。

下面为设置其配置:

其实正常情况下es集群默认配置足够使用,这里我们控制下fielddata 的内存使用

indices.fielddata.cache.size: 20%

restart

su - elk -c "/data/secoo_program/elasticsearch-6.4.0/bin/elasticsearch -d"

优化内存后的使用情况


image.png
image.png

如图可看出,内存使用回收趋于平稳,再看下系统整体监控对比图

image.png image.png

可以看出 优化前后效果明显,优化前系统基本处于FULL GC 的 STW 阶段,导致整个系统随着数据逐渐增加而服务能力下降,优化后系统稳定运行提供快速检索能力。

三、性能优化-索引篇

优化了内存使用后,系统的稳定性得到了保障。因为我们的es主要用于日志和skywalking 的数据存储检索,其使用方式写入远远大于检索,所以对于其写入能力也有着一定的要求。

当前目前对于skywalking 的写入如下

image.png

可以发现其写入能力非常低

在优化前必然要了解其核心概念,优化都是基于理论基础而来的,网上有很多文章这里不详细说了,下面看一张图理解下:

image.png

上图展示了一个doc index/write请求过来,es为其建立倒排的过程,而index opt.的优化点就主要集中在该posting list building过程,

  1. doc write/index request comes
  2. 根据自定义的routingId字段或者docId选择routing shard
  3. 为了提高容错,doc双写
    • 写入es实例的memory buffer(此时doc未能被search)
    • 写入transLog的内存
  4. es实例在每个refresh interval里将heap里面的docs刷到lucene利用着的系统缓存里(此时doc能够被search)
  5. transLog根据配置的持久化到disk的策略,同步docs到磁盘(顺序写盘)
  6. transLog的clean up

先看一下优化参数模版

PUT _template/skywalking
{
  "index_patterns": "skywalking*",
  "settings": {
    "index.indexing.slowlog.threshold.index.debug" : "2s",
    "index.indexing.slowlog.threshold.index.info" : "5s",
    "index.indexing.slowlog.threshold.index.trace" : "500ms",
    "index.indexing.slowlog.threshold.index.warn" : "10s",
    "index.optimize_auto_generated_id" : "true",
    "index.refresh_interval" : "30s",
    "index.search.slowlog.threshold.fetch.debug" : "500ms",
    "index.search.slowlog.threshold.fetch.info" : "800ms",
    "index.search.slowlog.threshold.fetch.trace" : "200ms",
    "index.search.slowlog.threshold.fetch.warn" : "1s",
    "index.search.slowlog.threshold.query.debug" : "2s",
    "index.search.slowlog.threshold.query.info" : "5s",
    "index.search.slowlog.threshold.query.trace" : "500ms",
    "index.search.slowlog.threshold.query.warn" : "10s",
    "index.translog.durability" : "async",
    "index.translog.flush_threshold_size" : "1gb",
    "index.translog.sync_interval" : "60s"
  }
}

对于网上很多资料有很多优化参数,这里我们并不需要调整每一个,通过理论可以看出,对于写入影响点有以下几个:

memory Buffer -> FilesystemCache 影响参数 refresh_interval: 1s,(将新生成的segment 刷入文件系统缓存中,才可以被搜索到)

transLog-> Disk 每次 index、bulk、delete、update 完成的时候,一定触发刷新 translog 到磁盘上,才给请求返回 200 OK

transLog-> empty transLog 这个阶段主要影响内存的回收,可以根据 大小 条数 时间自由设定,默认30m | 200M flush

auto doc id 如果手动为es doc设置一个id,那么es在每个write req都要去确认那个id是否存在

再经过如上简单的参数优化后,整体索引情况如下

image.png

但3k 的index 速度也是远远达不到我们的要求的,这里将使用esrally 对单分区进行下写入压力测试。

四、性能优化-搜索篇(待完成)

上一篇 下一篇

猜你喜欢

热点阅读