我的索引目前有 5 个分片,所有分片都包含数据。假设我想暂时阻止特定分片中的任何更多数据。有没有办法做到这一点?
2 回答
我不知道,您是否可以直接指定某些分片来存储您的数据。但是,在开始时,您可以指定_routing值,这将确定您的数据将存储到哪个分片中。通过这种方式,您可以间接控制 elasticsearch 以将您的数据存储在特定的分片中。例如,考虑这个映射:
{
"comment" : {
"_routing" : {
"required" : true,
"path" : "blog.post_id"
}
}
}
上面的代码将获取提供给它的 _routing 路径的哈希值,并根据哈希值选择将要存储到的分片。因此,最终,特定帖子的所有评论都将存储在同一个分片中。
人们之所以选择自定义路由而不是普通路由,即通常我们希望将数据存储在特定分片中的原因是为了提高搜索查询的性能。您可以指定分片将执行搜索的路由值。
我不确定您为什么希望您的数据仅存储在某些分片中。
这是一个很好的博客,它解释了为什么您希望将数据存储在特定的分片中,以及自定义路由将如何帮助您实现这一目标。
这是一个老问题,但今天它仍然非常相关,当我遇到类似的情况时,我来到这篇文章,我必须将文档分配给特定的分片,而不是随机的或主要的。
_routing
您可以通过Elasticsearch 的字段来实现这一点,方法是使用 Elasticsearch 给定的公式计算分片数:
shard_num = hash(_routing) % num_primary_shards
假设您不想将文档分配给 2 号分片,并且当从其哈希和分片编号中获取模数时,当分片编号不是 2 时,您必须提供路由名称。为此,您必须找到一个路由名称,为了在代码中进行解释,我将在 Java 中给出一个示例,以查找具有特定路由名称的分片号:
String routing = "routingName11";
final int numberOfShard = 30;
final int shard = routing.hashCode() % numberOfShard;
System.out.println("Routing: " + routing + " - shard number: " + shard);
输出:
Routing: routingName11 - shard number: -25
您必须确保您在索引中提供的路由名称不会导致生成该特定分片号。和上面一样,30 的模数routingName11
是 25,这是一个分片数。在这种情况下,您确实需要担心,因为索引文档不会存在于 2 号分片中。
作为一个完整的示例,我想演示使用路由名称进行索引:
假设我们创建“课程”索引并设置所需的路由:
PUT http://localhost:9200/course
{
"settings": {
"number_of_shards": 30
},
"mappings": {
"_routing": {
"required": true
}
}
}
然后你索引一个这样的文档:
PUT http://localhost:9200/course_index/_doc/1?routing=tenant0&refresh=true
{
"id": 1,
"title": "Data Security course in Lidl",
"description": "The course teaches our core Data Security measurements here in Lidle. As new regulations are out, ....",
"text": "Text of the couse goes here",
"created_date": 152625632,
"last_date": 152625632,
"expiration_date": null,
"domain_id": 10,
"language_id": 2
}
在我们的案例中,我们有一个多租户软件,其中大约 100 个租户(组织)在 Elasticsearch 中共享相同的索引,我们必须确保一个租户永远无法看到其他租户的数据的数据安全性。我们的解决方案是为所有租户创建一个包含 100 个分片的索引,并通过为每个租户找到一个路由名称来为每个租户分配一个分片。正如您在上面的索引映射示例中所见,路由设置为“必需”,每当您将 CRUD 操作发送到 Elasticsearch 时,您都必须定义路由,否则 Elasticsearch 将抛出routing_missing_exception