从官方文档上可以看到的是,官方推荐我们在搭ES集群的时候,留一半以上的内存给lucence,还说 lucence 是基于 filesystem cash 的。
我们可以从一次 ES 的写入数据的过程来看看为什么要这样做,以及里边的一些优化点。
另外下边附了一些文章链接,都很好,推荐看。
# # ES 的写入过程
我只用文字来描述一个大题上的流程:将数据写入到 Lucence;定时进行一个 refresh 操作,将Lucence 的数据写入到文件系统缓存中,然后最后再写入到磁盘中。
详细介绍:我们调用一次写入的 api,文档写入到 Lucence,这是存储在内存中的,这个时候,如果服务器宕机,是会丢失数据的,另外此时数据写入到了Lucence,是无法被立即被检索到的,接着是进行了一次 refresh 的操作,将数据写入到了文件缓存系统中。此时的数据可以被检索到,但是仍然会丢失数据。 最后才写入到磁盘中去,数据才不会丢失。
再关注一些上述的几个关键点:一个是refresh,这个refresh操作的时间间隔由 refresh_interval
参数控制,默认为1s, 当然还可以在写入请求中带上refresh表示写入后立即refresh,另外还可以调用refresh API显式refresh。另外一个是从写入磁盘的触发的条件:flush操作 另外每30分钟或当translog达到一定大小(由 index.translog.flush_threshold_size
控制,默认512mb), ES会触发一次flush操作,此时ES会先执行refresh操作将buffer中的数据生成segment,然后调用lucene的commit方法将所有内存中的segment fsync到磁盘。此时lucene中的数据就完成了持久化,会清空translog中的数据(6.x版本为了实现sequenceIDs,不删除translog)
参考文章:https://zhuanlan.zhihu.com/p/94915597
这一篇更好一点:https://zhuanlan.zhihu.com/p/34669354
这一篇流程图很清晰,文章简短,可以在熟悉以后看,一目了然:https://juejin.im/post/5d39a5a2f265da1ba252a55f
# # 基于这一点的 ES优化https://juejin.im/post/5c8f42f16fb9a0710a1bbee9