说到Elasticsearch,最明显的特点之一就是近实时准实时,当文档存储在Elasticsearch中时,会在1秒内几乎实时地被索引和完全搜索。那为什么说ES是准实时的呢?图片来自PexelsLucene,ESLuceneLucene是Elasticsearch所基于的Java库。引入了段搜索的概念:段:也叫段,类似于倒排索引,相当于一个数据集。提交点:提交点记录了所有已知的段。Lucene索引:“段的集合加上一个提交点”。它由一组段加上一个提交点组成。对于一个Lucene索引的组成,如下图所示:ES一个ElasticsearchIndex由一个或多个分片(shards)组成。Lucene中的Luceneindex相当于ES的一个shard。写入流程写入流程1.0(不完善)写入流程1.0如下:不断将Document写入In-memorybuffer(内存缓冲区)。当满足某些条件时,内存缓冲区中的文档被刷新到磁盘。生成一个新的segment和一个Commitpoint提交点。该段可以像任何其他段一样读取。图片如下:flushingfilestodisk非常耗资源,内存缓冲区和磁盘之间有缓存(cache)。一旦文件进入缓存,它就可以像磁盘上的一个段一样被读取。写入流程2.0写入流程2.0如下:不断的将Document写入In-memorybuffer(内存缓冲区)。当满足某些条件时,将内存缓冲区中的Documents刷新到缓存中。生成一个新段,该段仍在缓存中。这个时候还没有commit,但是已经可以读取了。图示如下:数据从buffer传输到cache的过程每秒周期性刷新一次。因此,新写入的Document最慢1秒就可以在缓存中查找到。Document从buffer到cache的过程称为刷新。一般1秒刷新一次,不需要额外修改。当然,如果有修改的需求,可以参考文末的相关信息。这就是为什么Elasticsearch是准实时的。使文档立即可见:PUT/test/_doc/1?refresh{"test":"test"}//或PUT/test/_doc/2?refresh=true{"test":"test"}Translog事务日志这里可以想到MySQL的binlog,ES中也有一个translog,用于故障恢复:Document不断写入In-memorybuffer,此时也会追加translog。当缓冲区中的数据每秒刷新到缓存中时,translog并没有进入刷新到磁盘,而是不断追加。translog将每5秒fsync一次到磁盘。translog会不断积累,越来越大。当translog足够大或者有规律的间隔时,就会执行flush。flush操作将分为以下几个步骤:Buffer被清空。记录提交点。缓存中的段通过fsync刷新到磁盘。translog被删除。值得注意的是:translog每5s刷新一次磁盘,所以失败后重启可能会丢失5s的数据。translog执行flush操作,默认30分钟执行一次,或者如果translog太大。手动执行flush:POST/my-index-000001/_flushdeleteandupdatesegment不能改变,所以docment不能从之前的segment中移除或更新。所以每次commit,产生一个commitpoint的时候,都会有一个.del文件,里面会列出被删除的文件(逻辑删除)。查询时,得到的结果会经过.del过滤后返回。更新时,旧文档也会被标记为删除,写入.del文件,同时写入新文件。这个时候查询会查询到两个版本的数据,但是在返回前会去掉一个。段合并每1秒执行一次刷新,以从内存中的数据创建一个段。太多的段会导致严重的问题。每个段消耗文件句柄、内存和cpu周期。更重要的是,每个搜索请求都必须依次检查每个段;所以段越多,搜索越慢。ES后台会有一个线程进行段合并:刷新操作会创建一个新的段并打开进行搜索。合并过程选择一小部分类似大小的段,并在后台将它们合并成更大的段。这不会中断索引和搜索。合并完成后,旧段将被删除。描述合并完成时的活动:新段被刷新到磁盘。编写一个新的提交点,其中包括新的段并排除旧的和较小的段。打开新段以供搜索。删除旧段。物理删除:在Segmentmerge中,那些已经被逻辑删除的文档将被物理删除。总结主要介绍内部写入和删除的过程,需要了解refresh、fsync、flush、.del、segmentmerge等术语的具体含义。完整图如下:以上为个人分享的ES相关内容,主要目的是在群内分享技术和扫盲。如果我说错了,希望大家留言指正。相关资料:准实时搜索:https://www.elastic.co/guide/en/elasticsearch/reference/7.9/near-real-time.html刷新API:https://www.elastic.co/guide/en/elasticsearch/reference/7.9/indices-refresh.htmlFlushAPI:https://www.elastic.co/guide/en/elasticsearch/reference/7.9/indices-flush.html作者:刘志航编辑:陶家龙来源:转载自公众号刘志航(ID:liuzhihangs)
