Elasticsearch搜索引擎深度解析:把搜索核心讲透,面试都是小菜

Elasticsearch搜索引擎深度解析:把搜索核心讲透,面试都是小菜

🎯 写在前面:在大数据时代,全文搜索是每个系统必备的功能。Elasticsearch作为分布式搜索的标杆,以其强大的全文搜索能力和水平扩展能力,成为搜索领域的不二之选。但你真的了解ES的底层原理吗?这篇文章,将带你深度剖析Elasticsearch!

一、核心原理:倒排索引

1.1 正排索引 vs 倒排索引

css 复制代码
┌─────────────────────────────────────────────────────────────────────┐
│                    正排索引 vs 倒排索引                              │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  正排索引(MySQL默认):                                              │
│  ┌─────────┬───────────────────────────────────┐                    │
│  │  文档ID  │              文档内容              │                    │
│  ├─────────┼───────────────────────────────────┤                    │
│  │    1    │  我爱北京天安门                   │                    │
│  │    2    │  北京是中国的首都                 │                    │
│  │    3    │  天安门在中国北京                 │                    │
│  └─────────┴───────────────────────────────────┘                    │
│  查询方式:文档ID → 文档内容                                          │
│                                                                      │
│  倒排索引(ES采用):                                                │
│  ┌───────────┬───────────────────────────────┐                     │
│  │    词    │              文档ID              │                     │
│  ├───────────┼───────────────────────────────┤                     │
│  │    我    │              [1]                 │                     │
│  │   天安门  │          [1, 3]                 │                     │
│  │   北京    │          [1, 2, 3]              │                     │
│  │   中国    │          [2, 3]                 │                     │
│  │   首都    │              [2]                 │                     │
│  │   是      │              [2]                 │                     │
│  └───────────┴───────────────────────────────┘                     │
│  查询方式:词 → 包含该词的文档列表                                    │
│                                                                      │
│  优势:查询"北京",直接返回[1,2,3],无需扫描全表!                    │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘

1.2 倒排索引详细结构

arduino 复制代码
┌─────────────────────────────────────────────────────────────────────┐
│                      倒排索引结构                                    │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  ┌────────────────────────────────────────────────────────────────┐ │
│  │                      Dictionary(词典)                          │ │
│  │  包含所有term,按字典序排列,支持二分查找                          │ │
│  └────────────────────────────────────────────────────────────────┘ │
│                              ↓                                        │
│  ┌────────────────────────────────────────────────────────────────┐ │
│  │                      Posting List(倒排列表)                     │ │
│  │  每个term对应一个列表,记录包含该term的文档ID                     │ │
│  │  [doc1, doc2, doc3, ...]                                       │ │
│  └────────────────────────────────────────────────────────────────┘ │
│                              ↓                                        │
│  ┌────────────────────────────────────────────────────────────────┐ │
│  │                      FST(有限状态机)                          │ │
│  │  用于前缀查询,如"开*"匹配"开放"、"开始"                        │ │
│  └────────────────────────────────────────────────────────────────┘ │
│                                                                      │
│  ┌────────────────────────────────────────────────────────────────┐ │
│  │                      Skip List(跳表)                          │ │
│  │  用于AND/OR运算加速,避免逐个遍历Posting List                    │ │
│  └────────────────────────────────────────────────────────────────┘ │
│                                                                      │
│  ┌────────────────────────────────────────────────────────────────┐ │
│  │                      Bitmap(位图)                              │ │
│  │  文档数量少时,使用bitset存储,节省空间                          │ │
│  └────────────────────────────────────────────────────────────────┘ │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘

1.3 分词器原理

java 复制代码
// ES分词流程
"我是程序员,在北京工作" 
    ↓ Analyzer
["我", "是", "程序", "程序员", "员", "在", "北京", "工作"]

/**
 * 分词器组成
 */
public class AnalyzerComponents {
    
    // 1. Character Filter(字符过滤器)
    // - HTML Strip:去除HTML标签
    // - Mapping:字符映射(如把":"替换为"_")
    // - Pattern Replace:正则替换
    
    // 2. Tokenizer(分词器)
    // - Standard:默认分词,按单词分割
    // - Keyword:不分词,整个字符串作为一个token
    // - Whitespace:按空格分割
    // - Punctuation:按标点分割
    
    // 3. Token Filter(词元过滤器)
    // - Lowercase:转小写
    // - Stop:去停用词(the, a, is)
    // - Synonym:同义词处理
    // - Stemming:词干提取(running → run)
}

// 自定义分词器
PUT /my_index
{
  "settings": {
    "analysis": {
      "char_filter": {
        "my_char_filter": {
          "type": "mapping",
          "mappings": ["& => and"]
        }
      },
      "tokenizer": {
        "my_tokenizer": {
          "type": "pattern",
          "pattern": "[,\\s]+"  // 按逗号和空格分割
        }
      },
      "filter": {
        "my_synonym": {
          "type": "synonym",
          "synonyms": [
            "程序员,码农,程序猿",
            "北京,帝都"
          ]
        },
        "my_stopwords": {
          "type": "stop",
          "stopwords": ["的", "了", "在"]
        }
      },
      "analyzer": {
        "my_analyzer": {
          "type": "custom",
          "char_filter": ["my_char_filter"],
          "tokenizer": ["my_tokenizer"],
          "filter": ["lowercase", "my_stopwords", "my_synonym"]
        }
      }
    }
  }
}

二、数据结构:Shard与Segment

2.1 ES数据存储架构

scss 复制代码
┌─────────────────────────────────────────────────────────────────────┐
│                      ES数据存储架构                                 │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  Index(索引)                                                       │
│    ↓                                                                 │
│  ┌────────┬────────┬────────┐                                      │
│  │ Shard 0│ Shard 1│ Shard 2│  ← 主分片(Primary Shard)           │
│  │  (P0)  │  (P1)  │  (P2)  │                                      │
│  └────────┴────────┴────────┘                                      │
│         ↓           ↓           ↓                                   │
│  ┌────────┬────────┬────────┐                                      │
│  │ Shard 0│ Shard 1│ Shard 2│  ← 副本分片(Replica Shard)        │
│  │  (R0)  │  (R1)  │  (R2)  │                                      │
│  └────────┴────────┴────────┘                                      │
│                                                                      │
│  Shard = Lucene Index                                               │
│  ↓                                                                   │
│  ┌────────────────────────────────────────────────────────────────┐ │
│  │                    Segment(分段)                              │ │
│  │  每个Shard包含多个Segment(_segments API查看)                  │ │
│  │  新数据写入新Segment,查询时并行搜索所有Segment                  │ │
│  └────────────────────────────────────────────────────────────────┘ │
│                              ↓                                        │
│  ┌────────────────────────────────────────────────────────────────┐ │
│  │                    Document写入流程                             │ │
│  │  1. 写入内存Buffer                                             │ │
│  │  2. 写入translog(保证持久性)                                  │ │
│  │  3. refresh后生成Segment                                       │ │
│  │  4. flush时清空Buffer和translog                                │ │
│  └────────────────────────────────────────────────────────────────┘ │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘

2.2 文档写入流程

java 复制代码
/**
 * 文档写入完整流程
 */

// 1. 客户端请求
PUT /my_index/_doc/1
{
  "name": "张三",
  "age": 28,
  "skills": ["Java", "Python"]
}

// 2. 请求路由到主分片
// hash(document_id) % number_of_shards = primary_shard

// 3. 主分片写入流程
/**
 * ┌─────────────────────────────────────────────────────────────────┐
 * │                    写入流程                                      │
 * │                                                                 │
 * │  1. 写入内存Buffer(不可搜索)                                   │
 * │          ↓                                                       │
 * │  2. 写入Translog(保证持久性)                                  │
 * │          ↓                                                       │
 * │  3. 定期refresh(默认1秒,可配置)                              │
 * │          ↓                                                       │
 * │  4. 生成新Segment(可搜索)                                     │
 * │          ↓                                                       │
 * │  5. Segment定期flush(清空Buffer和Translog)                   │
 * │          ↓                                                       │
 * │  6. Segment定期merge(合并小Segment,优化查询)                 │
 * │                                                                 │
 * └─────────────────────────────────────────────────────────────────┘
 */

// 4. 并行复制到副本分片
// 只有所有副本都写入成功,才算写入成功(consistency参数可调)

2.3 Segment合并机制

css 复制代码
┌─────────────────────────────────────────────────────────────────────┐
│                      Segment合并原理                                 │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  背景:ES不断写入新Segment,小Segment会越来越多                       │
│  问题:小Segment查询效率低(需要合并搜索多个Segment)                │
│                                                                      │
│  合并策略:                                                          │
│  ┌────────────────────────────────────────────────────────────────┐ │
│  │  Elasticsearch后台线程定期执行Force Merge                       │ │
│  │                                                                 │ │
│  │  小Segment合并为大Segment:                                      │ │
│  │  [S1] + [S2] + [S3] → [S_new]                                  │ │
│  │  合并时自动删除已标记删除的文档                                  │ │
│  └────────────────────────────────────────────────────────────────┘ │
│                                                                      │
│  配置优化:                                                          │
│  PUT /my_index/_settings                                            │
│  {                                                                   │
│      "number_of_shards": 3,          // 主分片数(创建时设置)      │
│      "number_of_replicas": 1,        // 副本数(可动态调整)         │
│      "refresh_interval": "5s"        // 刷新间隔(写多查少时调大)  │
│  }                                                                   │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘

三、查询DSL:深度解析

3.1 全文查询

json 复制代码
// 1. match查询(标准全文搜索)
GET /my_index/_search
{
  "query": {
    "match": {
      "title": {
        "query": "Java编程入门",
        "operator": "and"  // and: 所有词都匹配, or: 任一词匹配(默认)
      }
    }
  }
}

// 2. match_phrase(短语匹配)
GET /my_index/_search
{
  "query": {
    "match_phrase": {
      "title": {
        "query": "Java编程",
        "slop": 1  // 允许词之间间隔1个词
      }
    }
  }
}

// 3. multi_match(多字段匹配)
GET /my_index/_search
{
  "query": {
    "multi_match": {
      "query": "Java分布式",
      "fields": ["title^2", "content", "tags"],
      "type": "best_fields",  // 最佳字段(默认)
      "tie_breaker": 0.3  // 其他字段的权重
    }
  }
}

// 4. query_string(高级查询语法)
GET /my_index/_search
{
  "query": {
    "query_string": {
      "default_field": "content",
      "query": "(Java AND 分布式) OR (Spring AND 微服务)",
      "default_operator": "AND"
    }
  }
}

3.2 精确查询

json 复制代码
// 1. term查询(不分词,精确匹配)
GET /my_index/_search
{
  "query": {
    "term": {
      "status": "active"  // 精确匹配,不会分词
    }
  }
}

// 2. terms查询(多值精确匹配)
GET /my_index/_search
{
  "query": {
    "terms": {
      "status": ["active", "pending"]
    }
  }
}

// 3. range查询(范围查询)
GET /my_index/_search
{
  "query": {
    "range": {
      "age": {
        "gte": 18,
        "lte": 30,
        "boost": 2.0  // 权重提升
      },
      "create_time": {
        "gte": "2024-01-01",
        "lte": "now"  // 当前时间
      }
    }
  }
}

// 4. exists查询(非空查询)
GET /my_index/_search
{
  "query": {
    "exists": {
      "field": "phone_number"
    }
  }
}

3.3 复合查询

json 复制代码
// 1. bool查询(布尔组合)
GET /my_index/_search
{
  "query": {
    "bool": {
      "must": [        // 必须匹配(AND)
        { "match": { "title": "Java编程" } }
      ],
      "should": [      // 应该匹配(OR,增加相关性得分)
        { "match": { "content": "Spring" } },
        { "match": { "content": "微服务" } }
      ],
      "must_not": [    // 必须不匹配(NOT)
        { "term": { "status": "deleted" } }
      ],
      "filter": [       // 过滤(不计算得分,性能更好)
        { "range": { "age": { "gte": 18 } } },
        { "term": { "city": "北京" } }
      ],
      "minimum_should_match": 1  // 最少should匹配数
    }
  }
}

// 2. constant_score(常量分数)
GET /my_index/_search
{
  "query": {
    "constant_score": {
      "filter": { "term": { "status": "active" } },
      "boost": 1.5
    }
  }
}

// 3. function_score(函数评分)
GET /my_index/_search
{
  "query": {
    "function_score": {
      "query": { "match": { "title": "Java" } },
      "functions": [
        {
          "filter": { "range": { "age": { "lte": 30 } } },
          "gauss": {
            "age": {
              "origin": 25,
              "scale": 10,
              "decay": 0.5
            }
          }
        },
        {
          "field_value_factor": {
            "field": "popularity",
            "factor": 1.2,
            "modifier": "sqrt",
            "missing": 1
          }
        }
      ],
      "score_mode": "sum",  // 得分模式
      "boost_mode": "multiply"  // 最终得分模式
    }
  }
}

3.4 聚合查询

json 复制代码
// 1. 桶聚合(Bucket Aggregation)
GET /my_index/_search
{
  "size": 0,  // 不返回文档,只返回聚合结果
  "aggs": {
    "group_by_city": {
      "terms": {
        "field": "city",
        "size": 10,
        "min_doc_count": 5
      },
      "aggs": {
        "avg_age": {
          "avg": { "field": "age" }
        },
        "max_salary": {
          "max": { "field": "salary" }
        }
      }
    }
  }
}

// 2. 指标聚合(Metric Aggregation)
GET /my_index/_search
{
  "size": 0,
  "aggs": {
    "stats_age": {
      "stats": { "field": "age" }  // min, max, sum, avg, count
    },
    "percentile_salary": {
      "percentiles": {
        "field": "salary",
        "percents": [25, 50, 75, 95, 99]
      }
    }
  }
}

// 3. 嵌套聚合
GET /my_index/_search
{
  "size": 0,
  "aggs": {
    "by_gender": {
      "terms": { "field": "gender" },
      "aggs": {
        "avg_age": { "avg": { "field": "age" } },
        "by_city": {
          "terms": { "field": "city" },
          "aggs": {
            "avg_salary": { "avg": { "field": "salary" } }
          }
        }
      }
    }
  }
}

四、性能优化:实战技巧

4.1 索引设计优化

json 复制代码
// 1. 合理的分片数
/**
 * 分片数 = 数据量 / 单分片容量
 * 
 * 建议单分片容量:30-50GB
 * 
 * 场景1:数据量1TB
 *   建议分片数 = 1000GB / 40GB ≈ 25个主分片
 * 
 * 场景2:数据量100GB,预计增长到500GB
 *   建议分片数 = 500GB / 40GB ≈ 13个主分片
 */

// 2. 副本数设计
/**
 * 副本数 = 数据重要程度 + 查询压力
 * 
 * 高可用要求:至少1个副本
 * 读压力大:副本数 = ceil(读QPS / 单节点QPS)
 */

// 3. mappings优化
PUT /my_index
{
  "mappings": {
    "properties": {
      "user_id": { "type": "keyword" },  // 不需要全文搜索,用keyword
      "title": {
        "type": "text",
        "analyzer": "ik_max_word",  // 中文分词
        "fields": {
          "keyword": { "type": "keyword" }  // 支持精确匹配
        }
      },
      "age": { "type": "integer" },
      "salary": { "type": "scaled_float", "scaling_factor": 100 },
      "create_time": { "type": "date" },
      "tags": { "type": "keyword" }
    }
  },
  "settings": {
    "number_of_shards": 3,
    "number_of_replicas": 1,
    "refresh_interval": "5s",  // 写多查少时增大
    "translog": {
      "sync_interval": "10s",
      "durability": "async"  // 异步刷新,提升写入性能
    }
  }
}

4.2 查询优化

java 复制代码
// 1. 使用filter替代must
// filter:不计算相关性得分,可缓存
// must:计算相关性得分,不可缓存

// ❌ 低效
GET /my_index/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "title": "Java" } },
        { "term": { "status": "active" } }  // status不需要评分
      ]
    }
  }
}

// ✅ 高效
GET /my_index/_search
{
  "query": {
    "bool": {
      "must": { "match": { "title": "Java" } },
      "filter": { "term": { "status": "active" } }
    }
  }
}

// 2. 关闭source返回不必要的字段
GET /my_index/_search
{
  "_source": ["title", "author", "publish_time"],  // 只返回需要的字段
  "query": { ... }
}

// 3. 分页深度查询优化
// ❌ 深分页问题:from+size深度过大会OOM
POST /my_index/_search
{ "from": 10000, "size": 10 }  // 每次翻页都是前10010条

// ✅ 使用search_after(推荐)
POST /my_index/_search
{
  "size": 10,
  "query": { "match": { "title": "Java" } },
  "sort": [
    { "publish_time": "desc" },
    { "_id": "asc" }
  ]
}

// 后续查询使用search_after
POST /my_index/_search
{
  "size": 10,
  "query": { "match": { "title": "Java" } },
  "search_after": ["2024-03-01", "doc_id"],
  "sort": [
    { "publish_time": "desc" },
    { "_id": "asc" }
  ]
}

// ✅ 使用scroll(大批量导出)
POST /my_index/_search?scroll=5m
{
  "size": 1000,
  "query": { "match_all": {} }
}
// 返回 scroll_id,后续使用
POST /_search/scroll
{
  "scroll": "5m",
  "scroll_id": "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4..."
}

4.3 写入性能优化

json 复制代码
// 1. 批量写入
POST /my_index/_bulk
{ "index": { "_id": "1" } }
{ "title": "文档1", "content": "内容1" }
{ "index": { "_id": "2" } }
{ "title": "文档2", "content": "内容2" }
// 批量大小建议:5-15MB

// 2. 合理设置refresh_interval
PUT /my_index/_settings
{
  "refresh_interval": "30s"  // 写入期间临时关闭refresh
}

// 3. 副本设置为0,写入完成后恢复
PUT /my_index/_settings
{
  "number_of_replicas": 0
}
// 写入完成后
PUT /my_index/_settings
{
  "number_of_replicas": 1
}

// 4. 使用Routing减少搜索范围
PUT /my_index/_doc/1?routing=user_123
{ "title": "用户文章", "user_id": "user_123" }

// 查询时指定routing,减少搜索分片数
GET /my_index/_search?routing=user_123
{ "query": { "match": { "title": "Java" } } }
// 实际只搜索routing对应的分片,而不是全部分片

五、集群与高可用

5.1 集群架构

scss 复制代码
┌─────────────────────────────────────────────────────────────────────┐
│                      ES集群架构                                     │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│                        ┌─────────────┐                              │
│                        │  Client Node │  ← 协调节点(可选)          │
│                        │  (协调请求)  │                              │
│                        └──────┬──────┘                              │
│                               │                                       │
│            ┌─────────────────┼─────────────────┐                   │
│            ↓                 ↓                 ↓                    │
│     ┌─────────────┐  ┌─────────────┐  ┌─────────────┐              │
│     │  Master Node │  │  Master Node │  │  Master Node │              │
│     │  (Master)    │  │  (Candidate) │  │  (Candidate) │              │
│     └─────────────┘  └─────────────┘  └─────────────┘              │
│            ↓                 ↓                 ↓                    │
│     ┌─────────────┐  ┌─────────────┐  ┌─────────────┐              │
│     │  Data Node  │  │  Data Node  │  │  Data Node  │              │
│     │  (P0, R1)   │  │  (P1, R2)   │  │  (P2, R0)   │              │
│     └─────────────┘  └─────────────┘  └─────────────┘              │
│                                                                      │
│  节点类型:                                                           │
│  - Master:管理集群元数据(索引创建/删除、分片分配)                  │
│  - Data:存储数据、参与搜索和聚合                                    │
│  - Coordinating:接收请求、转发给Data节点、聚合结果                  │
│  - Ingest:数据预处理(pipeline)                                    │
│                                                                      │
│  分片分配策略:                                                       │
│  - 主分片故障 → 自动选举新主分片                                     │
│  - 副本分片故障 → 主分片复制数据到新副本                             │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘

5.2 故障恢复机制

json 复制代码
// 1. 分片恢复配置
PUT /_cluster/settings
{
  "transient": {
    "cluster.routing.allocation.enable": "all",  // 允许分片分配
    "cluster.routing.allocation.node_concurrent_recoveries": 2,  // 并发恢复数
    "indices.recovery.max_bytes_per_sec": "100mb"  // 恢复速度限制
  }
}

// 2. 手动触发分片重分配
POST /_cluster/reroute
{
  "commands": [
    {
      "move": {
        "index": "my_index",
        "shard": 0,
        "from_node": "node1",
        "to_node": "node2"
      }
    }
  ]
}

// 3. 查看集群健康状态
GET /_cluster/health
{
  "cluster_name": "my_cluster",
  "status": "green",  // green: 所有分片正常
  "number_of_nodes": 3,
  "active_primary_shards": 30,
  "relocating_shards": 0,
  "initializing_shards": 0,
  "unassigned_shards": 0
}

六、常见面试题

Q1:ES和MySQL如何选型?

复制代码
┌─────────────────────────────────────────────────────────────────────┐
│                    ES vs MySQL 对比                                 │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  MySQL适用场景:                                                      │
│  ✅ 事务要求高(强一致性)                                           │
│  ✅ 数据量小(千万级以下)                                           │
│  ✅ 关联查询复杂                                                     │
│  ✅ 需要实时更新的数据                                               │
│                                                                      │
│  ES适用场景:                                                         │
│  ✅ 全文搜索需求                                                     │
│  ✅ 数据量大(TB级)                                                 │
│  ✅ 查询延迟要求高(毫秒级)                                         │
│  ✅ 聚合分析需求                                                     │
│  ✅ 水平扩展能力                                                     │
│                                                                      │
│  最佳实践:MySQL + ES双写                                           │
│  - MySQL作为主存储,保证数据一致性                                   │
│  - ES作为搜索引擎,提供全文搜索能力                                  │
│  - 通过Canal/Binlog同步数据到ES                                      │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘

Q2:ES如何保证高可用?

markdown 复制代码
1. 分片副本机制
   - 每个主分片可以有多个副本分片
   - 副本分片分布在不同节点
   - 主分片故障,自动从副本选举新主分片

2. 故障检测
   - 节点间心跳检测(ping)
   - Master主动检测Data节点状态
   - 节点失联后,自动触发分片重分配

3. 集群健康状态
   - green:所有分片正常
   - yellow:所有主分片正常,但有副本分片未分配
   - red:有主分片不可用

4. 写入一致性
   - wait_for_active_shards:写入前等待的活跃分片数
   - consistency: quorum(大多数节点确认)

Q3:ES如何解决相关性排序问题?

json 复制代码
// 1. TF-IDF算法
/**
 * TF-IDF = TF(词频) × IDF(逆文档频率)
 * 
 * TF = 词在文档中出现次数
 * IDF = log(总文档数 / 包含该词的文档数)
 * 
 * 得分 = Σ(TF-IDF)
 */

// 2. BM25(ES默认算法)
/**
 * 改进了TF-IDF的饱和函数
 * 解决了词频过高导致得分饱和的问题
 * 
 * BM25(k1=1.2, b=0.75)
 * k1: 词频饱和参数
 * b: 文档长度归一化参数
 */

// 3. 自定义评分
GET /my_index/_search
{
  "query": {
    "function_score": {
      "query": { "match": { "title": "Java" } },
      "functions": [
        { "field_value_factor": { "field": "popularity", "factor": 1.2 } },
        { "weight": 2, "filter": { "term": { "is_vip": true } } }
      ],
      "score_mode": "sum",
      "boost_mode": "multiply"
    }
  }
}

七、总结

python 复制代码
┌─────────────────────────────────────────────────────────────────────┐
│                      Elasticsearch知识地图                           │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  核心原理 ──────────────────────────────────────────────────────→   │
│  倒排索引 → FST → 分词器 → Analyzer                                  │
│                                                                      │
│  数据结构 ──────────────────────────────────────────────────────→   │
│  Index → Shard → Segment → Document                                  │
│                                                                      │
│  查询DSL ──────────────────────────────────────────────────────→   │
│  match/term/range → bool复合查询 → 聚合查询                         │
│                                                                      │
│  性能优化 ──────────────────────────────────────────────────────→   │
│  mappings设计 → 分片策略 → 查询优化 → 写入优化                       │
│                                                                      │
│  集群高可用 ────────────────────────────────────────────────────→   │
│  主从复制 → 故障检测 → 自动恢复                                      │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘

🎯 讨论话题

大家在使用ES时遇到过哪些性能问题?是怎么排查和解决的?


往期热门文章推荐:


如果这篇文章对你有帮助,欢迎点赞、收藏、转发!我们下期再见! 👋

相关推荐
南璋2 小时前
MySQL排序踩坑:为什么"10"比"2"小?
后端
Java编程爱好者2 小时前
JVM 详解:从内存结构到调优实战,Java 开发者必读
后端
小瓦码J码2 小时前
如何手动部署一个向量模型服务
人工智能·后端
Carsene2 小时前
Spring Boot 包扫描新姿势:AutoScan vs @Import vs @ComponentScan 深度对比
spring boot·后端
Gopher_HBo2 小时前
ReentrantReadWriteLock源码讲解
java·后端
文浩AI2 小时前
Claude Code 创始人 Boris Cherny 的并行工作流最佳实践
后端
Baihai_IDP2 小时前
以 Nano-vLLM 为例,深入理解 LLM 推理引擎(Part 1)
人工智能·面试·llm
wuxinyan1232 小时前
Java面试题48:一文深入了解java设计模式
java·设计模式·面试
武子康2 小时前
大数据-267 实时数仓-架构演进:Lambda与Kappa架构实战指南
大数据·后端