Elasticsearch 避坑指南:我在项目中总结的 14 条实用经验
当前位置:点晴教程→知识管理交流
→『 技术文档交流 』
今天就把我在实际项目中积累的 ES 使用经验分享给大家,主要从索引设计、字段类型、查询优化、集群管理和架构设计这几个方面来展开。 索引设计:从基础到进阶1. 索引别名(alias):为变更留条后路刚开始做项目时,我习惯直接用索引名。直到有一次需要修改字段类型,才发现 ES 不支持直接修改映射,也不支持修改主分片数,必须重建索引。(**新增字段是可以的) 解决方案很简单:使用索引别名。业务代码中永远使用别名,重建索引时只需要切换别名的指向,整个过程用户无感知。 这就好比给索引起了个"外号",里面怎么换内容都不影响外面的人称呼它。 2. Routing 路由:让查询更精准在做 SaaS 电商系统时,我发现查询某个商家的订单数据特别慢。原来,默认情况下ES根据文档ID的哈希值分配分片,导致同一个商家的数据分散在不同分片上。 优化方案:使用商家 ID 作为 routing key,存储和查询数据时指定routing key。这样,同一个商家的所有数据都会存储在同一个分片上。 效果对比:
3. 分片拆分:应对数据增长当单个索引数据量持续增长时,单纯增加分片数并不是最佳方案。 我的经验是:
对于 SaaS 系统,ES单索引数据较大,且存在“超级大商户”,导致数据倾斜严重时,可以按商家ID%64取模进行索引拆分,比如
字段类型:选择比努力重要4. Text vs Keyword:理解它们的本质区别曾经有个坑:用户手机号用 text 类型存储,结果搜索完整的手机号却搜不到。原来 text 类型会被分词, 正确做法:
5. 多字段映射(multi-fields):按需使用不浪费ES 默认会为 text 字段创建 keyword 子字段,但这并不总是必要的。 我的选择:
6. 排序字段:选对类型提升性能用 keyword 字段做数值排序是个常见误区。比如价格排序, 推荐做法:
查询优化:平衡速度与精度7. 模糊查询:了解正确的打开方式在 ES 7.9 之前,wildcard 查询是个性能陷阱。它基于正则表达式引擎,前导通配符会导致全量词项扫描。 现在的方案:
8. 分页查询:避免深度分页的坑产品经理曾要求实现"无限滚动",我展示了深度分页的性能数据后,大家达成共识:业务层面避免深度分页才是根本解决方案。就像淘宝、Google 这样的大厂,也都对分页做了限制,这不仅是技术考量,更是用户体验的最优选择。 技术方案(仅在确实无法避免时考虑):
需要强调的是,这些技术方案都存在各自的局限性,业务设计上的规避始终是最佳选择。 集群管理:保障稳定运行9. 索引生命周期:自动化运维日志数据的特点是源源不断,如果不加管理,磁盘很快就会被撑满。 我的做法:
10. 准实时性:理解刷新机制很多新手会困惑:为什么数据写入后不能立即搜索? 原理:ES 默认 1 秒刷新一次索引,这是为了在实时性和写入性能之间取得平衡。 调整建议:
11. 内存配置:32G 限制的真相为什么 ES 官方建议不要超过 32G 内存? 技术原因:Java 的压缩指针技术在 32G 以内有效,超过这个限制会浪费大量内存。 实践建议:单个节点配置约50%内存,留出部分给操作系统。 架构设计:合理的分工协作12. ES 与数据库:各司其职曾经试图在 ES 里存储完整的业务数据,结果遇到数据一致性问题。 现在的方案:
好处:既享受 ES 的搜索能力,又保证数据的强一致性。 13. 嵌套对象:保持数据关联性处理商品规格这类数组数据时,用普通的 object 类型会导致数据扁平化,破坏对象间的关联。 解决方案:使用 nested 类型,保持数组内对象的独立性,确保查询结果的准确性。 14. 副本配置:读写平衡的艺术副本可以提升查询能力,但也不是越多越好。 经验值:
写在最后这些经验都是在解决实际问题中慢慢积累的。就像修路一样,开始可能只是简单铺平,随着车流量的增加,需要不断优化——设置红绿灯、划分车道、建立立交桥。使用 ES 也是同样的道理,随着业务的发展,需要不断调整和优化。 最大的体会是:理解原理比记住命令更重要。只有明白了为什么这样设计,才能在遇到新问题时找到合适的解决方案。
技术的价值不在于多复杂,而在于能否优雅地解决实际问题。与大家共勉。 转自https://www.cnblogs.com/xzqcsj/p/19291439 该文章在 2025/12/3 15:50:08 编辑过 |
关键字查询
相关文章
正在查询... |