Elasticsearch 数据存储底层机制详解
Elasticsearch 的底层存储机制依赖 Lucene 来实现数据的组织和管理。下面从数据存储的 流转过程 和 管理机制 两个方面来详细说明。
1. 数据存储流程
当一个文档通过 REST API 被写入 Elasticsearch 时,会经历以下流程:
1.1 接收请求
- 用户通过 REST API 发送一个文档,指定索引名称(
index
)。 - 数据被分配到相应的 主分片(Primary Shard)。
1.2 分片分配
- Elasticsearch 根据索引配置,利用哈希值对文档 ID 进行路由,确定文档应存储在哪个分片上。
- 分片可以分为主分片(Primary Shard)和副本分片(Replica Shard)。
1.3 文档处理
文档进入主分片后,Lucene 执行以下步骤:
- 倒排索引构建:
- 将文档中的字段解析为词条(Terms)。
- 创建倒排索引,将每个词条映射到包含该词条的文档 ID 列表。
- 存储正排索引:
- 记录字段与文档的原始值,用于排序、聚合等功能。
- 数据压缩:
- 使用压缩算法对文档存储结构优化,减少磁盘占用。
1.4 数据写入
- 经过处理的数据被写入 Lucene Segment(段文件)。
- 每次写入不会立即更新到磁盘,而是先写入内存中的缓冲区和 事务日志(translog)。
1.5 刷新到磁盘
- 定时(默认 1 秒)或手动触发刷新操作,将缓冲区中的数据刷新到磁盘,生成新的段文件(
segment
)。 - 同时清空事务日志,保证持久化。
1.6 数据同步到副本分片
- 主分片成功写入后,会将数据同步到副本分片。
- 副本分片的作用是提供高可用性和查询负载分担。
2. 数据管理机制
2.1 Lucene 段(Segment)
- Lucene 将数据存储在段文件(Segment)中,每个段文件是一个不可变的小型倒排索引。
- 当有新的写操作时,会创建新的段文件,而不是直接修改旧的段。
- 定期合并(Merge)段文件以减少段数量、优化查询性能。
2.2 Translog(事务日志)
- 每次写操作都会先写入事务日志,作为一个临时缓冲区。
- 在节点崩溃时,Elasticsearch 可以通过事务日志恢复未刷新的数据。
2.3 倒排索引
-
Elasticsearch 使用倒排索引快速定位包含某个词条的文档。
-
示例:假设存储的文档包含以下内容:
文档1:Elasticsearch 是一个分布式搜索引擎 文档2:Elasticsearch 支持全文搜索
倒排索引结构如下:
词条 -> 文档列表 Elasticsearch -> [1, 2] 分布式 -> [1] 搜索 -> [1, 2]
-
通过倒排索引,Elasticsearch 可以快速查询到包含特定词条的文档。
2.4 正排索引
-
用于支持聚合和排序操作。
-
示例:如果有字段
price
,正排索引会记录每个文档的price
值:文档ID -> 值 1 -> 100 2 -> 200
2.5 分布式存储
- 数据分片后被分配到集群中的多个节点上。
- Elasticsearch 会自动平衡分片,并提供高可用性机制:
- 主分片和副本分片分布在不同节点上。
- 节点故障时,副本分片会升级为主分片。
总结:数据存储的核心机制
- 写入流程: 数据从 REST 请求 -> 分片分配 -> Lucene 处理 -> 刷新到磁盘。
- 管理机制:
- Lucene 段文件管理数据,支持快速查询。
- 事务日志保证数据可靠性。
- 倒排索引和正排索引提供高效的全文搜索和排序聚合。
- 分布式架构确保高可用性。
若有错误与不足请指出,关注DPT一起进步吧!!!