多索引edit

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

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

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

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

事实上,只需要事先考虑一点点,添加一个新的索引就可以完全透明地完成,而你的应用程序根本不会察觉到任何的改变。

索引别名和零停机,我们提到过使用索引别名来指向当前版本的索引。 举例来说,给你的索引命名为 tweets_v1 而不是 tweets 。你的应用程序会与 tweets 进行交互,但事实上它是一个指向 tweets_v1 的别名。 这允许你随时将别名切换至新的索引(不需要停止服务)。

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

PUT /tweets_1/_alias/tweets_search 
PUT /tweets_1/_alias/tweets_index 

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

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

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

POST /_aliases
{
  "actions": [
    { "add":    { "index": "tweets_2", "alias": "tweets_search" }}, 
    { "remove": { "index": "tweets_1", "alias": "tweets_index"  }}, 
    { "add":    { "index": "tweets_2", "alias": "tweets_index"  }}  
  ]
}

添加索引 tweets_2 到别名 tweets_search

将别名 tweets_indextweets_1 切换至 tweets_2

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

一个文档 GET 请求,像一个索引写入请求那样,只能以单个索引为目标。 这导致在通过ID获取文档这样的场景下有一点复杂。作为代替,你可以对 tweets_1 以及 tweets_2 运行一个 ids 查询 搜索请求, 或者 multi-get 请求。

在处理基于时间的数据(如日志或社交事件流)时,使用多个索引来实现动态扩容是非常有利的,我们将在下一节中讨论。