【Elasticsearch】`_refresh`和`_flush`的区别
在Elasticsearch中,`_refresh`和`_flush`操作虽然看似都与“刷新”有关,但它们的功能和作用范围有显著区别:
`_refresh`操作
- 目的:使索引操作(如新增、更新、删除文档)后的更改能够立即被搜索到。
- 工作原理:将内存缓冲区(in-memory buffer)中的数据写入到一个新的Lucene segment中,并将其加载到文件系统缓存(OS cache)中,此时文档可以被搜索到,但数据尚未写入磁盘。
- 触发方式:
- 默认情况下,Elasticsearch每秒自动执行一次`_refresh`操作,但仅在最近30秒内有搜索请求的索引上执行。
- 可以通过设置`index.refresh_interval`来调整刷新间隔,或者在索引操作时通过`?refresh=true`参数强制触发。
- 当内存缓冲区达到一定大小(默认为节点堆内存的10%)时,也会触发`_refresh`。
- 特点:`_refresh`操作是同步的,会在操作完成前阻塞请求。
`_flush`操作
- 目的:将内存中的数据和事务日志(translog)中的操作永久写入磁盘,确保数据的持久性。
- 工作原理:
- `_flush`操作会先执行`_refresh`,将内存缓冲区中的数据写入新的Lucene segment并加载到文件系统缓存中。
- 然后,将这些segment从文件系统缓存强制刷入磁盘(通过`fsync`操作),并清空事务日志。
- 触发方式:
- 默认情况下,Elasticsearch会在以下情况下自动触发`_flush`操作:
- 每30分钟定时触发。
- 当事务日志大小超过512MB时。
- 在每次索引、批量、删除或更新操作完成后。
- 也可以通过API手动触发`_flush`操作。
- 特点:`_flush`操作是异步的,不会阻塞请求。
主要区别
- 数据可见性:`_refresh`使数据在搜索中可见,而`_flush`主要用于数据的持久化,不影响数据的搜索可见性。
- 操作范围:`_refresh`操作主要涉及内存缓冲区和文件系统缓存,而`_flush`操作会将数据写入磁盘并清空事务日志。
- 性能影响:`_refresh`操作的开销相对较小,但频繁的`_refresh`可能会影响写入性能;`_flush`操作的开销较大,但可以通过调整参数优化性能。
总结来说,`_refresh`用于使新文档能够被搜索到,而`_flush`用于确保数据持久化到磁盘,两者在Elasticsearch的索引管理中各自扮演着重要的角色。