当前位置: 首页 > news >正文

【架构实战】Elasticsearch搜索架构:从倒排索引到集群调优

【架构实战】Elasticsearch搜索架构:从倒排索引到集群调优

一、一个搜索请求,把整个集群打挂了

2019年双12,凌晨0点刚过5分钟,ES集群全部节点CPU 100%,查询超时,监控疯狂告警。

排查发现运营在后台跑了一句"查询所有包含’优惠券’关键词的订单",这条查询在3亿订单数据上做模糊匹配,瞬间打爆了整个集群。

更糟的是:运维经验不足,直接重启了全部节点——数据恢复花了6个小时,期间所有搜索功能不可用。

这就是ES运维的残酷现实:开箱即用很简单,扛住生产流量很难。

二、倒排索引——ES的核心原理

2.1 正排 vs 倒排

【正排索引(MySQL B+树)】 文档1 → "华为手机很好用" 文档2 → "小米手机性价比高" 文档3 → "iPhone也很好用" 查"手机" → 需要扫描所有文档 → O(n) 【倒排索引(Elasticsearch)】 词项(Term) → 文档列表 "华为" → [1] "手机" → [1, 2] "很好用" → [1, 3] "小米" → [2] "性价比" → [2] "iPhone" → [3] 查"手机" → 直接定位Term → [1, 2] → O(1)

2.2 分词器——搜索质量的根基

// 中文分词对比// Standard分词器(按字切分)"中华人民共和国"["中","华","人","民","共","和","国"]// IK分词器(按词切分)"中华人民共和国"["中华人民共和国","中华人民","中华","华人"]// 搜索"华人"时:// Standard: 匹配"华"+"人",结果包含"华为"、"中华"等大量噪音// IK: 精准匹配"华人",结果准确率大幅提升

三、ES集群架构设计

3.1 节点角色分离

┌──────────────┐ │ Client │ ← 负载均衡 + 请求分发 │ Nginx/Kibana│ └──────┬───────┘ │ ┌────────────┼────────────┐ │ │ │ ┌───────▼──────┐ ┌──▼──────┐ ┌───▼────────┐ │ Master Node │ │Data Node│ │Data Node │ │ × 3(候选) │ │ Hot │ │ Cold │ │ 集群管理 │ │ SSD │ │ HDD │ │ 不存数据 │ │ 热数据 │ │ 冷数据归档 │ └──────────────┘ └─────────┘ └────────────┘

角色分配原则

  • Master节点:3台,只做集群管理,不存数据,配置不用太高
  • Data Hot节点:SSD,存储热数据(最近30天),配置要高
  • Data Cold节点:HDD,存储冷数据,配置可降低
  • Client节点:可选的协调节点,分散查询压力

3.2 索引设计——分片策略

// 创建索引时决定分片和副本PUT/orders{"settings":{"number_of_shards":10,"number_of_replicas":2,"refresh_interval":"30s","routing.allocation.require.box_type":"hot"},"mappings":{"properties":{"order_id":{"type":"keyword"},"user_id":{"type":"long"},"product_name":{"type":"text","analyzer":"ik_max_word","search_analyzer":"ik_smart"},"amount":{"type":"scaled_float","scaling_factor":100},"status":{"type":"keyword"},"create_time":{"type":"date","format":"yyyy-MM-dd HH:mm:ss"}}}}

分片数计算公式

单分片最大容量 ≈ 50GB(SSD)或 30GB(HDD) 总分片数 = ceil(总数据量 / 50GB) 例:1TB数据 → 20个主分片 每个节点不超过 20分片/GB堆内存(经验值)

四、深入查询优化

4.1 避免深度分页

// 问题:Page 1000, Size 20GET/orders/_search{"from":20000,"size":20}// ES需要从每个分片取20020条,汇总后排序取20条// 内存开销:20020 * 分片数// 解决方案1:Search After(推荐)GET/orders/_search{"size":20,"query":{"match":{"status":"PAID"}},"sort":[{"create_time":"desc"},{"order_id":"desc"}],"search_after":[1625097600000,"123456"]// 上一页最后一条的排序值}// 解决方案2:业务限制深分页// 前端只允许查前100页,超过提示用户缩小查询范围

4.2 Filter vs Query

// Query(计算评分,有缓存)GET/orders/_search{"query":{"bool":{"must":[{"match":{"product_name":"手机"}}// 需要评分],"filter":[{"term":{"status":"PAID"}},// 精确过滤,有缓存{"range":{"create_time":{"gte":"2025-06-01"}}}]}}}// filter结果会被ES缓存,重复查询直接走缓存

4.3 聚合优化

// 大数据量聚合优化GET/orders/_search{"size":0,// 不需要原始文档,只要聚合结果"aggs":{"by_category":{"terms":{"field":"category_id","size":100,"execution_hint":"map"// 直接使用字段值,不计算全局序数},"aggs":{"total_amount":{"sum":{"field":"amount"}}}}}}

五、集群监控与调优

5.1 关键监控指标

指标正常值告警阈值说明
集群状态GreenYellow/Red有未分配分片
节点CPU< 60%> 80%查询压力大
堆内存使用< 75%> 85%接近GC临界点
磁盘使用< 70%> 85%水位线保护
Search Queue< 100> 500查询积压
GC频率< 5/min> 20/min频繁Full GC

5.2 堆内存配置

# jvm.options# 堆内存不超过32GB(压缩指针阈值)-Xms16g-Xmx16g# 堆内存不超过物理内存的50%# 剩下50%留给Lucene的OS Cache(文件缓存)# GC选型-XX:+UseG1GC-XX:MaxGCPauseMillis=200

5.3 索引生命周期管理(ILM)

// 自动管理索引的生命周期PUT_ilm/policy/orders_policy{"phases":{"hot":{"min_age":"0ms","actions":{"rollover":{"max_size":"50gb","max_age":"1d"}}},"warm":{"min_age":"30d","actions":{"forcemerge":{"max_num_segments":1},"shrink":{"number_of_shards":1}}},"cold":{"min_age":"60d","actions":{"allocate":{"require":{"box_type":"cold"}}}},"delete":{"min_age":"90d","actions":{"delete":{}}}}}

六、双11扛压实战

压测发现的问题和优化: 1. 热点分片 → 添加routing,按user_id路由 2. 查询慢 → 用filter替代query,利用缓存 3. 聚合慢 → eager_global_ordinals预加载 4. GC频繁 → 堆内存从32G降到16G(Lucene用OS Cache) 5. 写入慢 → refresh_interval从1s改为30s 6. 凌晨数据倾斜 → 用rollover按时间切分索引 最终结果: - 峰值写入:50万 docs/s - 查询P99:< 200ms - 集群规模:15个Data Hot + 5个Data Cold + 3个Master

七、总结

ES的调优之路就是不断做减法的过程:减少扫描、减少排序、减少聚合、减少不必要的字段。

核心实践

  1. 倒排索引是灵魂——理解分词和倒排原理才能写出高效查询
  2. 能用filter不用query——filter有缓存,query要计算评分
  3. 深分页是集群杀手——用search_after代替from/size
  4. 堆内存不超过32GB——剩下内存留给Lucene的OS Cache
  5. ILM自动化索引生命周期——Hot/Warm/Cold/Delete四阶段托管
  6. 监控先行——堆内存、队列长度、GC频率是三大关键指标

血的教训:ES集群挂了不要直接重启所有节点,先停写入流量,恢复Master节点,等集群状态Green后再逐个恢复Data节点。


个人观点,仅供参考

http://www.jsqmd.com/news/1173634/

相关文章:

  • 2026年7月沈阳宏碁售后本地化服务全景|交通指引气候养护到店全攻略 - 大品牌推荐
  • TPA3138D2音频放大器与PIC18F85K22微控制器的应用解析
  • 用make_blobs构建业务可信的虚构合成数据
  • 专业开发者如何实现浏览器Cookie的安全本地导出:Get cookies.txt LOCALLY深度解析
  • Hydra(九头蛇)工具使用(非常详细)从零基础入门到精通,看完这一篇就够了。
  • Spring Boot 3 + Vue 3 + MySQL 乒乓球室管理系统源码 前后端分离项目实战
  • LTC1864 ADC与PIC24F微控制器的信号采集系统设计
  • 告别隐私泄露!这款Windows离线语音识别工具,让你的会议记录效率提升300%
  • 王国保卫战 1-3 部 Lua 脚本反编译实战:7-Zip + LJD 工具链配置与参数修改
  • 2026年7月呼和浩特机械革命售后本地化服务全景|交通指引气候养护到店全攻略 - 品牌售后
  • 遗传算法工程化实践:从早熟收敛到可诊断优化系统
  • Adobe Animate 2024 父子级关系:3步完成行星公转动画(附图层绑定技巧)
  • shim-review完整指南:从零开始掌握启动加载器安全评估
  • C++系统化学习路径:从零基础到实战项目的完整指南
  • MCP3551与PIC18F24J11高精度ADC系统设计与优化
  • Linux命令与基础操作指南
  • 2026年7月沈阳宏碁售后维修权益与质保政策解读|在保过保全知道 - 大品牌推荐
  • Unity Recorder:游戏开发者的4K多机位录制与性能优化实战指南
  • 推荐卤制菜品色泽均匀的卤料 - 中媒介
  • 找提供开业全程指导的火锅加盟品牌 - 中媒介
  • 国家区域医疗中心一院两区全栈国产化落地实战:北京积水潭医院贵州医院双院区信创改造深度解析
  • 3步快速下载Wallpaper Engine创意工坊壁纸:免费图形化工具终极指南
  • WaveTools鸣潮工具箱:解锁游戏性能与数据管理的一站式解决方案
  • 遗传算法实战进阶:精英保留、自适应变异与小生境技术详解
  • 魔兽争霸III现代化升级指南:Warcraft Helper让你的经典游戏重获新生
  • A3908与PIC18F4550实现高精度电机控制方案
  • OpenCore Legacy Patcher:让老旧Mac重获新生的终极开源解决方案
  • TMC7300与PIC32MX664F064L在直流电机控制中的优势与实践
  • 三十年信誉铸就品牌:易奢福在武汉钻石回收市场的“金字招牌” - ys韩
  • 终极分屏游戏神器:Nucleus Co-op 完全指南