经过前面两篇文章的介绍,咱们大概已经知道了 Elasticsearch处理数据的流程,其中在Elasticsearch和磁盘之间还有一层称为FileSystem Cache的系统缓存,正是因为这层cache的存在才使得es可以拥有更快搜索响应能力。缓存
咱们都知道一个index是由若干个segment组成,随着每一个segment的不断增加,咱们索引一条数据后可能要通过分钟级别的延迟才能被搜索,为何有种这么大的延迟,这里面的瓶颈点主要在磁盘。elasticsearch
持久化一个segment须要fsync操做用来确保segment可以物理的被写入磁盘以真正的避免数据丢失,可是fsync操做比较耗时,因此它不能在每索引一条数据后就执行一次,若是那样索引和搜索的延迟都会很是之大。性能
因此这里须要一个更轻量级的处理方式,从而保证搜索的延迟更小。这就须要用到上面提到的FileSystem Cache,因此在es中新增的document会被收集到indexing buffer区后被重写成一个segment而后直接写入filesystem cache中,这个操做是很是轻量级的,相对耗时较少,以后通过必定的间隔或外部触发后才会被flush到磁盘上,这个操做很是耗时。但只要sengment文件被写入cache后,这个sengment就能够打开和查询,从而确保在短期内就能够搜到,而不用执行一个full commit也就是fsync操做,这是一个很是轻量级的处理方式并且是能够高频次的被执行,而不会破坏es的性能。优化
以下图:搜索引擎
在elasticsearch里面,这个轻量级的写入和打开一个cache中的segment的操做叫作refresh,默认状况下,es集群中的每一个shard会每隔1秒自动refresh一次,这就是咱们为何说es是近实时的搜索引擎而不是实时的,也就是说给索引插入一条数据后,咱们须要等待1秒才能被搜到这条数据,这是es对写入和查询一个平衡的设置方式,这样设置既提高了es的索引写入效率同时也使得es可以近实时检索数据。code
refresh的用法以下:blog
POST /_refresh //刷新全部的索引 POST /blogs/_refresh //刷新指定的索引
refresh操做相比commit操做是很是轻量级的可是它仍然会耗费必定的性能,因此不建议在每插入一条数据后就执行一次refresh命令,es默认的1秒的延迟对于大多数场景基本均可以接受。索引
固然并非全部的业务场景都须要每秒都refresh一次,若是你短期内要索引大量的数据,为了优化索引的写入速度,咱们能够设置更大的refresh间隔,从而提高写入性能,命令以下:it
PUT /my_logs { "settings": { "refresh_interval": "30s" } }
上面的参数是能够随时动态的设置到一个存在的索引里面,若是咱们正在插入超大索引时,咱们彻底能够先关闭掉这个refresh机制,等写入完毕以后再从新打开,这样以来就能大大提高写入速度。ast
命令以下:
PUT /my_logs/_settings { "refresh_interval": -1 } //禁用刷新机制 PUT /my_logs/_settings { "refresh_interval": "1s" } //设置每秒刷新一次
注意refresh_interval的参数是能够带时间周期的,若是你只写了个1,那就表明每隔1毫秒刷新一次索引,因此设置这个参数时务必要谨慎。