背景:目前国内有大量的公司都在使用 Elasticsearch,包括阿里、京东、滴滴、今日头条、小米、vivo等诸多知名公司。除了搜索功能之外,Elasticsearch还结合Kibana、Logstash、Elastic Stack还被广泛运用在大数据近实时分析领域,包括日志分析、指标监控等多个领域。
目录
问题1:为什么在建索引时,需要固定主分片数
问题2:ElasticSearch是如何将doc数据写入到不同分片的
问题3:Lucene和ElasticSearch有什么区别
问题4:Lucene Segment的作用是什么
Inverted Index
Stored Field
Document values
Cache
我们知道ES在创建索引时,需要指定分片数。
PUT /my_temp_index
{
"settings": {
"number_of_shards" : 1,
"number_of_replicas" : 0
}
}
其中number_of_shards,表示为每个索引的主分片数,默认值是 5 。这个配置在索引创建后不能修改。number_of_replicas为每个主分片的副本数,默认值是 1 。对于活动的索引库,这个配置可以随时修改。
那问题来了,为什么要固定主分片数呢?
这就涉及到关于Elasticsearch分片的初衷了, 关于Shard的解释参考 Elasticsearch的相关名称解释
分片的目的,主要是用于分布式的形式存储索引数据,一个索引分可能被分成多个分片,以此来减少单独节点的压力同时提高检索性能。
那数据是如何被分配到不同分片上的呢?
这就需要接着讨论我们的问题2来回答问题1的疑问。
首先,我们需要知道索引中文档数据的理由规则。
索引数据存储的时候,必然不会只落在单一的分片上,而是通过路由策略将文档存储到对应路由后的分片中。
当检索对应索引文档的时候, Elasticsearch 如何知道一个文档应该从哪个分片中获取呢?
这就涉及到ES中,doc路由公式决:
shard = hash(routing) % number_of_shards
其中,routing 是一个可变值,默认是文档的 _id ,也可以设置成一个自定义的值;
而 number_of_shards就是我们在问题1中提到的主分片数;
shard就是我们计算后得到的哪个分片号,因此也就确定了数据最终落在哪个分片。
综上,解释了为什么我们要在创建索引的时候就确定好主分片的数量并且永远不会改变这个数量。
大家试想一下,如果这个主分片数量可以动态调整,那么所有之前路由的值都会无效,文档也再也
找不到了。
首先,Lucene是一个 Java库 ,一套用于全文检索和搜寻的开源程式库,由Apache软件基金会支
持和提供。我们开发的时候可以直接将其引入到项目中,并使用函数调用来引用其功能。
而Elasticsearch是建在Lucene底座之上的一套支持分布式的搜索服务。由于Lucene底层操作比较
复杂,对于很多人来说上手难。因此Elasticsearch专门为我们抽象出了一套基于JSON的RESTFul
API 来便捷的调用Lucene功能, 可以理解为是对Lucene更进一层的封装。另外Elasticsearch还提供
了其他支持功能,例如线程池、队列、节点/集群监视API,数据监视API,集群管理等。
参考老王的这篇文章了解ES的整体架构:Elasticsearch架构及模块功能
我们所熟知的Solr,也是一个高性能的基于Lucene的全文搜索服务器。也同样对Lucene进行了扩展,提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展,并对查询性能进行了优化,并且提供了一个完善的功能管理界面,也是一款非常优秀的全文搜索引擎。
在Lucene里segment是索引中最小的独立存储单元,一个索引文件由一个或多个段组成。
Lucene的索引文件,会包含很多个segments文件,每个segment中包含多个documents文件,一
个segment中会有完整的正向索引和反向索引。
Segment主要作用: 在搜索时Lucene会遍历这些segments,以segments为基本单位独立搜索
每个segments文件,而后再把搜索结果合并。
Segment由四部分组成:Inverted Index、Sorted Fields、Document Values、Cache。
主要包括两部分:
1) 一个有序的数据字典Dictionary(包括单词Term和它出现的频率)。
2) 与单词Term对应的Postings(即存在这个单词的文件)。
当我们搜索的时候,首先将搜索的内容分解,然后在字典里找到对应Term,从而查找到与搜索相
关的文件内容。
当我们想要查找包含某个特定标题内容的文件时,Inverted Index就不能很好的解决这个问题,所
以lucene提供了另外一种数据结构Stored Fields来应对这个问题。
为了解决排序,聚合,facet问题的,Document values结构本质上是一个列式的存储,它高度优化
了具有相同类型的数据的存储结构。
Lucene也会将所有的信息做缓存,以此来提升查询效率。
引入Segment的好处:
1. 对文档的读写进行了解耦。
2. 提升写文档的速度。
具体细节比较复杂,老王会在后面的章节中具体介绍。