跨集群搜索
edit跨集群搜索
edit跨集群搜索允许您对一个或多个远程集群运行单个搜索请求。例如,您可以使用跨集群搜索来过滤和分析存储在不同数据中心的集群上的日志数据。
支持的API
edit以下API支持跨集群搜索:
- 搜索
- 异步搜索
- 多搜索
- 搜索模板
- 多搜索模板
- 字段能力
- Painless 执行 API
- 解析索引 API
- [预览] 此功能处于技术预览阶段,可能会在未来的版本中更改或删除。Elastic 将努力修复任何问题,但技术预览版中的功能不受官方 GA 功能支持 SLA 的约束。 EQL 搜索
- [预览] 此功能处于技术预览阶段,可能会在未来的版本中更改或删除。Elastic 将努力修复任何问题,但技术预览版中的功能不受官方 GA 功能支持 SLA 的约束。 SQL 搜索
- [预览] 此功能处于技术预览阶段,可能会在未来的版本中更改或删除。Elastic 将努力修复任何问题,但技术预览版中的功能不受官方 GA 功能支持 SLA 的约束。 矢量瓦片搜索
- [预览] 此功能处于技术预览阶段,可能会在未来的版本中更改或删除。Elastic 将努力修复任何问题,但技术预览版中的功能不受官方 GA 功能支持 SLA 的约束。 ES|QL
先决条件
edit-
跨集群搜索需要远程集群。要在 Elasticsearch Service 上设置远程集群,请参阅 在 Elasticsearch Service 上配置远程集群。如果您在自己的硬件上运行 Elasticsearch,请参阅 远程集群。
要确保您的远程集群配置支持跨集群搜索,请参阅 支持的跨集群搜索配置。
- 为了实现完整的跨集群搜索功能,本地和远程集群必须在相同的 订阅级别。
-
本地协调节点必须具有
remote_cluster_client节点角色。
-
如果你使用嗅探模式,本地协调节点必须能够连接到远程集群的种子节点和网关节点。
我们建议使用能够作为协调节点的网关节点。种子节点可以是这些网关节点的一个子集。
-
如果您使用代理模式,本地协调节点必须能够连接到配置的
proxy_address。该地址的代理必须能够将连接路由到远程集群上的网关节点和协调节点。 - 跨集群搜索需要在本地集群和远程集群上具有不同的安全权限。请参阅配置跨集群搜索的权限和远程集群。
跨集群搜索示例
edit远程集群设置
edit以下集群更新设置 API 请求添加了三个远程集群:cluster_one、cluster_two 和 cluster_three。
PUT _cluster/settings
{
"persistent": {
"cluster": {
"remote": {
"cluster_one": {
"seeds": [
"35.238.149.1:9300"
],
"skip_unavailable": true
},
"cluster_two": {
"seeds": [
"35.238.149.2:9300"
],
"skip_unavailable": false
},
"cluster_three": {
"seeds": [
"35.238.149.3:9300"
]
}
}
}
}
}
|
由于未在 |
搜索单个远程集群
edit在搜索请求中,您可以在远程集群上指定数据流和索引,格式为 。
以下搜索 API 请求在一个远程集群 cluster_one 上搜索 my-index-000001 索引。
GET /cluster_one:my-index-000001/_search
{
"size": 1,
"query": {
"match": {
"user.id": "kimchy"
}
},
"_source": ["user.id", "message", "http.response.status_code"]
}
API返回以下响应。请注意,当您搜索一个或多个远程集群时,会包含一个_clusters部分,以提供有关每个集群搜索的信息。
{
"took": 150,
"timed_out": false,
"_shards": {
"total": 12,
"successful": 12,
"failed": 0,
"skipped": 0
},
"_clusters": {
"total": 1,
"successful": 1,
"skipped": 0,
"running": 0,
"partial": 0,
"failed": 0,
"details": {
"cluster_one": {
"status": "successful",
"indices": "my-index-000001",
"took": 148,
"timed_out": false,
"_shards": {
"total": 12,
"successful": 12,
"skipped": 0,
"failed": 0
}
}
}
},
"hits": {
"total" : {
"value": 1,
"relation": "eq"
},
"max_score": 1,
"hits": [
{
"_index": "cluster_one:my-index-000001",
"_id": "0",
"_score": 1,
"_source": {
"user": {
"id": "kimchy"
},
"message": "GET /search HTTP/1.1 200 1070000",
"http": {
"response":
{
"status_code": 200
}
}
}
}
]
}
}
|
此部分的计数器显示所有可能的集群搜索状态以及当前处于该状态的集群搜索数量。集群可以是以下状态之一:运行中、
成功(所有分片上的搜索都成功)、部分成功(至少一个分片上的搜索成功,且至少一个失败)、跳过(在标记为 |
|
|
The |
|
|
用户提供的索引表达式。如果你提供了一个通配符,例如 |
|
|
在该集群上子搜索花费的时间(以毫秒为单位)。 |
|
|
该集群上子搜索的分片详情。 |
|
|
搜索响应体中包含了远程集群的名称,位于 |
搜索多个远程集群
edit以下搜索 API 请求在三个集群上搜索 my-index-000001 索引:
- 本地(查询)集群,有10个分片
-
两个远程集群,
cluster_one,有12个分片和cluster_two有6个分片。
GET /my-index-000001,cluster_one:my-index-000001,cluster_two:my-index-000001/_search
{
"query": {
"match": {
"user.id": "kimchy"
}
},
"_source": ["user.id", "message", "http.response.status_code"]
}
API返回以下响应:
{
"took": 150,
"timed_out": false,
"num_reduce_phases": 4,
"_shards": {
"total": 28,
"successful": 28,
"failed": 0,
"skipped": 0
},
"_clusters": {
"total": 3,
"successful": 3,
"skipped": 0,
"running": 0,
"partial": 0,
"failed": 0,
"details": {
"(local)": {
"status": "successful",
"indices": "my-index-000001",
"took": 21,
"timed_out": false,
"_shards": {
"total": 10,
"successful": 10,
"skipped": 0,
"failed": 0
}
},
"cluster_one": {
"status": "successful",
"indices": "my-index-000001",
"took": 48,
"timed_out": false,
"_shards": {
"total": 12,
"successful": 12,
"skipped": 0,
"failed": 0
}
},
"cluster_two": {
"status": "successful",
"indices": "my-index-000001",
"took": 141,
"timed_out": false,
"_shards": {
"total" : 6,
"successful" : 6,
"skipped": 0,
"failed": 0
}
}
}
},
"hits": {
"total" : {
"value": 3,
"relation": "eq"
},
"max_score": 1,
"hits": [
{
"_index": "my-index-000001",
"_id": "0",
"_score": 2,
"_source": {
"user": {
"id": "kimchy"
},
"message": "GET /search HTTP/1.1 200 1070000",
"http": {
"response":
{
"status_code": 200
}
}
}
},
{
"_index": "cluster_one:my-index-000001",
"_id": "0",
"_score": 1,
"_source": {
"user": {
"id": "kimchy"
},
"message": "GET /search HTTP/1.1 200 1070000",
"http": {
"response":
{
"status_code": 200
}
}
}
},
{
"_index": "cluster_two:my-index-000001",
"_id": "0",
"_score": 1,
"_source": {
"user": {
"id": "kimchy"
},
"message": "GET /search HTTP/1.1 200 1070000",
"http": {
"response":
{
"status_code": 200
}
}
}
}
]
}
}
使用异步搜索进行跨集群搜索,设置ccs_minimize_roundtrips=true
edit可以使用异步搜索 API 异步查询远程集群。
跨集群搜索接受一个ccs_minimize_roundtrips参数。对于
异步搜索,它默认为false。(注意:对于同步搜索,它默认为true。)
请参阅选择是否在跨集群搜索中减少往返次数的注意事项以了解更多关于此选项的信息。
以下请求使用ccs_minimize_roundtrips=true对三个集群(与前一个示例相同的集群)进行my-index-000001索引的异步搜索。
POST /my-index-000001,cluster_one:my-index-000001,cluster_two:my-index-000001/_async_search?ccs_minimize_roundtrips=true
{
"query": {
"match": {
"user.id": "kimchy"
}
},
"_source": ["user.id", "message", "http.response.status_code"]
}
API返回以下响应:
{
"id": "FklQYndoTDJ2VEFlMEVBTzFJMGhJVFEaLVlKYndBWWZSMUdicUc4WVlEaFl4ZzoxNTU=",
"is_partial": true,
"is_running": true,
"start_time_in_millis": 1685563581380,
"expiration_time_in_millis": 1685995581380,
"response": {
"took": 1020,
"timed_out": false,
"num_reduce_phases": 0,
"_shards": {
"total": 10,
"successful": 0,
"failed": 0,
"skipped": 0
},
"_clusters": {
"total" : 3,
"successful" : 0,
"skipped": 0,
"running": 3,
"partial": 0,
"failed": 0,
"details": {
"(local)": {
"status": "running",
"indices": "my-index-000001",
"timed_out": false
},
"cluster_one": {
"status": "running",
"indices": "my-index-000001",
"timed_out": false
},
"cluster_one": {
"status": "running",
"indices": "my-index-000001",
"timed_out": false
}
}
},
"hits": {
"total" : {
"value": 0,
"relation": "eq"
},
"max_score": null,
"hits": []
}
}
}
|
异步搜索ID。 |
|
|
当 |
|
|
The |
如果您在查询仍在运行时查询获取异步搜索端点,您将在响应的_clusters和_shards部分看到更新,因为每个集群完成其搜索。
如果你设置ccs_minimize_roundtrips=false,那么你还将看到来自已完成的分片(来自任何集群)的部分聚合结果,但在搜索完成之前,“hits”部分不会显示任何结果。
如果你设置ccs_minimize_roundtrips=true,那么你将在响应的“hits”和“aggregations”部分看到所有已完成集群的部分结果。(注意:即使本地集群尚未完成,你也可以看到来自本地集群的部分聚合结果。)下面的示例展示了ccs_minimize_roundtrips=true的情况。
GET /_async_search/FklQYndoTDJ2VEFlMEVBTzFJMGhJVFEaLVlKYndBWWZSMUdicUc4WVlEaFl4ZzoxNTU=
响应:
{
"id": "FklQYndoTDJ2VEFlMEVBTzFJMGhJVFEaLVlKYndBWWZSMUdicUc4WVlEaFl4ZzoxNTU=",
"is_partial": true,
"is_running": true,
"start_time_in_millis": 1685564911108,
"expiration_time_in_millis": 1685996911108,
"response": {
"took": 11164,
"timed_out": false,
"terminated_early": false,
"_shards": {
"total": 22,
"successful": 22,
"skipped": 0,
"failed": 0
},
"_clusters": {
"total": 3,
"successful": 2,
"skipped": 0,
"running": 1,
"partial": 0,
"failed": 0,
"details": {
"(local)": {
"status": "successful",
"indices": "my-index-000001",
"took": 2034,
"timed_out": false,
"_shards": {
"total": 10,
"successful": 10,
"skipped": 0,
"failed": 0
}
},
"cluster_one": {
"status": "successful",
"indices": "my-index-000001",
"took": 9039,
"timed_out": false,
"_shards": {
"total": 12,
"successful": 12,
"skipped": 0,
"failed": 0
}
},
"cluster_two": {
"status": "running",
"indices": "my-index-000001",
"timed_out": false
}
}
},
"hits": {
"total": {
"value": 542,
"relation": "eq"
},
"max_score": 1.7232,
"hits": [...list of hits here...]
}
}
}
|
本地集群和远程 |
|
|
由于两个集群已完成搜索,"successful" 集群条目设置为 2,"running" 集群条目减少到 1。每个集群完成后, |
|
|
截至目前已完成搜索的命中次数。最终的命中结果不会显示,直到所有集群上的搜索都已完成并合并。因此,"hits"部分可能会在你调用此端点时发生变化,直到搜索完全完成。 |
在所有集群的搜索完成后,查询
获取异步搜索端点将显示_clusters和_shards部分的最终状态,以及命中结果和任何聚合结果。
GET /_async_search/FklQYndoTDJ2VEFlMEVBTzFJMGhJVFEaLVlKYndBWWZSMUdicUc4WVlEaFl4ZzoxNTU=
响应:
{
"id": "FklQYndoTDJ2VEFlMEVBTzFJMGhJVFEaLVlKYndBWWZSMUdicUc4WVlEaFl4ZzoxNTU=",
"is_partial": false,
"is_running": false,
"start_time_in_millis": 1685564911108,
"expiration_time_in_millis": 1685996911108,
"completion_time_in_millis": 1685564938727,
"response": {
"took": 27619,
"timed_out": false,
"num_reduce_phases": 4,
"_shards": {
"total": 28,
"successful": 28,
"skipped": 0,
"failed": 0
},
"_clusters": {
"total": 3,
"successful": 3,
"skipped": 0,
"running": 0,
"partial": 0,
"failed": 0,
"details": {
"(local)": {
"status": "successful",
"indices": "my-index-000001",
"took": 2034,
"timed_out": false,
"_shards": {
"total": 10,
"successful": 10,
"skipped": 0,
"failed": 0
}
},
"cluster_one": {
"status": "successful",
"indices": "my-index-000001",
"took": 9039,
"timed_out": false,
"_shards": {
"total": 12,
"successful": 12,
"skipped": 0,
"failed": 0
}
},
"cluster_two": {
"status": "successful",
"indices": "my-index-000001",
"took": 27550,
"timed_out": false,
"_shards": {
"total": 6,
"successful": 6,
"skipped": 0,
"failed": 0
}
}
}
},
"hits": {
"total": {
"value": 1067,
"relation": "eq"
},
"max_score": 1.8293576,
"hits": [...list of hits here...]
}
}
}
|
搜索完成后,completion_time 会出现。 |
|
|
现在, |
|
|
The |
跨集群搜索失败
edit跨集群搜索期间失败可能导致以下两种情况之一:
- 部分结果(2xx HTTP状态码)
- 搜索失败(4xx或5xx HTTP状态码)
失败详情将在两种情况下出现在搜索响应中。
如果一个标记为 skip_unavailable=false 的集群不可用、在搜索过程中断开连接或在所有分片上搜索失败,搜索将会失败。在所有其他情况下,失败将导致部分结果。
在响应的 _shards 部分和 _clusters 部分中都会出现单个分片上的搜索失败。
失败的搜索将在响应中有一个额外的顶级errors条目。
这是一个由于一个集群中的一个分片失败而导致部分结果的搜索示例。搜索类似于之前展示的那些。这里使用了_async_search/status端点来显示完成状态,而不显示命中结果。
GET /_async_search/status/FmpwbThueVB4UkRDeUxqb1l4akIza3cbWEJyeVBPQldTV3FGZGdIeUVabXBldzoyMDIw
响应:
{
"id": "FmpwbThueVB4UkRDeUxqb1l4akIza3cbWEJyeVBPQldTV3FGZGdIeUVabXBldzoyMDIw",
"is_partial": true,
"is_running": false,
"start_time_in_millis": 1692106901478,
"expiration_time_in_millis": 1692538901478,
"completion_time_in_millis": 1692106903547,
"response": {
"took": 2069,
"timed_out": false,
"num_reduce_phases": 4,
"_shards": {
"total": 28,
"successful": 27,
"skipped": 0,
"failed": 1,
"failures": [
{
"shard": 1,
"index": "cluster_two:my-index-000001",
"node": "LMpUnAu0QEeCUMfg_56sAg",
"reason": {
"type": "query_shard_exception",
"reason": "failed to create query: [my-index-000001][1] exception message here",
"index_uuid": "4F2VWx8RQSeIhUE-nksvCQ",
"index": "cluster_two:my-index-000001",
"caused_by": {
"type": "runtime_exception",
"reason": "runtime_exception: [my-index-000001][1] exception message here"
}
}
}
]
},
"_clusters": {
"total": 3,
"successful": 2,
"skipped": 0,
"running": 0,
"partial": 1,
"failed": 0,
"details": {
"(local)": {
"status": "successful",
"indices": "my-index-000001",
"took": 1753,
"timed_out": false,
"_shards": {
"total": 10,
"successful": 10,
"skipped": 0,
"failed": 0
}
},
"cluster_one": {
"status": "successful",
"indices": "my-index-000001",
"took": 2054,
"timed_out": false,
"_shards": {
"total": 12,
"successful": 12,
"skipped": 0,
"failed": 0
}
},
"cluster_two": {
"status": "partial",
"indices": "my-index-000001",
"took": 2039,
"timed_out": false,
"_shards": {
"total": 6,
"successful": 5,
"skipped": 0,
"failed": 1
},
"failures": [
{
"shard": 1,
"index": "cluster_two:my-index-000001",
"node": "LMpUnAu0QEeCUMfg_56sAg",
"reason": {
"type": "query_shard_exception",
"reason": "failed to create query: [my-index-000001][1] exception message here",
"index_uuid": "4F2VWx8RQSeIhUE-nksvCQ",
"index": "cluster_two:my-index-000001",
"caused_by": {
"type": "runtime_exception",
"reason": "runtime_exception: [my-index-000001][1] exception message here"
}
}
}
]
}
}
},
"hits": {
}
}
}
|
搜索结果被标记为部分结果,因为至少有一个分片搜索失败。 |
|
|
The |
|
|
有部分结果的集群仍标记为“部分”。只有在搜索未返回任何数据时,它们才会被标记为“跳过”(或“失败”)。 |
|
|
已将 |
|
|
失败的shard数量已显示。 |
|
|
分片故障也会列在集群/详细信息条目下。 |
这里有一个示例,其中 cluster_one 和 cluster_two 在跨集群搜索期间失去了连接。由于 cluster_one 被标记为 skip_unavailable=true,其状态为 skipped,而由于 cluster_two 被标记为 skip_unavailable=false,其状态为 failed。由于存在一个 failed 的集群,还会出现一个顶级的 error,并返回 HTTP 状态码 500(未显示)。
如果您希望在集群不可用时搜索仍能返回结果,请为所有远程集群设置skip_unavailable=true。
GET /_async_search/FjktRGJ1Y2w1U0phLTRhZnVyeUZ2MVEbWEJyeVBPQldTV3FGZGdIeUVabXBldzo5NzA4
响应:
{
"id": "FjktRGJ1Y2w1U0phLTRhZnVyeUZ2MVEbWEJyeVBPQldTV3FGZGdIeUVabXBldzo5NzA4",
"is_partial": true,
"is_running": false,
"start_time_in_millis": 1692112102650,
"expiration_time_in_millis": 1692544102650,
"completion_time_in_millis": 1692112106177,
"response": {
"took": 3527,
"timed_out": false,
"terminated_early": false,
"_shards": {
"total": 10,
"successful": 10,
"skipped": 0,
"failed": 0
},
"_clusters": {
"total": 3,
"successful": 1,
"skipped": 1,
"running": 0,
"partial": 0,
"failed": 1,
"details": {
"(local)": {
"status": "successful",
"indices": "my-index-000001",
"took": 1473,
"timed_out": false,
"_shards": {
"total": 10,
"successful": 10,
"skipped": 0,
"failed": 0
}
},
"cluster_one": {
"status": "skipped",
"indices": "my-index-000001",
"timed_out": false,
"failures": [
{
"shard": -1,
"index": null,
"reason": {
"type": "node_disconnected_exception",
"reason": "[myhostname1][35.238.149.1:9300][indices:data/read/search] disconnected"
}
}
]
},
"cluster_two": {
"status": "failed",
"indices": "my-index-000001",
"timed_out": false,
"failures": [
{
"shard": -1,
"index": null,
"reason": {
"type": "node_disconnected_exception",
"reason": "[myhostname2][35.238.149.2:9300][indices:data/read/search] disconnected"
}
}
]
}
}
},
"hits": {
},
}
"error": {
"type": "status_exception",
"reason": "error while executing search",
"caused_by": {
"type": "node_disconnected_exception",
"reason": "[myhostname2][35.238.149.2:9300][indices:data/read/search] disconnected"
}
}
}
|
当发生此类错误时,分片计数通常只会是部分计数,因为我们每次搜索时都需要能够从远程集群获取分片信息。 |
|
|
|
|
|
失败列表显示远程集群节点已与查询集群断开连接。 |
|
|
|
|
|
当存在“失败”的集群时,会包含一个顶级的 |
从跨集群搜索中排除集群或索引
edit如果您使用通配符来包含一个大型集群和/或索引列表,您可以使用-减号明确排除一个或多个集群或索引。
要排除整个集群,您可以在集群别名前加上减号,例如:-mycluster:*。在排除集群时,您必须在索引位置使用*,否则将返回错误。
要排除特定的远程索引,您可以在索引前加上减号,例如 mycluster:-myindex。
排除一个远程集群
以下是如何在跨集群搜索中排除cluster_three,该搜索使用通配符来指定集群列表:
POST /my-index-000001,cluster*:my-index-000001,-cluster_three:*/_async_search { "query": { "match": { "user.id": "kimchy" } }, "_source": ["user.id", "message", "http.response.status_code"] }
|
符号 |
排除远程索引
假设您想要搜索所有匹配 my-index-* 的索引,但您希望排除 cluster_three 上的 my-index-000001。以下是您可以执行此操作的方法:
POST /my-index-000001,cluster*:my-index-*,cluster_three:-my-index-000001/_async_search { "query": { "match": { "user.id": "kimchy" } }, "_source": ["user.id", "message", "http.response.status_code"] }
使用异步搜索进行跨集群搜索,设置ccs_minimize_roundtrips=false
edit当 ccs_minimize_roundtrips 为 false 时,响应中的 _shards 和 _clusters 部分的行为会有所不同。
主要区别如下:
-
_shards部分的总量统计将立即准确,因为搜索开始前会从所有集群中收集分片的总数。 -
_shards部分将随着单个分片上的搜索完成而逐步更新,而在减少往返次数的情况下,分片部分将在本地集群上的分片搜索完成后更新,然后随着每个远程集群报告其完整的搜索结果而更新。 -
_cluster部分一开始就会列出其所有分片计数,因为这些计数也是在查询阶段开始之前获得的。
示例使用与上一节相同的设置(ccs_minimize_roundtrips=true):
POST /my-index-000001,cluster_one:my-index-000001,cluster_two:my-index-000001/_async_search?ccs_minimize_roundtrips=false
{
"query": {
"match": {
"user.id": "kimchy"
}
},
"_source": ["user.id", "message", "http.response.status_code"]
}
如果查询时间超过wait_for_completion_timeout时长,API将返回以下响应(参见异步搜索)。
{
"id": "FklQYndoTDJ2VEFlMEVBTzFJMGhJVFEaLVlKYndBWWZSMUdicUc4WVlEaFl4ZzoxNTU=",
"is_partial": true,
"is_running": true,
"start_time_in_millis": 1685563581380,
"expiration_time_in_millis": 1685995581380,
"response": {
"took": 1020,
"timed_out": false,
"_shards": {
"total": 28,
"successful": 0,
"failed": 0,
"skipped": 0
},
"_clusters": {
"total" : 3,
"successful": 0,
"skipped": 0,
"running": 3,
"partial": 0,
"failed": 0,
"details": {
"(local)": {
"status": "running",
"indices": "my-index-000001",
"timed_out": false,
"_shards": {
"total": 10,
"successful": 0,
"skipped": 0,
"failed": 0
}
},
"cluster_one": {
"status": "running",
"indices": "my-index-000001",
"timed_out": false,
"_shards": {
"total": 12,
"successful": 0,
"skipped": 0,
"failed": 0
}
},
"cluster_two": {
"status": "running",
"indices": "my-index-000001",
"timed_out": false,
"_shards": {
"total": 6,
"successful": 0,
"skipped": 0,
"failed": 0
}
}
}
},
"hits": {
"total" : {
"value": 0,
"relation": "eq"
},
"max_score": null,
"hits": []
}
}
}
|
所有参与搜索的集群中的所有分片都在这里列出。请关注此部分和/或_clusters部分以监控搜索进度。 |
|
|
从 |
|
|
The |
可选的远程集群
edit默认情况下,如果请求中的远程集群不可用或在所有分片上搜索失败并返回错误,跨集群搜索将失败。使用skip_unavailable集群设置将特定远程集群标记为跨集群搜索的可选或必需。
在 Elasticsearch 8.15 中,skip_unavailable 的默认值从 false 更改为 true。在 Elasticsearch 8.15 之前,如果您希望将一个集群视为跨集群搜索的可选集群,则需要设置该配置。从 Elasticsearch 8.15 开始,您需要设置配置以使一个集群成为跨集群搜索的必需集群。
如果 skip_unavailable 为 true,跨集群搜索:
-
如果在搜索期间远程集群的节点不可用,则跳过该远程集群。响应的
_clusters.skipped值包含任何跳过的集群的计数,并且响应的_clusters.details部分将显示skipped状态。 -
忽略远程集群返回的错误,例如与不可用分片或索引相关的错误。这可能包括与搜索参数相关的错误,例如
allow_no_indices和ignore_unavailable。 -
忽略在远程集群上搜索时的
allow_partial_search_results参数以及相关的search.default_allow_partial_results集群设置。这意味着在远程集群上的搜索可能会返回部分结果。
您可以通过编辑 elasticsearch.yml 配置文件中的 cluster.remote. 设置来修改 skip_unavailable 设置。例如:
cluster:
remote:
cluster_one:
seeds: 35.238.149.1:9300
skip_unavailable: false
cluster_two:
seeds: 35.238.149.2:9300
skip_unavailable: true
或者,您可以通过集群更新设置 API 设置 cluster.remote 设置,如此处所示。
当配置了skip_unavailable: true(如上面的cluster_two)的远程集群在跨集群搜索期间断开连接或不可用时,Elasticsearch不会在最终结果中包含该集群的匹配文档,并且搜索将被视为成功(HTTP状态200 OK)。
如果集群中至少有一个分片提供了搜索结果,这些结果将被使用,搜索将返回部分数据。无论远程集群的skip_unavailable设置如何,这都是成立的。(如果在使用异步搜索进行跨集群搜索时,is_partial字段将被设置为true以指示部分结果。)
跨集群搜索如何处理网络延迟
edit由于跨集群搜索涉及向远程集群发送请求,任何网络延迟都可能影响搜索速度。为了避免搜索缓慢,跨集群搜索提供了两种处理网络延迟的选项:
- Minimize network roundtrips
-
默认情况下,Elasticsearch减少了远程集群之间的网络往返次数。这减少了网络延迟对搜索速度的影响。然而,Elasticsearch无法减少大型搜索请求的网络往返次数,例如那些包括滚动或 内部命中的请求。
请参阅在跨集群搜索中选择是否最小化往返次数的考虑因素以了解此选项的工作原理。
- Don’t minimize network roundtrips
-
对于包含滚动或内部命中的搜索请求,Elasticsearch会向每个远程集群发送多个出站和入站请求。您也可以通过将
ccs_minimize_roundtrips参数设置为false来选择此选项。虽然通常较慢,但这种方法可能适用于低延迟的网络。参见不要最小化网络往返以了解此选项的工作原理。
The vector tile search API 总是最小化网络往返次数,并且不包含 ccs_minimize_roundtrips 参数。
近似kNN搜索不支持最小化网络往返次数,并将参数ccs_minimize_roundtrips设置为false。
选择是否在跨集群搜索中减少往返次数的考虑因素
edit减少往返次数的优点:
- 对于查询大量分片的跨集群搜索,minimize roundtrips选项通常会提供更好的性能。如果被搜索的集群具有高网络延迟(例如,远地理区域),这一点尤其明显。
-
在进行异步跨集群搜索时,
GET _async_search/端点将提供所有已返回结果的集群的顶部命中和聚合,即使在其他集群上搜索仍在进行时也是如此。换句话说,它会在搜索进行过程中提供“增量”的部分结果。请注意,如果本地集群包含在搜索中,它有特殊的处理方式,即在本地集群上的搜索仍在进行时,可以显示部分聚合(但不包括部分顶部命中)。
在使用异步搜索时不最小化往返次数,可以在搜索仍在进行时,随着单个分片完成(而不是整个集群),获取查询中任何聚合的增量结果,但在所有集群上的搜索完成之前,不会显示顶部命中。
默认情况下,同步搜索会减少往返次数,而异步搜索则不会。您可以通过使用ccs_minimize_roundtrips参数来覆盖默认设置,将其设置为true或false,如本文档前面几个示例所示。
最小化网络往返次数
edit以下是当您最小化网络往返时跨集群搜索的工作原理。
-
您向本地集群发送了一个跨集群搜索请求。该集群中的协调节点接收并解析了请求。
-
协调节点向每个集群发送一个搜索请求,包括本地集群。每个集群独立执行搜索请求,并应用其自身的集群级别设置到请求中。
-
每个远程集群将其搜索结果发送回协调节点。
-
在从每个集群收集结果后,协调节点在跨集群搜索响应中返回最终结果。
不要最小化网络往返次数
edit以下是不减少网络往返时跨集群搜索的工作原理。
-
您向本地集群发送了一个跨集群搜索请求。该集群中的协调节点接收并解析了请求。
-
协调节点发送一个“搜索分片”传输层请求到每个远程集群,以使它们执行一个“可以匹配”搜索,以确定每个集群上应该搜索哪些分片。
-
每个远程集群将其响应发送回协调节点。 此响应包含有关将在其上执行跨集群搜索请求的索引和分片的信息。
-
协调节点将搜索请求发送到每个分片,包括其自身集群中的分片。每个分片独立执行搜索请求。
当网络往返未被最小化时,搜索将执行,就好像所有数据都在协调节点的集群中一样。我们建议更新集群级别的设置,以限制搜索,例如
action.search.shard_count.limit、pre_filter_shard_size和max_concurrent_shard_requests,以适应这种情况。如果这些限制设置得太低,搜索可能会被拒绝。 -
每个分片将其搜索结果发送回协调节点。
-
在从每个集群收集结果后,协调节点在跨集群搜索响应中返回最终结果。
支持的跨集群搜索配置
edit在8.0+版本中,Elastic支持从本地集群到远程集群的搜索,运行:
- 上一个次要版本。
- 相同版本。
- 同一主要版本中的较新次要版本。
Elastic 还支持从运行主要版本最后一个次版本的本地集群搜索到运行下一个主要版本任何次版本的远程集群。例如,本地 7.17 集群可以搜索任何远程 8.x 集群。
远程集群版本 |
|||||||||||||||||||
本地集群版本 |
6.8 |
7.1–7.16 |
7月17日 |
8.0 |
8.1 |
8.2 |
8.3 |
8.4 |
8.5 |
8.6 |
8.7 |
8.8 |
8.9 |
8.10 |
8.11 |
8.12 |
8.13 |
8.14 |
8.15 |
6.8 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7.1–7.16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7月17日 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8.0 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8.1 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8.2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8.3 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8.4 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8.5 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8.6 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8.7 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8.8 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8.9 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8.10 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8.11 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8.12 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8.13 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8.14 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8月15日 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
对于EQL search API,如果本地和远程集群的版本在7.17.7(包括)之前或8.5.1(包括)之前,它们必须使用相同的Elasticsearch版本。
例如,本地 8.0 集群可以搜索远程 7.17 或任何远程 8.x 集群。然而,从本地 8.0 集群到远程 7.16 或 6.8 集群的搜索是不支持的。
仅支持在所有搜索的集群中都存在的功能。如果在不支持该功能的远程集群中使用该功能,将导致未定义的行为。
使用不支持配置的跨集群搜索可能仍然有效。然而,此类搜索未经过Elastic的测试,其行为不保证。
确保跨集群搜索支持
edit确保您的集群支持跨集群搜索的最简单方法是保持每个集群在同一版本的Elasticsearch上。如果您需要维护不同版本的集群,您可以:
- 维护一个专用的跨集群搜索集群。将此集群保持在所需搜索其他集群的最早版本。例如,如果您有7.17和8.x集群,您可以维护一个专用的7.17集群,用作跨集群搜索的本地集群。
- 保持每个集群之间的次要版本不超过一个。这使您可以在运行跨集群搜索时将任何集群用作本地集群。
升级期间的跨集群搜索
edit在本地集群进行滚动升级时,您仍然可以搜索远程集群。然而,本地协调节点的“升级自”和“升级至”版本必须与远程集群的网关节点兼容。
在同一集群中运行多个版本的Elasticsearch超过升级期间是不支持的。
有关升级的更多信息,请参阅 升级 Elasticsearch。