我想我找到了一种方法,如果熟悉 ElasticSearch 的人可以确认它会很好用,那就太好了。
我刚刚阅读了这篇文章,最后一节启发了我这个想法:
http://www.elasticsearch.org/blog/chang-mapping-with-zero-downtime/
这个想法是创建两个别名(index_search 和 index_write),它们在开头指向同一个索引(我们称之为 index_1)。想象有一天 index_1 中的分片数量不够,在这种情况下,我们可以创建一个具有相同映射和分片数量的新索引(我们称之为 index_2),如果我们添加到 index_1本来可以的。
然后,我们更新别名 index_search 以使其指向“index_1,index_2”(index_1 和 index_2),就像在两个索引上进行搜索一样。然后,我们将 index_write 更新为 index_2,因此只在新分片上进行写入,因为 index_1 的分片被认为已满。
将来,我们可以添加一个新索引 (index_3) 并将 index_search 映射到“index_1, index_2, index_3”。
当然,在我们的应用程序中,我们将始终使用索引的别名而不是真实名称,这样转换对于应用程序将是不可见的,我们不必更改应用程序的代码。
使用 Sense 语法的示例:
PUT index_1
{
"settings": {
"number_of_shards": 1
}
}
POST _aliases
{
"actions": [
{
"add": {
"index": "index_1",
"alias": "index_search"
}
},
{
"add": {
"index": "index_1",
"alias": "index_write"
}
}
]
}
PUT index_write/article/1
{
"title":"One first index",
"article":"This is an article that is indexed on index_1"
}
PUT index_2
{
"settings": {
"number_of_shards": 2
}
}
POST _aliases
{
"actions": [
{
"add": {
"index": "index_2",
"alias": "index_search"
}
},
{
"add": {
"index": "index_2",
"alias": "index_write"
}
},
{
"remove": {
"index": "index_1",
"alias": "index_write"
}
}
]
}
PUT index_write/article/2
{
"title":"One second index",
"article":"This is an article that is indexed on index_2"
}
此解决方案的问题是,如果您更新 index_1 上的文档,而 index_write 指向 index_2,它会复制它。这意味着您必须在更新之前搜索它才能找到真正的索引。此外,您不能使用 ID 为 1 index_write 的 GET 命令。