高阶配置与调优

高阶配置与调优 #

面向生产环境的高级配置与性能调优指南。

系统级配置 #

文档内容
NUMA 配置NUMA 优化配置
NVME 配置NVME 存储优化
RAID 配置RAID 阵列配置
磁盘加密数据安全加密
国密配置国密算法支持
TLS 安全配置SSL/TLS 安全通信

高级调优 #

文档内容
集群协调调优选举、故障检测、集群状态发布参数调优
Ingest Pipeline 配置Pipeline 管理、Processor 使用、性能调优
索引排序索引排序配置与提前终止优化
高级配置参数集群、节点、索引和传输层配置参数分类参考

❓ 常见问题解答 #

Q1: Easysearch 服务启动很慢,如何排查? #

常见原因:

  1. JVM 堆设置过大,AlwaysPreTouch 在启动期间初始化全部堆内存页
  2. 节点发现或集群引导配置错误
  3. 分片恢复、索引加载或磁盘 I/O 较慢

诊断步骤:

# 检查实际生效的 JVM 参数
jcmd <pid> VM.flags

# 将路径替换为当前节点的 ${path.logs}/<cluster.name>.log
ES_LOG_FILE="/actual/path/to/path.logs/<cluster.name>.log"
grep -E "master not discovered|recovered|recovery|started" "$ES_LOG_FILE"

节点启动后,可继续检查仍在进行的分片恢复:

GET /_cat/recovery?v&active_only=true

Easysearch 启动器已经启用 AlwaysPreTouch。它可以改善运行期间的内存访问稳定性,但会增加大堆节点的启动耗时,不应将其 作为启动加速参数重复添加。调整堆内存时应保持 -Xms-Xmx 相同,并根据物理内存和工作负载确定大小,不能直接套用固定值。

discovery.seed_hosts 用于节点发现,并不是性能调优参数。应确认其中的地址可以解析和连通,并检查 cluster.initial_master_nodes 是否只用于新集群的首次引导。详见集群协调调优JVM 配置


Q2: 查询响应时间很长(>1s),如何优化? #

快速诊断:

# 启用慢查询日志
PUT /my-index/_settings
{
  "index.search.slowlog.threshold.query.warn": "500ms"
}

慢日志默认写入 ${path.logs}/<cluster.name>_index_search_slowlog.json${path.logs}/<cluster.name>_index_search_slowlog.log,不会自动写入 Easysearch 索引。可以在节点上直接检查对应文件:

# 将路径替换为当前节点实际配置的 path.logs
ES_LOG_DIR="/actual/path/to/path.logs"
ls "$ES_LOG_DIR"/*_index_search_slowlog.json "$ES_LOG_DIR"/*_index_search_slowlog.log

若需让所有新索引启用慢日志,应通过索引模板配置。完整配置方法见 日志配置

常见原因和解决方案:

原因症状解决方案
缓存未命中相同查询每次都慢检查查询/请求缓存统计和查询是否满足缓存条件;查询缓存默认已启用
Bool 查询过复杂CPU 占用高展平查询、使用 terms
高成本排序Fetch 或排序阶段耗时高减少排序数据量;固定排序模式可在新索引上验证索引排序并重建数据
GC 停顿间歇性延迟检查 GC 日志、堆占用和对象分配,再评估 JVM 调整
线程池拒绝查询超时定位被拒绝的线程池和请求,限制并发、降低单请求成本或扩容节点

Q3: 磁盘占用快速增长,如何控制? #

诊断方法:

# 查看分片大小
GET /_cat/shards?v&h=index,shard,prirep,state,store,node&s=store:desc

# 查看索引大小
GET /_cat/indices?v&h=index,store.size&s=store.size:desc

常见原因和解决方案:

原因症状解决方案
活跃索引段数较多小段多、合并持续运行优先等待后台自动合并,不要对仍在写入的索引执行 force merge
Translog 占用较大_stats/translog 显示大小持续增长检查 flush 阈值、保留租约和恢复活动;必要时在维护窗口执行 flush,而不是 refresh
编码器压缩率较低_source、stored fields 占用较高为新建或重建的冷数据索引评估 best_compression,并验证写入和查询开销
只读索引包含大量删除文档删除文档比例和磁盘占用较高确保磁盘余量后,对只读索引评估 only_expunge_deletes

Force merge 只适合不再写入的只读或归档索引,并可能在执行期间临时增加磁盘占用。详见 Refresh、Flush 与 Force Merge


Q4: 内存占用持续增长,最后 OOM,怎么办? #

首先保留现场并确认内存消耗来源:

GET /_nodes/stats/jvm,breaker?filter_path=nodes.*.jvm.mem,nodes.*.breakers

GET /_stats/fielddata,query_cache,request_cache,segments

发行包默认已经启用 -XX:+HeapDumpOnOutOfMemoryError 并配置 heap dump 路径。应确认目标目录存在、空间足够且受到访问控制, 再分析 OOM 时生成的 dump。若必须在线生成 dump,应在维护窗口执行,并预留至少与堆大小相当的磁盘空间:

jcmd <pid> GC.heap_dump /path/to/heap.hprof

生成 heap dump 可能造成长时间停顿,文件也可能包含敏感数据。不要在未确认物理内存、文件缓存、容器限制和实际对象占用前直接 增加堆。确需调整时,必须同时修改 -Xms-Xmx,并遵守JVM 配置 中的容量约束。


Q5: 集群不稳定,频繁出现节点掉线,怎么排查? #

诊断步骤:

# 查看集群健康状态
GET /_cluster/health?pretty

# 查看节点状态
GET /_cat/nodes?v&h=name,master,node.role,cpu,heap.percent,load_1m,disk.used_percent
# 将路径替换为当前节点的 ${path.logs}/<cluster.name>.log
ES_LOG_FILE="/actual/path/to/path.logs/<cluster.name>.log"
grep -Ei "master not discovered|node-left|disconnected|gc|circuit_breaking" "$ES_LOG_FILE" | tail -100

常见原因和解决方案:

原因症状解决方案
主节点发现超时频繁重选主先检查 DNS、网络、GC 和节点负载;确认误判后再评估故障检测参数
GC 停顿长节点假死优化 JVM 配置
网络不稳定间歇性连接问题修复丢包、延迟、DNS、防火墙或连接跟踪问题
线程池队列满请求拒绝定位请求来源,实施限流、背压、查询优化或节点扩容
磁盘空间不足触发磁盘水位、分片无法分配或索引变为只读限制新增写入并扩容;核对快照和保留策略后,只清理已确认过期的数据

cluster.fault_detection.* 属于静态节点配置。增大 timeout 或 retry count 会延迟真实故障的发现,只能在确认网络抖动或长时间 GC 是误判原因后修改,并需要重启节点。不要仅为消除掉线现象扩大故障检测阈值或线程池。

删除索引前必须确认索引用途、别名或数据流关系、保留要求,以及可用快照是否已成功完成并能够恢复。不要在未展开并核对实际索引 清单时使用通配符删除。


Q6: CPU 占用率很高(>80%),如何降低? #

短时 CPU 峰值并不一定表示故障。应结合查询延迟、写入吞吐、线程池拒绝和持续时间,确认是否存在资源饱和。

诊断方法:

# 查看热线程
GET /_nodes/hot_threads?threads=5&type=cpu&ignore_idle_threads=true

# 查看线程池统计
GET /_cat/thread_pool?v&h=node_name,name,active,queue,rejected

# 对照 JVM GC、查询、写入和合并统计
GET /_nodes/stats/process,jvm,indices?filter_path=nodes.*.process.cpu,nodes.*.jvm.gc,nodes.*.indices.search,nodes.*.indices.indexing,nodes.*.indices.merges

常见原因和解决方案:

原因症状解决方案
复杂查询或聚合search 线程持续占用 CPU使用 Profile API 定位高成本阶段,减少脚本、前导通配符、高基数聚合或过大的结果集
集中写入触发大量合并merge 线程和磁盘 I/O 同时升高削平写入峰值或提升存储能力,默认保留 merge 自动节流,不要直接修改 merge policy
GC 频繁GC 线程 CPU 高且暂停增加检查 GC 日志、分配速率、缓存和 breaker,再根据证据调整工作负载或 JVM
高成本排序search 线程 CPU 高减少命中文档和排序字段;只有固定排序长期匹配时,才在新建索引上验证索引排序并重建数据

Q7: 如何选择合适的 GC 算法? #

Easysearch 2.4.0 要求 JDK 21 或更高版本,发行配置默认使用 G1GC。堆大小本身不能作为切换 GC 的唯一依据;通常应保留发行包 默认设置,并先通过 GC 日志确认吞吐、暂停时间和对象分配问题。

jcmd <pid> VM.flags
jcmd <pid> GC.heap_info

CMS 不适用于当前支持的运行时。ZGC 等其他收集器也不是默认配置,只能在固定 JDK、真实业务负载和完整稳定性测试下验证后使用, 不能仅因为堆大于某个阈值直接切换。详细设置见JVM 配置


相关文档 #