
1. 倒排索引Elasticsearch的搜索加速器倒排索引是Elasticsearch实现毫秒级搜索的核心数据结构。与传统数据库的正向索引不同它采用词项→文档的逆向映射方式。当文档入库时ES会自动进行分词处理将文本分解为独立的词项Term然后建立词项到文档的映射关系。举个例子假设我们有三篇技术文档文档1《分布式系统架构设计》文档2《高性能缓存技术》文档3《系统架构优化指南》经过标准分词器处理后生成的倒排表示例词项文档ID列表位置信息分布式[1]{1:[0]}系统[1,3]{1:[1], 3:[1]}架构[1,3]{1:[2], 3:[2]}设计[1]{1:[3]}这种结构使得搜索系统架构时ES只需查找系统→文档[1,3]查找架构→文档[1,3]取交集得到文档1和3 整个过程完全避免全表扫描时间复杂度从O(n)降到O(1)。关键技巧ES默认会对text类型字段自动建立倒排索引但对keyword类型则不会。需要精确匹配的字段应设为keyword类型。2. 分片机制分布式架构的核心设计2.1 分片的基本原理Elasticsearch通过分片Shard实现数据的水平切分和分布式存储。创建索引时就需要确定分片数例如PUT /my_index { settings: { number_of_shards: 5, number_of_replicas: 1 } }这表示该索引将被分成5个主分片每个主分片有1个副本。分片一旦设定就不能修改但副本数可以动态调整。2.2 分片的路由算法文档存入哪个分片由以下公式决定shard_num hash(_routing) % num_primary_shards默认使用文档ID作为_routing值。这种确定性路由保证相同ID的文档总是落到同一分片避免查询时全分片扫描。2.3 分片的查询流程当执行搜索请求时客户端请求发送到协调节点协调节点将查询广播到所有相关分片主分片或副本各分片并行执行本地搜索协调节点合并结果排序后返回避坑指南分片数不是越多越好。每个分片都会消耗内存和CPU资源。建议单个分片大小控制在30-50GB对于日增量小的业务甚至可以控制在10GB以内。3. 全链路性能调优实战3.1 写入性能优化批量写入使用bulk API建议每批5-15MB数据POST _bulk { index : { _index : test, _id : 1 } } { field1 : value1 } { index : { _index : test, _id : 2 } } { field1 : value2 }刷新间隔调整默认1秒刷新会导致频繁段合并PUT /my_index/_settings { index.refresh_interval: 30s }线程池配置针对写入密集型场景thread_pool: write: size: 16 queue_size: 100003.2 查询性能优化使用过滤器上下文filter不计算评分可利用缓存GET /_search { query: { bool: { must: [ { match: { title: elasticsearch }} ], filter: [ { range: { date: { gte: now-1d/d }}} ] } } }字段数据加载优化避免对text字段排序PUT /my_index/_mapping { properties: { user_id: { type: keyword, doc_values: true } } }3.3 JVM与操作系统调优堆内存设置不超过物理内存的50%且不超过32GB禁用交换分区sudo swapoff -a文件描述符限制ulimit -n 65535MMAP使用index.store.type: mmapfs4. 典型问题排查手册4.1 查询慢速问题现象搜索响应时间超过1秒排查步骤检查慢查询日志PUT /_settings { index.search.slowlog.threshold.query.warn: 1s, index.search.slowlog.threshold.query.info: 500ms }使用Profile API分析查询细节GET /my_index/_search { profile: true, query: {...} }检查分片是否均衡GET _cat/shards?v4.2 节点离线处理现象集群状态变红解决方案优先恢复主分片PUT _cluster/settings { persistent: { cluster.routing.allocation.enable: primaries } }手动重新路由分片POST _cluster/reroute { commands: [ { move: { index: my_index, shard: 2, from_node: node1, to_node: node2 } } ] }5. 实战经验总结在电商搜索场景的优化案例中我们通过以下措施将平均响应时间从800ms降到120ms将商品标题字段设置为textkeyword双字段对价格、类目等过滤字段启用doc_values使用bool查询分离匹配条件和过滤条件对热词查询结果启用请求缓存定期执行_forcemerge减少段数量对于日志分析场景则更注重写入性能采用时间滚动索引logs-2023-08-01关闭副本number_of_replicas:0设置较大的refresh_interval30s使用gzip压缩原始日志采用冷热分离架构