ElasticSearch原理

一、插入更新与删除

1、保存文档,写入缓存
2、文档个数达到阈值或者刷新时间到
3、对缓存内的数据写入磁盘,并且生成倒排索引segment

ElasticSearch底层使用Lucene的全文搜索能力,Lucene不支持对于倒排索引的修改,但是文档的新增、修改、删除又必须修改倒排索引。怎么办呢

1、使用缓存,并且将倒排索引拆分为多个小的倒排索引。对缓存内一定数量的文档,新增生成一个小的倒排索引segment
2、删除文档、每个segment还有一个.del文件,虽然不能修改倒排索引segment。但是删除文档,可以把删除的文档记录到.del文件中。查询的时候,会将.del中的文档过滤掉
3、更新文档、更新文档可以分为删除和新增。现在.del删除旧文档,在缓存中新增新文档。

所以ES适用于更新频率不高的场景。如果更新频率很高,会产生很多垃圾数据无法清除占用磁盘空间,而且每次查询还需要过滤大量数据,大大降低性能。

使用倒排索引根据关键词(Term)搜索文档。elasticSearch为了加快倒排索引的速度,对Term进行升序排序,logN时间复杂度查找Term。

二、段合并

1、不断更新文档,不断把旧文档标记为已清除,不断生成新文档。ES的空间会不断被垃圾数据占满。而且查询性能不断降低(需要过滤标记为已删除的文档 )。
为了解决这个问题,提出了段合并。在段合并过程会把标记为已清除的文档真正的删除。
2、保存新文档,会不断生成segment。segment数量太多也会降低ES的查询性能。
需要在合适的时机,将一个个segment合并为大的segment。
ElasticSearch原理_第1张图片

segment合并的好处
减少索引段的数量,提升了内存空间,从而提高了检索速度。
减少索引的容量(文档数)——段合并会移除被标记为已删除的那些文档。提高了全文检索的速度,并移除了旧版本的数据。

segment合并带来的问题
磁盘IO操作的代价;因为段合并操作是非常耗I/O的,因为需要从旧的索引段中读取数据然后合并到新的索引段。
查询性能有一定影响;虽然说索引段合并的操作是异步进行的,但由于合并操作非常耗I/O,若合并时,正好也在进行大量的查询操作,在那些I/O处理速度慢的系统中,系统性能会受到影响。

三、Term Dictionary 倒排索引词典

Mysql的B+树索引保存在内存,ES的倒排索引保存在磁盘,因为每个文档都要分词,词典太大,内存放不下。

你会发现,本来Mysql中我存储三行数据就可以了,而在ES中却存储了七行数据,哪里高效了?ES为了查询Term快速,将所有Term排序,然后二分法查找Term,LogN的查找效率,类似查字典表,这个就是Term Dictionary。

四、Term Index

当数据量多的时候,Term Dictionary的量也很大,放在缓存中不现实,而Term Index就像是字典中的索引页一样,比如我找A开头的有哪些,分别在哪页等等,在Term Dictionary的基础上又加了一层索引,可以看成一棵树。
当然,Term Index不会保存所有的Term Dictionary,只是保存了Term的一些前缀与Term Dictionary之间的映射关系,再结合FST压缩技术,Term Index可以保存在内存中,这样从Term Index查询到Term Dictionary的block位置之后,再去磁盘中查找Term,就大大减少了访问磁盘的次数。
ElasticSearch原理_第2张图片

五、分片

Elasticsearch 为了完成分布式系统,对一些名词概念作了变动。索引成为了整个集群级别的命名,而在单个主机上的Lucene 索引,则被命名为分片(shard)。多个主分片类似于数据库纵向扩容。一个主分片可以有多个副本分片(replica shard)就是横向扩容。
借助于分片机制,ES中的一个索引可以被拆分成多个分片分布在集群中的多台服务器上,减轻了单台服务的读写压力,增加了单个索引的容量上限,实现了大规模数据的存储和检索。
ES默认使用文档id生成hash值,对主分片个数进行取模,算出来这个文档应该去哪个分片查询。所以每个索引的主分片个数是不能修改的。在创建索引的时候就要考虑好几个主分片。副本分片可以修改。

主从分片同步,提高容错率,也可以读写分离,提高并发效率。

主分片同步副本是异步进行的。

六、查询缓存,为什么适用于读多写少

1、并不是每次查询ES都查倒排索引得到文档id,再根据文档ID去查询B+树得到文档内容。
2、ES每个分片机器都有自己的缓存,查询不到缓存再查倒排索引,查文档,过滤等一系列流程。再放到缓存、
3、缓存使用LRU算法
4、如果这个分片的数据被修改了(增删改),缓存立即失效,防止查到脏数据。

ES适用于读多写少并不是说写入的效率很低。而是增删改会严重降低查询的效率。
一、insert产生的影响
1、insert会产生新的段,会造成段合并,段合并非常消耗磁盘IO。降低查询的速度
2、insert或造成查询缓存失效

二、delete产生的影响
1、查询会过滤标记为已删除的文档,如果频繁update,会造成标记del的文档很多,过滤浪费时间
三、update产生的影响
delete和update叠加的影响

你可能感兴趣的:(elasticsearch,lucene,搜索引擎)