ElasticSearch 性能优化教程

ES 优化

  • 索引优化

    • 映射(Mapping):合理设计索引映射,避免使用动态映射,并为每个字段明确指定数据类型。
    • 字段类型:对于不需要全文搜索的字段,使用 keyword 类型而非 text 类型。
    • 合并(Merging):通过配置 index.merge 参数优化段合并,以减少 I/O 开销。
    • 刷新间隔:调整 index.refresh_interval 参数,减少刷新频率以提高写入性能(默认是 1 秒,可以根据实际需要调整)。
  • 查询优化

    • 缓存:利用 ES 的节点查询缓存和过滤器缓存来加速常见查询。
    • 分片首选项:设置 preference 参数来避免每次查询都访问不同的副本,从而提高缓存命中率。
    • 分页:避免深分页,使用 search_afterscroll 来处理大量结果集。
  • 集群优化

    • 节点类型:配置专用的主节点、数据节点和客户端节点(协调节点)。
    • 主节点:负责管理集群状态和索引元数据,建议配置数量为较小且为奇数(如 3 个)。
    • 数据节点:负责存储数据和处理搜索、聚合操作,需要较高的内存和磁盘 I/O。
    • 客户端节点:只负责处理请求和分发,不存储数据和索引,不参与集群管理。
    • 分片数量:合理配置索引的分片数量和副本数量,太多的分片会导致管理开销增加,而太少的分片则可能无法充分利用集群资源。
    • 副本数量:在生产环境中,至少配置一个副本以提高数据的可用性。
  • 硬件优化

    • 磁盘:使用高速 SSD 磁盘,提高读写速度。
    • CPU:多核 CPU 有助于处理并发查询和索引操作。
    • 内存:确保有足够的可用内存,因为 ES 需要将索引数据和文件系统缓存保存在内存中。一般建议为 ES 分配 50% 的物理内存给 JVM 堆内存,但不超过 32GB。
  • 监控和维护

    • 监控:使用 X-Pack Monitoring、Elasticsearch-head、ES-client、Cerebro 等工具实时监控集群健康状况。
    • 日志管理:定期检查和清理日志,防止磁盘空间不足。
    • 快照备份:定期进行快照备份,确保数据可以恢复。

JVM 优化

  • 堆内存设置

    • 合理分配堆内存:一般建议将堆内存设置为系统内存的 50%,但不超过 32GB,以避免触发 Compressed Oops 的失效。建议将 -Xms-Xmx 设置为相同值,以避免动态调整带来的性能开销。可以在 jvm.options 文件中配置:
      1
      2
      -Xms16g
      -Xmx16g
  • 垃圾回收器

    • 选择合适的垃圾回收器:Elasticsearch 7.x 版本及以上默认使用 G1 GC,适用于大多数场景。可以根据具体需求和环境考虑其他垃圾回收器(如 CMS),但 G1 GC 通常是较好的选择。确保在 jvm.options 中设置:
      1
      -XX:+UseG1GC
  • JVM 参数优化

    • 堆外内存:限制堆外内存,以避免 OOM(Out Of Memory)错误:
      1
      -XX:MaxDirectMemorySize=16g
    • 垃圾回收日志:启用 GC 日志以监控和分析垃圾回收性能:
      1
      -Xlog:gc*:file=/var/log/elasticsearch/gc.log:time,level,tags
    • 线程栈大小:调整线程栈大小,可以在某些场景下提高性能:
      1
      -Xss1m
  • 堆栈优化

    • 内存锁定:在 elasticsearch.yml 中启用内存锁定:
      1
      bootstrap.memory_lock: true
  • JVM 版本

    • 使用最新的稳定版本:确保使用最新的 Java 版本,并且是经过 Elasticsearch 测试和推荐的版本。Elasticsearch 通常推荐使用 Oracle JDK 或 OpenJDK。
  • 线程池

    • 线程池配置:根据使用场景优化线程池配置(例如,搜索线程池、写线程池等),可以在 elasticsearch.yml 中配置:
      1
      2
      thread_pool.search.size: 30
      thread_pool.write.size: 30

Linux 系统优化

  • 系统资源限制

    • 文件描述符:增加最大文件描述符数量(Elasticsearch 建议至少配置 65536)。
      1
      2
      echo "elasticsearch soft nofile 65536" >> /etc/security/limits.conf
      echo "elasticsearch hard nofile 65536" >> /etc/security/limits.conf
    • 虚拟内存:增加虚拟内存映射数量(Elasticsearch 建议至少配置 262144)。
      1
      2
      echo "vm.max_map_count=262144" >> /etc/sysctl.conf
      sysctl -w vm.max_map_count=262144
  • 内存和交换

    • 禁用交换分区:Elasticsearch 对性能敏感,尽量避免使用交换分区。
      1
      2
      3
      swapoff -a
      echo "vm.swappiness = 1" >> /etc/sysctl.conf
      sysctl -w vm.swappiness=1
    • 锁定内存:允许 Elasticsearch 锁定内存以防止内存交换(需要在 Elasticsearch 配置文件 elasticsearch.yml 中设置 bootstrap.memory_lock: true)。
      1
      2
      echo "elasticsearch soft memlock unlimited" >> /etc/security/limits.conf
      echo "elasticsearch hard memlock unlimited" >> /etc/security/limits.conf
  • 磁盘和文件系统

    • 文件系统类型:使用适合大规模读写操作的文件系统(如 ext4 或 XFS)。
    • 磁盘 I/O 调度器:将磁盘 I/O 调度器设置为 noopdeadline,适合 SSD 磁盘。
      1
      echo "noop" > /sys/block/sdX/queue/scheduler
    • 磁盘分区对齐:确保磁盘分区对齐以提高 I/O 性能,特别是在使用 SSD 磁盘时。
  • 网络设置

    • TCP 设置:优化 TCP 参数以提高网络性能。
      1
      2
      3
      4
      5
      echo "net.ipv4.tcp_retries2 = 5" >> /etc/sysctl.conf
      echo "net.ipv4.tcp_keepalive_time = 300" >> /etc/sysctl.conf
      echo "net.ipv4.tcp_keepalive_intvl = 60" >> /etc/sysctl.conf
      echo "net.ipv4.tcp_keepalive_probes = 9" >> /etc/sysctl.conf
      sysctl -p