背景:
ES中存在索引i_dm_f_da_enterprise,设置为"refresh_interval" : -1,禁用定时refresh。在索引中已经存在数据的情况下,重新进行全量导入,导致索引中存在大量标记“已删除”的文档,磁盘空间占用较大。我希望通过优化,减少索引所占用的磁盘空间,偶然发现refresh刷新(POST i_dm_f_da_enterprise/_refresh )可以达到目的,但不明原理,特此提问。
为了阐明问题,本人在下方提供了刷新前后的索引、段的信息,包括文档数量、段数量、段的committed信息等
理论背景:
- 根据ES官方文档,refresh操作是将ES内存(buffer)的文档合并为一个新的段,再将其导入本地系统缓存(os cache)的过程。该过程不涉及段级别的合并,而是会新增一个段。该过程不涉及flush、merge操作,对磁盘没有影响,同时也不应该导致所占磁盘空间减少。
刷新前:
1. 观察索引占用磁盘空间情况:GET /_cat/indices?vhealth status index uuid pri rep docs.count docs.deleted store.size pri.store.size green open i_dm_f_da_enterprise vQJl3D2ETvKCCEfbathbXw 36 1 338486628 72052057 804.1gb 384.3gb
2. 观察segment段的数量:GET /_cat/segments/i_dm_f_da_enterprise?v=true
段的数量:3191个
`
index shard prirep ip segment generation docs.count docs.deleted size size.memory committed searchable
i_dm_f_da_enterprise 0 p 9.99.112.6 _1uc 2388 3338940 3246825 4.7gb 35454 false true
i_dm_f_da_enterprise 0 p 9.99.112.6 _1uw 2408 194240 0 144.9mb 3716 true true
i_dm_f_da_enterprise 0 p 9.99.112.6 _1vu 2442 167028 0 124.8mb 3652 true true
i_dm_f_da_enterprise 0 p 9.99.112.6 _1xl 2505 2828321 15314 2gb 17086 false true
`
**操作:refresh刷新:POST i_dm_f_da_enterprise/_refresh **
刷新后:
1. 观察索引占用磁盘空间情况:GET /_cat/indices?v health status index uuid pri rep docs.count docs.deleted store.size pri.store.size green open i_dm_f_da_enterprise vQJl3D2ETvKCCEfbathbXw 36 1 338486628 72052057 584gb 294.9gb
2. 观察segment段的数量:GET /_cat/segments/i_dm_f_da_enterprise?v=true
段的数量:1973个
`
index shard prirep ip segment generation docs.count docs.deleted size size.memory committed searchable
i_dm_f_da_enterprise 0 p 9.99.112.6 _1uw 2408 194240 0 144.9mb 3716 true true
i_dm_f_da_enterprise 0 p 9.99.112.6 _1vu 2442 167028 0 124.8mb 3652 true true
观察总结:
- 通过GET /_cat/indices?v查看索引信息,发现docs.count(文档总数量)与docs.deleted(被删除的文档数量)不变,索引占用磁盘空间大幅减少,段的数量大幅减少。
- 通过GET /_cat/segments/i_dm_f_da_enterprise?v=true查看段信息,发现committed=false的段被删除,且刷新前后docs.count总数减少。
疑问:
- 为什么通过GET /_cat/indices?v和GET /_cat/segments/i_dm_f_da_enterprise?v=true观察到的doc.count变化不匹配,前者不变而后者减少?
- 为什么refresh会删除GET /_cat/segments中committed=false的segment?refresh操作是否会导致段的合并?根据官方文档,committed字段代表是否已经持久化至磁盘,因此应由flush过程控制,而非refresh。
官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-segments.html
流程图: