Previous: elasticsearch外用与内观(一)-常用功能与使用方法
在了解了es的基本用法之后,我们再来看看当插入文档数据时,elasticsearch都在做什么。
首先,es的索引只是一个逻辑概念,实际上是由一个个物理分片组成的,每个分片就是一个lucene实例,我们看到这里有9个分片,也就是有9个lucene实例,所以每个分片都能独立完成搜索功能,最后由es对结果进行合并。
分片包括主分片shard和副本分片replica,副本分片仅仅是主分片的一个拷贝。
每个分片是分布在不同的节点上的,每启动一个es实例,就是一个节点:
我们看到这里启动了3个es实例,也就是有3个节点。
我们往es的索引里插入的文档,首先被插入到主分片里:
因为每个文档只能属于一个主分片,而es默认给索引设置了5个主分片,我们这里画的是3个主分片,所以这些文档在插入的时候,就会散列存储到不同的主分片里,也就是存到lucne实例里, 而lucene实例的内部结构,又是由很多lucene索引组成:
我们建的es索引里的每个字段,就是一个个lucene索引:
而lucene索引是由一个个segment组成的,每个segment大小是不一样的,有大有小:
每个segment就是一个包含了一些倒排索引的独立段:
所以,我们在往es插入数据后,最后创建了很多包含了倒排索引的segment段,而搜索的时候,也是从这些segment段里的倒排索引进行搜索的:
我们看一下整体的示意图:
最外层的就是一个es索引,因为索引有很多分片,每个分片就是一个lucene实例, lucene实例里,由lucene索引构成,而每个es索引字段就是一个lucene索引,lucene索引里边由segment组成,每个segment里边就是一些倒排索引。
因为倒排索引是搜索引擎的核心,我们简单介绍一下倒排索引
倒排索引
数据库里的正排索引是这样存储的,数据以id为主键,然后是名称字段。这样虽然通过id获取数据很快,但是通过名称搜索就很慢。
而倒排索引是以拆分好的分词作为主键,id放在后边。这样如果想用某个关键字获取数据,就可以直接找到对应数据的id,从而获取到数据。
es在插入数据的时候,除了会构建倒排索引这种存储结构之外,还会构建另外一种存储结构,doc values。
Doc values 只支持不需要分词的字段:
也就是如果字段是text类型,那么就只有倒排索引,而其他类型除了有倒排索引,还会存一个doc values。
doc values大概的结构是这样的,和数据库的存储结构类似:
为什么需要这种格式的数据,因为像聚合操作这种功能,需要使用某个字段来进行分类,这就需要知道这个字段里都有什么内容(包含哪些terms),而倒排索引是把一个字段的内容都打散了存储的,所以需要使用doc values这种类似数据库的存储结构,来进行聚合操作。
这也引出了一个我们需要关注的点,即:聚合操作的字段,不能设置为text类型,因为text类型,没有doc values。
Next: elasticsearch外用与内观(三)-当搜索时,elasticsearch都在做什么(上)