引言
经常说,es中的index就是关系数据库的数据库,真的就这么简单吗?它和倒排索引、分片(shard)以及段(segment)的关系是啥?这些作为elasticsearch中非常核心的概念,有必要弄明白。
注:本文主要从宏观上讲述各个逻辑概念的设计意义及其关系,后续根据需要可细化相应部分。
逻辑概念
- es index
首先看下官网对es index的定义:
An index is like a ‘database’ in a relational database. It has a mapping which defines multiple types.An index is a logical namespace which maps to one or more primary shards and can have zero or more replica shards.
这两句话看似简单,其实包含es的一些设计理念:
-
索引是一种数据的逻辑组织方式,便于进行数据的隔离,类似于关系数据库中的命名空间的概念。
-
index存在的主副本分片,实现了索引数据分布在整个集群的节点上。
- 倒排索引
经过文本分析后文档的分词(某个字段)存储到倒排索引中。倒排索引主要维护分词和分词所在文档列表的映射关系,它提供搜索功能(针对倒排索引进行搜索)。比如:
d1: 我在学习es
d2、它在学习hadoop
在倒排索引中的展示形式如下:
分词 | 词频 | 文档列表 |
---|---|---|
我 | 1 | d1 |
在 | 2 | d1,d2 |
学习 | 2 | d1,d2 |
他 | 1 | d1 |
es | 1 | d1 |
hadoop | 1 | d2 |
注: 需要注意的是索引的每个字段都会创建一个倒排索引。
- 分片
分片本质上对应的Lucene的index,分片的引入其实采用分而治之的思想。单台机器的处理能力、内存、存储资源有限。在大数据时代,index的数据可能会增长快,远远超过单机的资源能力。因而,将index的数据切分为多个shard分布到多个节点上,各个文档存在分片上(不会跨分片),请求会发送到多个shard进行查询和合并结果。既实现了es的横向扩展能力,也提高了搜索性能。另外,集群规模改变时,分片自动迁移,完成数据的均衡分布。
-
段
segment是Lucene的一个概念,Lucene的Index由多个segment和提交点(commit point)组成,主要用于实现不需要进行提交(刷入磁盘)可以让文件被检索。这里简单说明下:
在es和磁盘之间存在一个文件系统缓存层,如下图所示:
in-memory indexing buffer的文档会待写入新的segment(绿色图标部分)。

in-memory indexing buffer中的文档写入新的segment后(灰色图标的数据),buffer中会被清空。因为segment本身是可被检索的,从而实现了不用commit,就可检索的效果,如下图所示:

另外,需要说明的是,每个segment会对应生成一个segment文件,该文件是不可变的。涉及到文档更新均是先逻辑删除,再在segment merge阶段进行物理删除,这也是为嘛es不适合大量文档更新的场景。
总结
本文从定义以及设计定位方面讲述了es的index、shard以及Segment,为了更方便理解它们的关系,画个二维表格协助理解:

es的index包含多shard,shard对应的是Lucene的一个index,Lucene的index包含多个segment。
参考:
https://www.elastic.co/guide/en/elasticsearch/reference/7.10/near-real-time.html
网友评论