在分布式日志服务架构中,咱们只须要将logstash的output指向ES就能够了,可是,写入的数据是如何变成Elasticsearch里能够被检索和聚合的索引内容的呢?本文重点介绍数据在写入Elasticsearch索引流程中发生的具体操做。重点在于其中segment、buffer和translog三部分对实时性和性能方面的影响。缓存
Lucene对于新收到的数据写入到新的索引文件里。Lucene把每次生成的倒排索引,叫作一个segment,而后另外使用一个commit文件,记录索引内全部的segment。而生成segment的数据来源则是放在内存中的buffer,也就是说,动态更新过程以下:架构
上面的内容中,内存buffer刷入磁盘,可是不可避免的问题就是写磁盘太慢了。对于咱们的日志服务来讲,若是要进行一些实时性统计,这个速度是不能接受的。因此,在内存buffer刷入磁盘的处理中,还有一个中间状态:curl
其实就是多加了一步文件系统缓存。Elasticsearch中默认1s中刷新一次。若是以为间隔时间仍是很短,能够调用/_refresh接口来修改。
不过对于日志场景来讲,咱们更须要的是更快的写入性能,因此咱们最好是经过/_settings接口或者定制template的方式,加大refresh_intereval参数:分布式
curl -XPOST http://127.0.0.1:9200/logstash-lms-2019.02.19/_settings -d'{"refresh_interval":"10s"}'
若是是导入历史数据的场合,甚至能够直接关闭。性能
refres只是写到文件系统缓存,若是最后一步写入到磁盘期间发生了错误、硬件故障灯问题,数据会丢失吗?
这里有另外一个控制机制。Elasticsearch在把数据写入到内存buffer的同时,其实还另外记录了一个translog日志。
refres发生时,translog日志文件依旧保持原样。若是期间发生异常,Elasticsearch会从commit位置开始,恢复整个translog文件中的记录,保证数据一致性。
等到真正吧segment刷新到磁盘,commit文件更新后,translog才会清空,即flush操做。
Elasticsearch默认30分钟flush一次,或者translog文件>512M时会主动flush。能够经过如下参数进行设置:url
index.translog.flush_threshold_period index.translog.flush_threshold_size #控制每收到多少条数据后flush一次 index.translog.flush_threshold_ops