多索引

最后,记住没有任何规则限制你的应用程序只使用一个索引。当我们发起一个搜索请求时,它被转发至索引中每个分片的一份拷贝(一个主分片或一个副本分片),如果我们向多个索引发出同样的请求,会发生完全相同的事情——只不过会涉及更多的分片。

TIP: 搜索 1 个有着 50 个分片的索引与搜索 50 个每个都有 1 个分片的索引完全等价:搜索请求均命中 50 个分片。

当你需要在不停服务的情况下增加容量时,下面有一些有用的建议。相较于将数据迁移到更大的索引中,你可以仅仅做下面这些操作:

  • 创建一个新的索引来存储新的数据。
  • 同时搜索两个索引来获取新数据和旧数据。

实际上,通过一点预先计划,添加一个新索引可以通过一种完全透明的方式完成,你的应用程序根本不会察觉到任何的改变。

index-aliases,我们提到过使用索引别名来指向当前版本的索引。举例来说,给你的索引命名为 tweets_v1 而不是 tweets 。你的应用程序会与 tweets 进行交互,但事实上它是一个指向 tweets_v1 的别名。这允许你将别名切换至一个更新版本的索引而保持服务运转。

我们可以使用一个类似的技术通过增加一个新索引来扩展容量。这需要一点点规划,因为你需要两个别名:一个用于搜索另一个用于索引数据:

  1. PUT /tweets_1/_alias/tweets_search <1>
  2. PUT /tweets_1/_alias/tweets_index <1>

<1> tweets_searchtweets_index 这两个别名都指向索引 tweets_1

新文档应当索引至 tweets_index ,同时,搜索请求应当对别名 tweets_search 发出。目前,这两个别名指向同一个索引。

当我们需要额外容量时,我们可以创建一个名为 tweets_2 的索引,并且像这样更新别名:

  1. POST /_aliases
  2. {
  3. "actions": [
  4. { "add": { "index": "tweets_2", "alias": "tweets_search" }}, <1>
  5. { "remove": { "index": "tweets_1", "alias": "tweets_index" }}, <2>
  6. { "add": { "index": "tweets_2", "alias": "tweets_index" }} <2>
  7. ]
  8. }

<1> 添加索引 tweets_2 到别名 tweets_search

<2> 将别名 tweets_indextweets_1 切换至 tweets_2

一个搜索请求可以以多个索引为目标,所以将搜索别名指向 tweets_1 以及 tweets_2 是完全有效的。 然而,索引写入请求只能以单个索引为目标。因此,我们必须将索引写入的别名只指向新的索引。

TIP: 一个文档 GET 请求,像一个索引写入请求那样,只能以单个索引为目标。(((“HTTP methods”, “GET”)))(((“GET method”))) 这导致在通过ID获取文档这样的场景下有一点复杂。作为代替,你可以对 tweets_1 以及 tweets_2 运行一个 {ref}/query-dsl-ids-query.html[ids 查询] 搜索请求,或者 (((“mget (multi-get) API”))){ref}/docs-multi-get.html[multi-get] 请求。

在服务运行中使用多索引来扩展索引容量对于一些使用场景有着特别的好处,像我们将在下一节中讨论的基于时间的数据例如日志或社交事件流。