初次接触到这两个概念,估计都会觉得他们没什么差别,都是为了在操作索引之后让索引可以被实时性的搜索,不过它们还是有点不同的。
Elasticsearch底层依赖Lucene,这里我们介绍下Lucene的segment, Reopen,commit。
Segment
在ES中,基本的存储单元是shard(分片),但是在更底层的Lucene上稍微有点不同,ES的每一个shard是Lucene的一个index(索引),Lucene的索引由多个segment组成,每个segment就是ES文档的倒序索引,里面包含了一些term(词)的mapping(映射)。
当每个ES的文档创建的时候,都会写入一个新的segment中,因此每次写入的都是新的segment,所以不需要修改之前的segment。在删除文档的时候,只是在它属于的segment哪里标记为已删除就可,没有真正的从磁盘中抹除。更新也是同样的,只是在对应之前segment哪里标记为逻辑删除,然后新建一个新的segment。
Lucene Reopen
Reopen是为了让数据可以可以被搜索到,尽管这个时候数据可以被搜索到,但是不一定保证数据已经被持久化到磁盘中。
Lucene Commit
Commit就是为了让数据持久化,每一次的Commit,不同segment的数据都会被持久化到磁盘中,虽然这样可以让数据更安全,但是每一次操作都会消耗系统资源,会有大量的IO操作。
Translog
ES在持久化的时候引入了一种新的方式,translog(transaction log),一个文档被索引之后,就会被添加到内存缓冲区,并且 追加到了translog.
ES的Refresh
默认情况下,ES会每秒refresh一次,每次操作都会把内存缓冲区的内容拷贝到新创建的segment中去,这一步是在内存中操作的,这个时候新的文档就会被搜索了。也就是说ES是近实时性的搜索,差不多1s钟,才能让数据可以被搜索到。
ES的Flush
Flush操作意味着,所有在内存缓冲区的文档被写到新的Lucene Segment中,也就是所有在内存中的segment被提交到了磁盘,同时清除translog。
一般Flush的时间间隔会比较久,默认30分钟,或者当translog达到了一定的大小,也会触发flush操作。
最后
简单来说,ES的refresh操作是为了让最新的数据可以立即被搜索到。而flush操作则是为了让数据持久化到磁盘中,另外ES的搜索是在内存中处理的,因此Flush操作不影响数据能否被搜索到。
translog一般在进行flush的时候被清空,一般在fsync和commit的时候被持久化到磁盘,默认的translog是在6.x版本以后,每次请求都会fsync到磁盘。不过有些index.translog的配置可以设置
来源:51CTO
作者:java架构师1
链接:https://blog.51cto.com/13981400/2402526