美文网首页
es加载性能优化

es加载性能优化

作者: caster | 来源:发表于2020-11-09 10:52 被阅读0次

    本文主要讨论es加载速度的优化,有些优化会导致部分功能及数据安全性丧失,需要理性使用。
    网络中大部分的性能优化方案基本源于官网,如下位置:

    官网加载速度优化建议
    以下优化包含但不限于官方文档:

    1. indice相关设置

    {
      "settings": {
        "number_of_shards": n,//分片尽量设置多一些,能提高加载速度
        "number_of_replicas": 0,//副本设置为0,丧失数据安全性
        "refresh_interval": "-1",//刷新时间设置为-1,丧失数据实时性
        "merge": {
          "scheduler": {
            "max_thread_count": "1" //合并时最大线程数
          },
          "policy": {
            "max_merged_segment": "5gb",//段超过多大就不参与合并
            "segments_per_tier": "24"
          }
        },
        "translog.durability": "async",//异步translog,后续具体分析
        "translog.flush_threshold_size": "2gb",
        "translog.sync_interval": "100s"
      },
      "mappings": {
        "_doc": {
          "properties": {
            "name": {
              "type": "keyword",
              "doc_values":false, //不存储doc,丧失聚合排序等功能
              "index":false  //不索引,丧失查询功能
            }
          }
        }
      }
    }
    
    

    2. cluster相关设置

    indices.memory.index_buffer_size: 30%  //加大索引数据的缓存
    
    discovery.zen.ping_timeout: 60s      //超时时间,默认3s
    discovery.zen.fd.ping_interval: 30s    //节点多久ping一次master,默认1s
    discovery.zen.fd.ping_timeout: 60s    //等待响应时间,默认30s
    discovery.zen.fd.ping_retries: 6       //失败或超时后重试的次数,默认3
    
    thread_pool.write.size: cpus+1        //设置写线程数,默认cpus
    thread_pool.write.queue_size: 2000   //加大数据写队列,默认200
    
    

    具体分析以上配置:

    3. 关闭某些存储结构

    不需要聚合:doc_values:false
    不需要返回数据: _source:false
    只聚合不搜索:index:false
    不算分:norms:false
    能用keyword就不用text
    Index_options设置倒排索引具体内容
    ……

    4. bulk合理使用

    Resthighclient和Bulkprocess.add()均为线程安全,可多线程调用一个实例添加数据。
    控制client提交bulk在多节点间轮训(client.transport.sniff :true/restclient添加多个节点)
    设置bulk thread_poll线程数为cpu+1 ,增大队列2000(不要太大,会GC)
    setBulkSize(5mb):大小建议是5-15MB,默认不能超过100M
    bulkActions(1000):1000-5000个文档,如果你的文档很大,可以适当减少队列
    bulk的concurrentRequests:默认是1
    多线程并发写入,可以减少每次底层磁盘fsync的次数和开销。
    一旦发现es返回了TOO_MANY_REQUESTS的错误,JavaClient也就是EsRejectedExecutionException。此时那么就说明es是说已经到了一个并发写入的最大瓶颈了。
    如果加载过程中检测到HTTP429返回表示集群压力过大

    5. 增加/禁用refresh间隔

    refresh默认1s:用index.refresh_interval参数可以设置,这样会其强迫es每秒中都将内存中的数据写入磁盘中,创建一个新的segment file。
    延长或者禁止refresh

    PUT /test/_settings
    { "refresh_interval": "30s" } 
    
    PUT /test/_settings
    { "refresh_interval": -1 } 
    

    手动刷新数据查询:

    POST /_refresh 
    POST /test/_refresh 
    

    6. 关闭swap 内存交换

    如果要将es jvm内存交换到磁盘,再交换回内存,大量磁盘IO,性能很差。
    将/etc/fstab 文件中包含swap的行注释掉

    sed -i '/swap/s/^/#/' /etc/fstab
    

    系统关闭:

    swapoff -a/vm.swappiness = 1
    

    es锁定内存:
    2.4以前:

    bootstrap.mlockall: true
    

    新版本:

    bootstrap.memory_lock:true
    

    锁定内存需要系统配置:

    1. 修改/etc/security/limits.conf
    2. ulimit -l unlimited

    7. cache相关

    filesystem cache被用来执行更多的IO操作,如果我们能给filesystemcache更多的内存资源,那么es的写入性能会好很多。即保证运行es实例的服务器有多余闲置内存供给(除去配置的堆内存)

    8. 使用自动生成的id

    如果我们要手动给es document设置一个id,那么es需要每次都去确认一下那个id是否存在,这个过程是比较耗费时间的。如果我们使用自动生成的id,那么es就可以跳过这个步骤,写入性能会更好。对于你的业务中的表id,可以作为es document的一个field。

    9. buffer相关

    如果我们要进行非常重的高并发写入操作,那么最好将index buffer调大一些,indices.memory.index_buffer_size,这个可以调节大一些,设置的这个index buffer大小,是所有的shard公用的,但是如果除以shard数量以后,算出来平均每个shard可以使用的内存大小,一般建议,但是对于每个shard来说,最多给512mb,因为再大性能就没什么提升了。es会将这个设置作为每个shard共享的index buffer,那些特别活跃的shard会更多的使用这个buffer。默认这个参数的值是10%,也就是jvm heap的10%,如果我们给jvmheap分配10gb内存,那么这个index buffer就有1gb,对于两个shard共享来说,是足够的了。
    索引缓冲区用于存储新索引的文档。当它填满时,缓冲区中的文档将写入磁盘上的段。它在节点上的所有分片之间划分。

    必须在群集中的每个数据节点上进行配置:
    1. indices.memory.index_buffer_size:30%
    设置百分比 or 字节大小值。默认为10%,意味着10%分配给节点的总堆将用作所有分片共享的索引缓冲区大小。
    2. indices.memory.min_index_buffer_size
    如果index_buffer_size设置为百分比,则可以使用此设置指定最小值。默认为48mb。
    3. indices.memory.max_index_buffer_size
    如果index_buffer_size设置为百分比,则可以使用此设置指定最大值。默认为无限制。

    10. translog相关

    1. index.translog.sync_interval
    translog写入磁盘并提交频率。默认为5s。小于的值100ms是不允许的。
    2. index.translog.durability
    是否在每个索引,删除,更新或批量请求之后提交translog。此设置接受以下参数:
    request(默认):每个请求后提交。如果发生硬件故障,所有已确认的写入都已提交到磁盘。
    Async:每隔sync_interval时间提交。如果发生故障,将丢弃自上次自动提交以来的所有已确认写入。
    3. index.translog.flush_threshold_size
    一旦事务日志达到这个值,就会发生一次flush;默认值为512mb。调大就可以减少flush的次数以及大段的合并次数。可以适当调大,但不能超过indexBufferSize*1.5倍/(可能并发写的大索引数量),否则会触发限流,并导致JVM内存不释放。
    4. generation_threshold_size
    默认64M,系统支持,但官方文档没有的参数,超过该阈值会产生新的translog文件,要小于index.translog.flush_threshold_size,否则会影响flush,进而触发限流机制。
    示例:

    "translog.durability": "async",
    "translog.flush_threshold_size": "2gb",
    "translog.sync_interval": "100s",
    "translog.generation_threshold_size":"64mb"
    

    11. 段合并策略

    老版本策略:

    PUT /_cluster/settings
    {
        "persistent" : {
            "indices.store.throttle.max_bytes_per_sec" : "100mb"
        }
    }
    

    设置限流类型为 none 彻底关闭合并限流。等你完成了导入,记得改回 merge 重新打开限流

    PUT /_cluster/settings
    {
        "transient" : {
            "indices.store.throttle.type" : "none" 
        }
    }
    "merge.policy.max_merged_segment": "1000mb",
    

    当前策略:

    "merge" : {
          "scheduler" : {
            "max_thread_count" : "1" //merge时最大的线程数
          },
          "policy" : {  
            "max_merged_segment":"5gb",//超过此大小的segment不再参与合并 
            "floor_segment" : "2g",     //默认 2MB,小于这个大小的 segment,优先被归并  
            "segments_per_tier" : "24", //每个tier允许的segement 数,越小需要合并的操作越多,要大于at_once
            "max_merge_at_once" : "5"  //默认一次最多归并 10 个 segment
          }
    }
    

    merge 策略有三种:
    tiered
    log_byete_size
    log_doc

    默认情况下:
    1. index.merge.polcy.type: tiered
    索引创建时合并策略就已确定,不能更改,但是可以动态更新策略参数,一般情况下,不需要调整.如果堆栈经常有很多 merge, 可以尝试调整以下配置:
    2. index.merge.policy.floor_segment
    该属性用于阻止segment 的频繁flush, 小于此值将考虑优先合并,默认为2M,可考虑适当降低此值
    3. index.merge.policy.segments_per_tier
    该属性指定了每层分段的数量,取值约小最终segment 越少,因此需要 merge 的操作更多,可以考虑适当增加此值.默认为10,他应该大于等于 index.merge.policy.max_merge_at_once
    4. index.merge.policy.max_merged_segment
    指定了单个 segment 的最大容量,默认为5GB,可以考虑适当降低此值

    12. spark的使用

    使用spark写es,利用分布式的资源

    13. didi开源的fastindex分析

    核心思想:启动多个java进程(可以利用mr/spark)构造多个es实例写数据,然后将多个es实例的data目录下的索引文件(lucene索引)合并到线上集群的真实索引中(使用lucene自带的indexWriter.addIndexes(*) api)

    相关文章

      网友评论

          本文标题:es加载性能优化

          本文链接:https://www.haomeiwen.com/subject/fmxhbktx.html