• elasticsearch性能优化


    1. 硬件相关

    1.1 硬盘

    一块好的硬盘,会带来ES整体性能10倍以上提升,推荐在datanode节点上使用SSD硬盘,索引的data目录,存放在SSD硬盘上。
    1.2 内存

    建议内存>128G时,ES使用的JVM内存为30G,lucene会消耗大量的cache,如果索引文件很大,建议预留足够多的cache给lucene使用;
    如果内存<64G时,需要综合考虑单节点上索引文件的大小来评估,如果索引文件较大,建议ES JVM内存配置为16G,留下足够的内存给cache使用;

    2. 操作系统相关

    2.1 调整磁盘参数

    磁盘blockdev参数的readbuffer,建议调整为32
    可以通过命令 blockdev --getra /dev/vdb 查看,需要sudo权限,通过命令 blockdev --setra 32 /dev/vdb 进行调整;

    3. ES相关

    3.1 集群相关

    检查集群单个datanode节点的负载情况

    • 可以通过命令 GET _cat/nodes?v 来查看,重点关注各个节点的 heap.percent和ram.percent指标;
    • heap.percent表示ES使用的JVM内存情况,该值应该低于75,如果长时间大于75,表示JVM内存配置不够,如果JVM已经配置到30G,则表示该Datanode节点上的压力较大,需要考虑增加Datanode节点来分摊压力;
    • ram.percent 表示机器上内存的使用情况,实际对应linux上的
      used+cache内存使用情况,如果该值接近100%,则表示机器上cache内存不够用,主要是由于ES检索中,lucene会消耗大量cache内存,如果cache不够,会导致lucene无法将部分文件加载到cache中,会频繁从磁盘中进行读取,导致查询延时加大;

    检查集群上各个节点上的shard分布情况
    可以通过命令 GET _cat/shards?v 来查看,重点关注单个datanode上的shard数量,以及shard的总大小;
    建议解决方案:

    • 如果datanode节点的压力过载,那就要设法降低datanode节点上的压力,主要是要降低节点上活跃的shard数量
    • 评估索引是否在使用,关闭不用的索引
    • 评估索引的副本数是否合理,降低副本数
    • 如果只有部分datanode节点压力过载,可能原因是这些节点上的索引数据量较大,并且较为活跃,可以手工移动shard到其他压力相对较小的datanode上,注意手工调整前,需要先关闭集群的分片自动分配机制,调整完成后再打开;

    3.2 索引相关

    • 检查索引分片数

    索引分片数不是越少越好,也不是越多越好,需要结合索引文件的大小,并发写入、查询的性能要求,进行调优,在分片数和性能之间达到一个平衡即可;
    ES官方建议,一个分片的大小在10-40G之间,具体要结合索引的mapping复杂度来进行实际调优;
    索引的分片数,是在索引创建的时候设置的,无法进行动态调整,如果要调整,需要通过新建索引,然后将旧索引的数据,通过reindex命令迁移到新索引中来进行;

    • 检查索引副本数

    副本数不是越多越好,副本存在的意义,最主要是保障数据的可靠性,另外可以提升查询QPS,但是也会给集群带来翻倍的资源消耗;
    建议在性能满足要求的情况下,谨慎增加副本数,没有没有特殊场景,使用默认的副本数1即可;
    参考命令
    curl -XPUT “http://127.0.0.1:9200/{index-name}/_settings” -H “Content-Type: application/json” -d ‘{
    “number_of_replicas” : 0
    }’

    • 调整refreshtime参数

    refreshtime主要用于索引有写入场景时,写入的数据多久可以被检索到,refreshtime默认为1s,表示数据通过bulk接口写入后,最多1s后数据可以被写入到cache中(不是磁盘),然后就可以被检索到;
    如果ES仅用于检索,没有写入场景,则可以将refreshtime设置为-1;
    如果ES有写入场景,但是对检索实时性要求不高,可以将refreshtime设置为一个较大的值,比如60s;
    参考命令
    curl -XPUT “http://127.0.0.1:9200/{index-name}/_settings” -H “Content-Type: application/json” -d ‘{
    “refresh_interval”: “60s”
    }’

    • 调整translog参数

    translog存在的意义,是为了保证数据可靠性,当新写入的数据通过refresh刷新到cache,还没有写到磁盘时,如果发生丢失,可以从translog中进行恢复,ES中默认每30分钟进行一次flush操作,或者当translog的数据达到某个上限的时候会进行一次flush操作;
    而translog的可靠性如何保证呢,ES中默认是每5s将synclog写入磁盘,将这个间隔 index.translog.sync_interval 调大,可以减少磁盘IO的次数;另外,也可以适当调大translog文件多大时会自动写入磁盘的阈值,目的也是为了减少磁盘IO次数;
    参考命令
    curl -XPUT “http://127.0.0.1:9200/index/_settings?pretty” -d '{
    “index.translog.durability”: “async”,
    “index.translog.flush_threshold_size”: “1gb”,
    “index.translog.sync_interval”: “30s”
    }

    curl -XPUT ‘192.168.2.181:9200/index/_settings?pretty’ -H “Content-Type: application/json” -d '{
    “index.translog.durability”: “async”,
    “index.translog.flush_threshold_size”: “1gb”,
    “index.translog.sync_interval”: “30s”
    }

    • 检查segment参数

    segment表示shard中的分段,ES中每次flush,会生成一个segment,然后再通过专门的merge线程,对segment进行merge,在检索时,ES会依次去每个segment检索,segment越多,会导致检索效率越低;
    通过 _cat/shards?v&h=index,shard,prirep,segmentsCount 可以查到shard的segment数量,该值越大,表示shard中存在的分段数量越多,
    如果索引后续不会再有大规模的写操作,建议可以通过 forcemerge 命令,对segment进行强制合并,可以指定合并后的segment数量, 但是要注意,segment合并操作,会消耗大量的磁盘IO,也会占用两倍于shard大小的磁盘空间,建议在确保磁盘空间足够的情况下,选择闲时进行merge操作;

  • 相关阅读:
    Pytorch API
    一种优雅的Golang的库插件注册加载机制
    混合开发架构|Android工程集成React Native、Flutter、ReactJs
    LintCode 87: Remove Node in Binary Search Tree BST操作经典题
    使用PHP对接企业微信审批接口的问题与解决办法(二)
    南大通用数据库-Gbase-8a-学习-14-LOAD加载数据
    Vue Router跨域报错的原因和解决方法
    使用 CRD 开启您的 Ingress 可观测之路
    以太坊分水岭:建立自我延续的生态系统
    ASP.NET Core 分层服务注入思想实现
  • 原文地址:https://blog.csdn.net/qq_31024251/article/details/126952494