Elasticsearch核心概念与架构设计
作为当今最流行的分布式搜索引擎,Elasticsearch (ES) 凭借其强大的全文检索能力和横向扩展性,成为了日志分析、站内搜索和数据挖掘的首选方案。
如果习惯了 MySQL 等关系型数据库(RDBMS),初入 ES 的世界可能会对一些名词感到陌生。本文将带你通过类比和实战代码,彻底搞懂 ES 的"骨架"与"灵魂"。
1. 核心对象映射:从 SQL 到 DSL
DSL是你与ES对话的语言,全称(Domain Specific Language)
理解 ES 最快的方式,就是建立它与关系型数据库的思维映射。虽然底层原理截然不同,但在逻辑结构上有着极强的对应关系:
| 关系型数据库 (RDBMS) | Elasticsearch | 说明 |
|---|---|---|
| Table (表) | Index (索引) | 数据的逻辑容器 |
| Row (行) | Document (文档) | 单条数据记录,JSON 格式 |
| Schema (表结构) | Mapping (映射) | 定义字段名称与数据类型 |
| Column (列) | Field (字段) | 文档中的具体属性 |
实战场景
假设我们要存储客服系统的对话历史,在 ES 中,我们通过创建一个名为 dialog_history 的 Index 来实现。
Index 与 Document 的操作
在 ES 中,插入数据(Indexing)通常使用的是 RESTful API。
json
# 向索引 dialog_history 插入一条 Document
# POST /<Index Name>/_doc/<ID>
POST /dialog_history/_doc/1001
{
"user_id": "u_8829",
"agent_id": "a_007",
"timestamp": "2023-10-27T10:00:00Z",
"message_content": "请问应对程序员35岁中年危机?",
"tags": ["account", "urgent"]
}
如果不预先定义结构,ES 会根据第一条数据自动推断类型(Dynamic Mapping)。但在生产环境中,为了性能和准确性,我们必须显式定义 Mapping。
2. Mapping:数据的骨架 (Keyword vs Text)
Mapping 相当于数据库的 Schema,它定义了每个字段的数据类型。其中,String 类型的字段分为 Text 和 Keyword,这是 ES 面试和实战中的必考点。
核心区别
-
Text (文本类型)
-
处理方式 :会被分词器 (Analyzer) 处理。例如 "Apple Store" 会被拆分为
["apple", "store"]。 -
用途:全文检索(Full-Text Search)。比如搜 "Apple" 能搜到这条记录。
-
限制:通常不能用于聚合(Aggregation)或排序(Sorting),因为被拆散了。
-
Keyword (关键字类型)
-
处理方式 :不分词 ,原样存储。 "Apple Store" 存储为
"Apple Store"。 -
用途:精确匹配(Exact Match)、过滤、排序、聚合。
-
场景:ID、状态码、标签、邮箱地址。
代码实战:定义 Mapping
让我们为 dialog_history 定义一个精确的 Mapping:
json
PUT /tm_dialog_history
{
"mappings": {
"properties": {
"user_id": {
"type": "keyword" // ID 不需要分词,用于精确筛选
},
"timestamp": {
"type": "date"
},
"message_content": {
"type": "text", // 内容需要被搜索,使用 text
"analyzer": "ik_max_word" // 假设使用中文分词器
},
"status": {
"type": "keyword" // 状态用于统计,使用 keyword
}
}
}
}
查询对比示例:
- 搜索
message_content(Text) 时,搜 "密码" 可以匹配到 "重置我的账户密码"。 - 搜索
user_id(Keyword) 时,搜 "u_88" 无法匹配 "u_8829",必须完全一致。
3. 倒排索引 (Inverted Index):ES 快如闪电的秘密
为什么在数亿行数据中,MySQL 用 LIKE %keyword% 会卡死,而 ES 却能毫秒级返回?答案在于倒排索引。
- 正排索引 (Forward Index):文档 ID -> 关键词。就像书的正文,你要找某个词,必须从第一页翻到最后一页(全表扫描)。
- 倒排索引 (Inverted Index) :关键词 -> 文档 ID 列表。就像书的目录 或索引页。
举例说明
假设有两个文档:
- Doc 1: "Elasticsearch is fast"
- Doc 2: "Elasticsearch is distributed"
倒排索引结构如下:
| Term (词项) | Posting List (文档 ID 列表) |
|---|---|
| Elasticsearch | [1, 2] |
| fast | [1] |
| distributed | [2] |
当你搜索 "fast" 时,ES 直接定位到词典中的 "fast",立刻知道它在 Doc 1 中,完全无需遍历所有文档。这就是 ES 检索速度快数量级的根本原因。
4. 分布式架构:Shard & Replica
ES 天生就是分布式的。为了处理海量数据(PB 级)并保证高可用,它引入了 分片 (Shard) 和 副本 (Replica) 的概念。
Shard (主分片 - Primary Shard)
- 概念:它是数据的水平拆分。如果你有 1TB 数据,设置 5 个 Shard,每个 Shard 只需要承载 200GB。
- 作用 :水平扩展。允许数据分布在多台机器上,并行读写,突破单机存储和性能限制。
- 注意 :主分片数量在索引创建后很难修改(需要 Reindex),所以规划很重要。
Replica (副本分片 - Replica Shard)
- 概念:它是主分片的完整拷贝。
- 作用:
- 高可用 (HA):如果存放主分片的节点挂了,副本会立刻升为主分片,数据不丢失。
- 读性能扩展:搜索请求可以在主分片或副本上执行。增加副本数可以提高系统的并发吞吐量。
配置示例
json
PUT /tm_dialog_history
{
"settings": {
"number_of_shards": 3, // 数据切成 3 份
"number_of_replicas": 1 // 每份数据有 1 个备份 (总共 3主 + 3副 = 6个分片)
},
"mappings": { ... }
}
总结
Elasticsearch 不是黑魔法,它是一套设计精良的分布式系统:
- Index/Document 解决了数据存储格式。
- Mapping (Text/Keyword) 决定了数据如何被理解和搜索。
- 倒排索引 提供了极致的检索性能。
- Shard/Replica 保证了系统的扩展性和可靠性。
先写到这里~