天天看点

Elasticsearch索引的基本操作(8)-索引缓存、refresh、flush等操作

1、缓存清理

通过缓存清理的API _cache/clear,需要使用POST方法执行,可以清理指定索引或整个集群的缓存。

清除单个索引的缓存,操作如下:

POST /new_index/_cache/clear

{}

清除多个索引的缓存,操作如下:

POST /new_index,new_index_2/_cache/clear

{}

清除整个集群的缓存,操作如下:

POST /_cache/clear

{}

默认不带要清理的缓存类型参数的情况下,会清理指定索引的所有缓存,也可以通过指定要清理的缓存类型如query, fielddata 或request这些URL参数,并给其设定值true,以达到清除指定缓存的目的,操作如下:

#清除query的缓存

POST /new_index/_cache/clear?query=true

{}

#清除fielddata的缓存

POST /new_index/_cache/clear?fielddata=true

{}

#清除request的缓存

POST /new_index/_cache/clear?request=true

{}

2、flush操作

通过flush刷新操作,使用GET或POST方法调用_flush API,确保原来只保留在事务日志(transaction log)中的数据,得以真正的保存到Lucene索引中。在默认情况下,Elasticsearch会根据自动触发刷新,通常用户不需要直接调用该操作。不过在一些特殊场景之下手动触发也可以提高效率,如需要重启整个集群,手动执行flush将数据全部写入到索引中,对后面数据的恢复的速度也有提高,因为索引不需要再从事务日志提取数据用于恢复索引。

刷新操作可以一次性只刷新单个索引,也可以刷新多个索引,多个索引之间以英文逗号“,”分隔,也可以刷新所有索引。

刷新单个索引,操作如下:

GET /new_index/_flush

刷新多个索引,操作如下:

GET /new_index,new_index_2/_flush

刷新全部索引,操作如下:

GET /_flush

默认情况下,如果指定索引的某些分片正在执行刷新操作,则针对这些分片的刷新操作会抛出异常。可以通过参数对刷新操作的情况做相应的控制,如下表所示:

参数名称 说明
wait_if_ongoing

如果设置为true,如有另外一个刷新操作正在执行,则当前刷新操作将会阻塞,直到另一个刷新操作执行完后才执行。

默认为false,如果执行时另外一个刷新操作正在执行,会以异常的方式执行。

force 设置是否强制执行刷新,默认不会强制刷新,只会在索引有发生变化时执行刷新。通过强制执行可以增加事务日志的ID,即使索引没有变化。

3、refresh操作

refresh操作是Elasticsearch实现准实时搜索和高效率搜索的保证,通过refresh操作将buffer队列中的数据写入到位于OS Cache(OS Cache本身是一块内存区域,操作的速度非常块)的segment中,这样存储数据的segment就可以被搜索调用了,而不用等到通过耗时的fsync将数据写入到硬盘中。

Elasticsearch默认执行数据写入缓存的时间间隔是1秒,这也是Elasticsearch称为准实时搜索引擎的来由,根据不同的应用场景,该值可通过settings中的index.refresh_interval参数进行调整。

在Index、Update、Delete、Get和Bulk等操作中,都支持Refresh参数,它支持以下的值:

  1. 空字符串或true:刷新更改到缓存中,待其执行成功返回时,被刷新的更改就可以被搜索到,刷新涉及的分片只是更改发生的主分片和相应的副分片,并不一定是整个索引。

如果频率的执行refresh=true这样的操作,可能会导出生成很多很多小的段文件,这也会给后

期段文件的合并增加处理时间,因而除了更改被立即搜索到优点,可能会导致以下几个不足:

  1. 生成过多的、小的段文件;
  2. 搜索会由于过多的小的段文件存在,影响搜索效率;
  3. 后期段文件的合并,也会增加处理时间;

因而频繁使用refresh=true这样的操作,需要仔细考虑,以免得不偿失。

  1. wait_for:等待自动刷新操作的发生,通常该操作不会执行主动刷新,然后再响应。refresh=wait_for请求通常只影响其本身,不会影响其它的请求。使用refresh=wait_for的注意事项:
  1. refresh=wait_for会等到刷新发生后才会响应,过多的使用会导致索引的操作效率被降低,直接的体现就是TPS上不去;
  2. 不要同时发起过多的refresh=wait_for请求,可将其通过将多个请求合并为单个bulk请求,Elasticsearch会并行处理这些请求,直到所有的请求都执行成功且等到被刷新后,再统一返回;
  3. refresh=wait_for的监听队列是有长度限制,其受限于系统中参数index.max_refresh_listeners的配置值的影响,默认是1000,如果由于过多的refresh=wait_for请求导致该除列满了,则新的wait_for请求不能够放在该监听队列中,就只能够立即返回。由于Elasticsearch对wait_for的设计理念是只要返回了就表示已经刷新了,因而此时就会在返回前立即触发刷新操作,在响应的字段中会增加“"forced_refresh": true”这样的内容。
  1. false:这个是refresh的默认值,表示不执行刷新操作,更新的可见由系统自行调度refresh的逻辑控制。

refresh操作可操作单个索引,也可以操作多个索引,多个索引之间以英文逗号“,”分隔,也可以操作所有索引。

refresh单个索引,操作如下:

GET /new_index/_refresh

refresh多个索引,操作如下:

GET /new_index,new_index_2/_refresh

refresh全部索引,操作如下:

GET /_refresh

响应如下:

{

  "_shards" : {

    "total" : 4,

    "successful" : 3,

    "failed" : 0

  }

}

结果显示需要刷新操作的分片总共是4个,成功刷新了3个,失败了0个,还有1个副本没有刷新,是因为当前分片副本处理待分配的状态。将该索引的副本数减少1个后再执行refresh操作,总分片数就变成3个了。

​​​​​​​4、索引强制合并

强制合并的功能为强制合并一个或多个索引,目的是通过索引合并达到减少段的数量,通过POST方法执行_forcemerge API。

强制合并请求在没有执行完成之前,请求会一直被阻塞,直到执行完成才会返回,如果期间该HTTP请求由于网络或者其它原因被断开,合并请求将继续在后台执行,直到完成或发生异常结束。如果已经有强制合并正在执行,后续发起的强制合并请求将被会阻塞,直到当前正在执行的合并请求执行完后才执行。

强制合并应该只针对只读索引执行,因为针对可写的索引执行强制合并,可能会导致非常大的段文件生成(每段大于5Gb),且后续的合并策略会自动忽略这样的大文件,由于这些文件后续不能够执行合并操作,可能导致该文件中都是被删除了的文档,最终导演当前分片中存在非常大的段文件。

强制合并可以操作单个索引,也可以操作多个索引,多个索引之间以英文逗号“,”分隔,也可以操作所有索引。

强制合并单个索引,操作如下:

POST /new_index/_forcemerge

{}

强制合并多个索引,操作如下:

POST /new_index,new_index_2/_forcemerge

{}

强制合并全部索引,操作如下:

POST /_forcemerge

{}

响应如下:

{

  "_shards" : {

    "total" : 3,

    "successful" : 3,

    "failed" : 0

  }

}

响应显示待处理的总分片数为3个,成功处理3个,失败为0个。

上面的示例都没有带参数,强制合并API可以接收一些参数,用于调整其行为。

强制合并的参数

参数名称 说明
max_num_segments 设置需要合并的段数。如果需要整个索引完全合并,则将该值设置为1。默认情况下会检查合并操作是否需要执行,如果需要才执行,否则就不执行。
only_expunge_deletes

合并过程是否仅操作哪些包含了被删除文档的段,将这些段中未标识为删除的内容放到一个新创建的段中,然后将这些包含了被删除文档的段全部删除。

注:这不会覆盖index.merge.policy.expunge_deletes_allowed阈值。

flush 是否应在强制合并后执行刷新,默认为true。

继续阅读