ElasticSearch 性能优化教程
ES 优化
索引优化:
- 映射(Mapping):合理设计索引映射,避免使用动态映射,并为每个字段明确指定数据类型。
- 字段类型:对于不需要全文搜索的字段,使用
keyword
类型而非text
类型。 - 合并(Merging):通过配置
index.merge
参数优化段合并,以减少 I/O 开销。 - 刷新间隔:调整
index.refresh_interval
参数,减少刷新频率以提高写入性能(默认是 1 秒,可以根据实际需要调整)。
查询优化:
- 缓存:利用 ES 的节点查询缓存和过滤器缓存来加速常见查询。
- 分片首选项:设置
preference
参数来避免每次查询都访问不同的副本,从而提高缓存命中率。 - 分页:避免深分页,使用
search_after
或scroll
来处理大量结果集。
集群优化:
- 节点类型:配置专用的主节点、数据节点和客户端节点(协调节点)。
- 主节点:负责管理集群状态和索引元数据,建议配置数量为较小且为奇数(如 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
- 合理分配堆内存:一般建议将堆内存设置为系统内存的 50%,但不超过 32GB,以避免触发 Compressed Oops 的失效。建议将
垃圾回收器:
- 选择合适的垃圾回收器:Elasticsearch 7.x 版本及以上默认使用 G1 GC,适用于大多数场景。可以根据具体需求和环境考虑其他垃圾回收器(如 CMS),但 G1 GC 通常是较好的选择。确保在
jvm.options
中设置:1
-XX:+UseG1GC
- 选择合适的垃圾回收器:Elasticsearch 7.x 版本及以上默认使用 G1 GC,适用于大多数场景。可以根据具体需求和环境考虑其他垃圾回收器(如 CMS),但 G1 GC 通常是较好的选择。确保在
JVM 参数优化:
- 堆外内存:限制堆外内存,以避免 OOM(Out Of Memory)错误:
1
-XX:MaxDirectMemorySize=16g
- 垃圾回收日志:启用 GC 日志以监控和分析垃圾回收性能:
1
-Xlog:gc*:file=/var/log/elasticsearch/gc.log:time,level,tags
- 线程栈大小:调整线程栈大小,可以在某些场景下提高性能:
1
-Xss1m
- 堆外内存:限制堆外内存,以避免 OOM(Out Of Memory)错误:
堆栈优化:
- 内存锁定:在
elasticsearch.yml
中启用内存锁定:1
bootstrap.memory_lock: true
- 内存锁定:在
JVM 版本:
- 使用最新的稳定版本:确保使用最新的 Java 版本,并且是经过 Elasticsearch 测试和推荐的版本。Elasticsearch 通常推荐使用 Oracle JDK 或 OpenJDK。
线程池:
- 线程池配置:根据使用场景优化线程池配置(例如,搜索线程池、写线程池等),可以在
elasticsearch.yml
中配置:1
2thread_pool.search.size: 30
thread_pool.write.size: 30
- 线程池配置:根据使用场景优化线程池配置(例如,搜索线程池、写线程池等),可以在
Linux 系统优化
系统资源限制:
- 文件描述符:增加最大文件描述符数量(Elasticsearch 建议至少配置 65536)。
1
2echo "elasticsearch soft nofile 65536" >> /etc/security/limits.conf
echo "elasticsearch hard nofile 65536" >> /etc/security/limits.conf - 虚拟内存:增加虚拟内存映射数量(Elasticsearch 建议至少配置 262144)。
1
2echo "vm.max_map_count=262144" >> /etc/sysctl.conf
sysctl -w vm.max_map_count=262144
- 文件描述符:增加最大文件描述符数量(Elasticsearch 建议至少配置 65536)。
内存和交换:
- 禁用交换分区:Elasticsearch 对性能敏感,尽量避免使用交换分区。
1
2
3swapoff -a
echo "vm.swappiness = 1" >> /etc/sysctl.conf
sysctl -w vm.swappiness=1 - 锁定内存:允许 Elasticsearch 锁定内存以防止内存交换(需要在 Elasticsearch 配置文件
elasticsearch.yml
中设置bootstrap.memory_lock: true
)。1
2echo "elasticsearch soft memlock unlimited" >> /etc/security/limits.conf
echo "elasticsearch hard memlock unlimited" >> /etc/security/limits.conf
- 禁用交换分区:Elasticsearch 对性能敏感,尽量避免使用交换分区。
磁盘和文件系统:
- 文件系统类型:使用适合大规模读写操作的文件系统(如 ext4 或 XFS)。
- 磁盘 I/O 调度器:将磁盘 I/O 调度器设置为
noop
或deadline
,适合 SSD 磁盘。1
echo "noop" > /sys/block/sdX/queue/scheduler
- 磁盘分区对齐:确保磁盘分区对齐以提高 I/O 性能,特别是在使用 SSD 磁盘时。
网络设置:
- TCP 设置:优化 TCP 参数以提高网络性能。
1
2
3
4
5echo "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
- TCP 设置:优化 TCP 参数以提高网络性能。