往期回顾:
近似实时搜索(Near real-time search)是指文档存储在Elasticsearch,它会在 1 秒内近乎实时地建立索引并完全可搜索。
究其原因,是在于ES的索引存储机制。
当索引一个文档(即在ES中插入一个文档,后面都使用术语:索引文档),会首先写入到内存缓冲区(In-memory buffer)中,此时的文档是不能被检索到的,即不可查,读取不到的;
当内存缓冲区满或者ES每秒定期刷新(refresh)索引(仅限于过去30s内收到一个或者多个搜索请求的索引),ES会将内存缓冲区(In-memory buffer)中的数据在到文件系统缓存(filesystem cache)写入一个新的segement,然后清空内存缓冲区(In-memory buffer),此时的文档是可读的,可以被检索到的;这个操作比完全提交到磁盘要轻量许多,文件系统缓存的目的就是减少磁盘I/O操作的次数,经常执行不会降低ES性能。
也就是说,近似实时查询的原因是有一个等待写入到一个segement的时间间隔。
文件系统缓存被操作系统自动管理,异步的(fsync)将这个segement刷入(flush)到磁盘,同时标记这个segement已经被提交。
到这里,可能会疑惑segement是个什么东西?接下来一起看下ES索引结构。并将以图示形象的表示segment产生及落盘的过程。
Elasticsearch是基于的Java库Lucene开发的,Lucene引入了按段搜索(per-segement search)的概念。在Lucene 中索引一词的意思是“段的集合(a collection of segments )加上一个提交点(a commit point)”。它是可以检索的。
索引文档,首先写入内存缓冲区,此时并未写入到segement,不可读。
发生refresh(ES每秒refresh一次索引),生成新的segement添加到提交点(Commit point)写入到文件系统缓存,并清除内存缓冲区(In-memory)。注意此时还未被提交到磁盘(等待操作系统刷盘落盘),因此下图中以灰色表示,但是从此刻开始都是可检索的。
写入文件系统缓存的segement已经被操作系统管理,等待操作系统写入磁盘。当操作系统将其写入(fsync)磁盘,就完成了提交。此时被标记为已提交,清空文件系统缓存。
往期回顾: