失败存储区 (Failure store)
失败存储是数据流内部的一组辅助索引,专用于存储失败的文档。失败的文档是指在未启用失败存储的情况下,会导致摄取管道异常或其结构与数据流的映射发生冲突的任何文档。如果没有失败存储,失败的文档将导致索引操作失败,并在操作响应中返回错误消息。
当启用数据流的失败存储时,这些失败将被捕获到一个单独的索引中并持久化,以便以后进行分析。客户端会收到一个带有标志的成功响应,该标志指示失败已被重定向。
失败存储附加到单个数据流。如果 reroute 处理器 更改了索引请求的目标数据流,后续的失败将被重定向到新目标的失败存储(如果已启用)。
失败存储不会捕获由背压、安全问题或文档版本冲突引起的失败。这些失败总是按原样返回,因为它们需要客户端采取特定的操作。
在本页中,您将了解如何设置、使用和管理失败存储,以及失败存储文档的结构。
有关如何使用失败存储来识别和修复摄取管道及数据中的错误的示例,请参阅 使用失败存储解决摄取问题。
要在 Elastic Stack 中查看和修改失败存储,您需要以下数据流级别的权限
read_failure_storemanage_failure_store
有关更多信息,请参考 授予数据流和别名的权限。
每个数据流都有自己的失败存储,可以启用它来接受失败的文档。默认情况下,此失败存储是禁用的,任何摄取问题都会在对写入操作的响应中抛出。
您可以在数据流的 索引模板 中指定它在首次创建时是否应启用失败存储。
要在新数据流上启用失败存储,请在模板的 data_stream_options 中启用它
PUT _index_template/my-index-template
{
"index_patterns": ["my-datastream-*"],
"data_stream": { },
"template": {
"data_stream_options": {
"failure_store": {
"enabled": true
}
}
}
}
- 要在创建时应用的数据流选项。
- 将为匹配此模板的新数据流启用失败存储功能。
创建匹配的数据流后,将启用其失败存储。
使用 索引模板 启用失败存储只能影响新创建的数据流。使用模板的现有数据流不会受到模板的 data_stream_options 字段更改的影响。要修改现有数据流的选项,请使用 put data stream options API
PUT _data_stream/my-datastream-existing/_options
{
"failure_store": {
"enabled": true
}
}
- 失败存储选项现在将启用。
也可以使用此 API 禁用失败存储重定向。当停用失败存储时,仅暂停失败文档重定向。数据流中的任何现有失败数据都将保留,直到通过手动删除将其移除,或者直到数据因达到其最大配置保留期而过期。
PUT _data_stream/my-datastream-existing/_options
{
"failure_store": {
"enabled": false
}
}
- 将失败文档重定向到失败存储的操作现在将被禁用。
您还可以在 Kibana 中启用数据流失败存储。在 Streams 页面上定位该数据流(其中 stream 直接映射到一个数据流)。选择一个 stream 以查看其详细信息,然后转到 Retention 选项卡,在那里您可以找到 Enable failure store 选项。
如果您有大量现有的数据流,您可能希望在一个地方启用它们的失败存储。与其分别更新它们的每个选项,不如在 集群设置 中将 data_streams.failure_store.enabled 设置为索引模式列表。任何匹配这些模式之一的数据流在运行时都会启用其失败存储。
PUT _cluster/settings
{
"persistent" : {
"data_streams.failure_store.enabled" : [ "my-datastream-*", "logs-*" ]
}
}
- 匹配
my-datastream-*或logs-*的索引会将失败重定向到失败存储,除非显式禁用。
如果在匹配的数据流的 数据流选项 中显式启用或禁用了失败存储,则这些数据流将忽略此配置。
PUT _cluster/settings
{
"persistent" : {
"data_streams.failure_store.enabled" : [ "my-datastream-*", "logs-*" ]
}
}
- 为
my-datastream-*和logs-*启用失败存储
PUT _data_stream/my-datastream-1/_options
{
"failure_store": {
"enabled": false
}
}
- 尽管
my-datastream-1匹配my-datastream-*,但它的失败存储是被禁用的。数据流选项会覆盖集群设置。
失败存储旨在减轻向 Elasticsearch 摄取数据时检测和处理失败的负担。客户端在写入文档时不太可能遇到不可恢复的失败,并且开发人员可以更轻松地对有故障的管道和映射进行故障排除。
有关如何使用失败存储来识别和修复摄取管道及数据中的错误的示例,请参阅 使用失败存储解决摄取问题。
一旦为数据流启用了失败存储,它就会开始重定向因常见摄取问题而失败的文档,而不是在写操作中返回错误。当文档被重定向到失败存储时,客户端会以非侵入式的方式得到通知。
每个数据流的失败存储都由一系列专用于存储失败文档的索引组成。这些失败索引的功能非常类似于数据流的常规后备索引:有一个接受失败文档的写入索引,这些索引可以进行滚动更新,并且会根据生命周期策略随时间自动清理。失败索引在第一次需要存储失败文档时按需创建。
当绑定到数据流的文档在摄取过程中遇到问题时,响应会带有 failure_store 字段的注释,该字段描述了 Elasticsearch 如何响应该问题。在适用的情况下,failure_store 字段会出现在 bulk 和 index API 响应中。客户端可以利用此信息根据 Elasticsearch 的响应来调整其行为。
这里我们有一个发送两个文档的 bulk 操作。两者都写入被映射为 long 字段类型的 id 字段。第一个文档将被接受,但第二个文档将导致失败,因为值 invalid_text 无法被解析为 long。第二个文档将被重定向到失败存储
POST my-datastream-new/_bulk
{"create":{}}
{"@timestamp": "2025-05-01T00:00:00Z", "id": 1234}
{"create":{}}
{"@timestamp": "2025-05-01T00:00:00Z", "id": "invalid_text"}
- 格式正确的文档。
- 无法使用当前映射解析的无效文档。
{
"errors": false,
"took": 400,
"items": [
{
"create": {
"_index": ".ds-my-datastream-new-2025.05.01-000001",
"_id": "YUvQipYB_ZAKuDfZRosB",
"_version": 1,
"result": "created",
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"_seq_no": 3,
"_primary_term": 1,
"status": 201
}
},
{
"create": {
"_index": ".fs-my-datastream-new-2025.05.01-000002",
"_id": "lEu8jZYB_ZAKuDfZNouU",
"_version": 1,
"result": "created",
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"_seq_no": 10,
"_primary_term": 1,
"failure_store": "used",
"status": 201
}
}
]
}
- 响应代码为
200 OK,且响应正文未报告遇到的任何错误。 - 第一个文档被接受并写入数据流的写入索引中。
- 第二个文档在摄取期间遇到问题,并被重定向到数据流的失败存储。
- 响应带有注释字段,指示已使用失败存储来持久化第二个文档。
如果由于某个问题将文档重定向到数据流的失败存储,则响应上的 failure_store 字段将为 used,并且响应将不返回任何错误信息
{
"_index": ".fs-my-datastream-new-2025.05.01-000002",
"_id": "lEu8jZYB_ZAKuDfZNouU",
"_version": 1,
"result": "created",
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"_seq_no": 11,
"_primary_term": 1,
"failure_store": "used"
}
- 此索引操作的文档已发送到失败存储的写入索引。
- 响应带有指示文档已被重定向的标志。
如果本可以将文档重定向到数据流的失败存储,但失败存储被禁用了,则响应上的 failure_store 字段将为 not_enabled,并且响应将正常显示所遇到的错误。
{
"error": {
"root_cause": [
{
"type": "document_parsing_exception",
"reason": "[1:53] failed to parse field [id] of type [long] in document with id 'Y0vQipYB_ZAKuDfZR4sR'. Preview of field's value: 'invalid_text'"
}
],
"type": "document_parsing_exception",
"reason": "[1:53] failed to parse field [id] of type [long] in document with id 'Y0vQipYB_ZAKuDfZR4sR'. Preview of field's value: 'invalid_text'",
"caused_by": {
"type": "illegal_argument_exception",
"reason": "For input string: \"invalid_text\""
},
"failure_store": "not_enabled"
},
"status": 400
}
- 未启用失败存储时,失败会正常返回给客户端。
- 响应带有指示失败存储本可以接受该文档但未启用的标志。
- 由于映射问题,响应状态为
400 Bad Request。
如果文档被重定向到数据流的失败存储,但该失败文档无法存储(例如,由于分片不可用或类似问题),则响应上的 failure_store 字段将为 failed,并且响应将显示原始失败的错误,以及详细说明为什么无法存储该失败的被抑制错误
{
"error": {
"root_cause": [
{
"type": "document_parsing_exception",
"reason": "[1:53] failed to parse field [id] of type [long] in document with id 'Y0vQipYB_ZAKuDfZR4sR'. Preview of field's value: 'invalid_text'",
"suppressed": [
{
"type": "cluster_block_exception",
"reason": "index [.fs-my-datastream-2025.05.01-000002] blocked by: [FORBIDDEN/5/index read-only (api)];"
}
]
}
],
"type": "document_parsing_exception",
"reason": "[1:53] failed to parse field [id] of type [long] in document with id 'Y0vQipYB_ZAKuDfZR4sR'. Preview of field's value: 'invalid_text'",
"caused_by": {
"type": "illegal_argument_exception",
"reason": "For input string: \"invalid_text\""
},
"suppressed": [
{
"type": "cluster_block_exception",
"reason": "index [.fs-my-datastream-2025.05.01-000002] blocked by: [FORBIDDEN/5/index read-only (api)];"
}
],
"failure_store": "failed"
},
"status": 400
}
- 问题的根本原因是映射不匹配。
- 由于不可预见的问题,失败存储此时无法接受写入,因此无法重定向文档。
- 响应中包含完整的异常树。
- 响应带有指示失败存储本会接受该文档但未能接受的标志。
- 由于最初的映射问题,响应状态为
400 Bad Request。
积累了一些失败后,就可以像搜索常规数据流一样搜索失败存储。
在摄取管道失败的情况下重定向到失败存储的文档将以其原始的、未处理的形式存储。如果摄取管道通常会从文档中编辑敏感信息,那么处于原始、未处理形式的失败文档可能会包含敏感信息。
此外,失败文档的结构可能与数据流中的正常数据不同,在使用 文档级安全 或 字段级安全 时应特别小心。任何期望对常规文档和失败文档都使用这些功能的安全性策略,都应考虑两种文档类型之间文档结构的任何差异。
为了限制对潜在敏感数据的可见性,用户需要对数据流拥有 read_failure_store 索引权限,以便搜索该数据流的失败存储数据。
可以通过使用 Elasticsearch 中现有的搜索 API 来搜索数据流的失败存储。
要指示应在失败存储数据上执行搜索,请使用 索引组件选择器语法 来指出搜索操作要针对数据流的哪个部分。在数据流名称后面附加 ::failures 后缀表示该操作应针对该数据流的失败存储而不是其常规后备索引执行。
POST _query?format=txt
{
"query": """FROM my-datastream::failures | DROP error.stack_trace | LIMIT 1"""
}
- 我们在此处删除了
error.stack_trace字段,以使示例中没有换行符。
包含失败文档的搜索结果示例
@timestamp | document.id |document.index |document.routing| error.message |error.pipeline |error.pipeline_trace|error.processor_tag|error.processor_type| error.type
------------------------+--------------------+---------------+----------------+-------------------------------------------------------------------------------------------------------------------------------------+---------------+--------------------+-------------------+--------------------+--------------------------
2025-05-01T12:00:00.000Z|Y0vQipYB_ZAKuDfZR4sR|my-datastream |null |[1:45] failed to parse field [id] of type [long] in document with id 'Y0vQipYB_ZAKuDfZR4sR'. Preview of field's value: 'invalid_text'|null |null |null |null |document_parsing_exception
因为 document.source 字段未映射,所以它不会出现在 ES|QL 结果中。
GET my-datastream::failures/_search
包含失败文档的搜索结果示例
{
"took": 0,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 1,
"hits": [
{
"_index": ".fs-my-datastream-2025.05.01-000002",
"_id": "lEu8jZYB_ZAKuDfZNouU",
"_score": 1,
"_source": {
"@timestamp": "2025-05-01T12:00:00.000Z",
"document": {
"id": "Y0vQipYB_ZAKuDfZR4sR",
"index": "my-datastream",
"source": {
"@timestamp": "2025-05-01T00:00:00Z",
"id": "invalid_text"
}
},
"error": {
"type": "document_parsing_exception",
"message": "[1:53] failed to parse field [id] of type [long] in document with id 'Y0vQipYB_ZAKuDfZR4sR'. Preview of field's value: 'invalid_text'",
"stack_trace": """o.e.i.m.DocumentParsingException: [1:53] failed to parse field [id] of type [long] in document with id 'Y0vQipYB_ZAKuDfZR4sR'. Preview of field's value: 'invalid_text'
at o.e.i.m.FieldMapper.rethrowAsDocumentParsingException(FieldMapper.java:241)
at o.e.i.m.FieldMapper.parse(FieldMapper.java:194)
... 24 more
Caused by: j.l.IllegalArgumentException: For input string: "invalid_text"
at o.e.x.s.AbstractXContentParser.toLong(AbstractXContentParser.java:189)
at o.e.x.s.AbstractXContentParser.longValue(AbstractXContentParser.java:210)
... 31 more
"""
}
}
}
]
}
}
- 该文档属于数据流上的失败存储索引。
- 失败文档的时间戳是失败在 Elasticsearch 中发生的时间。
- 发送的文档被捕获在失败文档中。失败文档捕获了失败时的文档 ID、文档要写入的数据流以及文档的内容。
document.source字段是未映射的,以确保始终捕获失败。 - 失败文档捕获有关所遇错误的信息,例如错误类型、错误消息和压缩的堆栈跟踪。
POST _sql?format=txt
{
"query": """SELECT * FROM "my-datastream::failures" LIMIT 1"""
}
包含失败文档的搜索结果示例
@timestamp | document.id |document.index |document.routing| error.message |error.pipeline |error.pipeline_trace|error.processor_tag|error.processor_type| error.stack_trace | error.type
------------------------+--------------------+---------------+----------------+-------------------------------------------------------------------------------------------------------------------------------------+---------------+--------------------+-------------------+--------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------
2025-05-05T20:49:10.899Z|sXk1opYBL1dfU_1htCAE|my-datastream |null |[1:45] failed to parse field [id] of type [long] in document with id 'sXk1opYBL1dfU_1htCAE'. Preview of field's value: 'invalid_text'|null |null |null |null |o.e.i.m.DocumentParsingException: [1:45] failed to parse field [id] of type [long] in document with id 'sXk1opYBL1dfU_1htCAE'. Preview of field's value: 'invalid_text'
at o.e.i.m.FieldMapper.rethrowAsDocumentParsingException(FieldMapper.java:241)
at o.e.i.m.FieldMapper.parse(FieldMapper.java:194)
... 19 more
Caused by: j.l.IllegalArgumentException: For input string: "invalid_text"
at o.e.x.s.AbstractXContentParser.toLong(AbstractXContentParser.java:189)
at o.e.x.s.AbstractXContentParser.longValue(AbstractXContentParser.java:210)
... 26 more
|document_parsing_exception
因为 document.source 字段未映射,所以它不会出现在 SQL 结果中。
失败文档具有由 Elasticsearch 内部处理的统一结构。
@timestamp- (
date) 文档在 Elasticsearch 中遇到失败的时间戳。 文档 (document)-
(
object) 失败时的文档。如果文档在摄取管道中失败,则该文档将是原始索引请求到达时的未处理版本。如果文档由于映射问题而失败,则该文档将是应用了任何摄取管道之后的状态。document.id- (
keyword) 失败时原始文档的 ID。 document.routing- (
keyword, 可选) 如果指定了路由,则为失败时原始文档的路由。 document.index- (
keyword) 失败时文档正在写入的索引。 document.source- (未映射对象) 原始文档的正文。此字段未映射,且仅存在于失败文档的 source 中。这可以防止在重定向失败文档时失败存储中出现映射冲突。如果您需要在查询中包含来自原始文档 source 的字段,请在搜索请求上使用 运行时字段。
error-
(
object) 有关阻止该文档被索引的失败信息。error.message- (
match_only_text) 描述失败的错误消息。 error.stack_trace- (
text) Elasticsearch 针对该失败提供的压缩堆栈跟踪。 error.type- (
keyword) 失败的类型分类。值与失败的索引 API 响应中返回的类型相同。 error.pipeline- (
keyword, 可选) 如果失败发生在摄取管道中,此字段将包含管道的名称。 error.pipeline_trace- (
keyword, 可选数组) 如果失败发生在摄取管道中,此字段将包含文档在失败之前访问过的管道列表。 error.processor_tag- (
keyword, 可选) 如果失败发生在带有标签注释的摄取处理器中,标签内容将显示在此处。 error.processor_type- (
keyword, 可选) 如果失败发生在摄取处理器中,此字段将包含处理器类型。(例如script、append、enrich等)
失败项的 document 字段的内容取决于失败在摄取过程中发生的时间。向数据流发送数据时,文档可能会在两个不同的阶段失败:在摄取管道期间以及在索引期间。
- 在摄取管道期间失败的文档将存储最初发送给 Elasticsearch 时的文档 source。在重定向失败之前,来自管道的更改将被丢弃。
- 在索引期间失败的文档将存储索引操作期间的文档 source。来自管道的任何更改都将反映在被重定向的文档 source 中。
为了帮助演示这些失败类型之间的差异,我们将使用以下管道和模板定义。
PUT _ingest/pipeline/my-datastream-example-pipeline
{
"processors": [
{
"set": {
"override": false,
"field": "@timestamp",
"copy_from": "_ingest.timestamp"
}
},
{
"set": {
"field": "published",
"copy_from": "data"
}
}
]
}
- 我们使用此处理器在文档缺少
@timestamp时为其添加一个。 - 一个简单的处理器,将
data字段复制到published字段。
PUT _index_template/my-datastream-example-template
{
"index_patterns": ["my-datastream-ingest*"],
"data_stream": {},
"template": {
"settings": {
"index.default_pipeline": "my-datastream-example-pipeline" // Calling the pipeline by default.
},
"mappings": {
"properties": {
"published": { // A field of type long to hold our result.
"type": "long"
}
}
},
"data_stream_options": {
"failure_store": {
"enabled": true // Failure store is enabled.
}
}
}
}
- 默认调用该管道。
- 一个类型为 long 的字段,用于保存我们的结果。
- 已启用失败存储。
在摄取过程中,文档首先由所有适用的摄取管道进行处理。此过程会修改文档的副本,并且仅在所有管道完成后才将更改保存到原始文档中。如果由于摄取管道期间发生失败而将文档发送到失败存储,则在重定向失败之前,将丢弃管道对文档所做的任何更改。这意味着文档将处于客户端最初发送时的状态。这样做的好处是能够看到未运行任何管道之前的文档,并允许在模拟操作中使用原始文档,以进一步对摄取管道中的任何问题进行故障排除。
使用上面定义的管道和模板,我们将发送一个缺少管道所需字段的文档。该文档将失败
POST my-datastream-ingest/_doc
{
"random": 42 // Not the field we're looking for.
}
- 不是我们要找的字段。
{
"_index": ".fs-my-datastream-ingest-2025.05.09-000002",
"_id": "eXS-tpYBwrYNjPmat9Cx",
"_version": 1,
"result": "created",
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1,
"failure_store": "used"
}
- 文档失败并进入了失败存储。
检查对应的失败文档将显示发送给 Elasticsearch 时其原始形式的文档。
GET my-datastream-ingest::failures/_search
{
"took": 0,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 1,
"hits": [
{
"_index": ".fs-my-datastream-ingest-2025.05.09-000002",
"_id": "eXS-tpYBwrYNjPmat9Cx",
"_score": 1,
"_source": {
"@timestamp": "2025-05-09T20:31:13.759Z",
"document": {
"index": "my-datastream-ingest",
"source": {
"random": 42
}
},
"error": {
"type": "illegal_argument_exception",
"message": "field [data] not present as part of path [data]",
"stack_trace": """j.l.IllegalArgumentException: field [data] not present as part of path [data]
at o.e.i.IngestDocument.getFieldValue(IngestDocument.java:202)
at o.e.i.c.SetProcessor.execute(SetProcessor.java:86)
... 14 more
""",
"pipeline_trace": [
"my-datastream-example-pipeline"
],
"pipeline": "my-datastream-example-pipeline",
"processor_type": "set"
}
}
}
]
}
}
document字段显示该文档的状态是在任何管道执行之前的。- 管道在应该添加时间戳之后失败了。
我们可以看到文档在管道中的第二个处理器上失败了。第一个处理器本会添加一个 @timestamp 字段。由于管道失败了,我们发现它没有添加任何 @timestamp 字段,因为它没有保存管道失败之前的任何更改。
可能发生失败的第二个时间是在索引期间。在文档由任何适用的管道处理后,在将它们索引到分片之前,会使用索引映射对其进行解析。如果由于此过程中的失败而将文档发送到失败存储,则它将以发生任何摄取之后的状态进行存储。这是因为在此阶段,原始文档已经被摄取管道的更改所覆盖。这样做的好处是允许您查看文档在写入操作的映射和索引阶段时的外观。
在上述示例的基础上,我们发送一个文档,其本应为数值的地方却包含文本值
POST my-datastream-ingest/_doc
{
"data": "this field is invalid"
}
- 上面的映射期望该字段是一个数值。
{
"_index": ".fs-my-datastream-ingest-2025.05.09-000002",
"_id": "sXTVtpYBwrYNjPmaFNAY",
"_version": 1,
"result": "created",
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1,
"failure_store": "used"
}
- 文档失败并被发送到失败存储。
如果我们获取对应的失败文档,我们可以看到存储的文档已应用了默认管道。
GET my-datastream-ingest::failures/_search
{
"took": 0,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 1,
"hits": [
{
"_index": ".fs-my-datastream-ingest-2025.05.09-000002",
"_id": "sXTVtpYBwrYNjPmaFNAY",
"_score": 1,
"_source": {
"@timestamp": "2025-05-09T20:55:38.943Z",
"document": {
"id": "sHTVtpYBwrYNjPmaEdB5",
"index": "my-datastream-ingest",
"source": {
"@timestamp": "2025-05-09T20:55:38.362486755Z",
"data": "this field is invalid",
"published": "this field is invalid"
}
},
"error": {
"type": "document_parsing_exception",
"message": "[1:91] failed to parse field [published] of type [long] in document with id 'sHTVtpYBwrYNjPmaEdB5'. Preview of field's value: 'this field is invalid'",
"stack_trace": """o.e.i.m.DocumentParsingException: [1:91] failed to parse field [published] of type [long] in document with id 'sHTVtpYBwrYNjPmaEdB5'. Preview of field's value: 'this field is invalid'
at o.e.i.m.FieldMapper.rethrowAsDocumentParsingException(FieldMapper.java:241)
at o.e.i.m.FieldMapper.parse(FieldMapper.java:194)
... 24 more
Caused by: j.l.IllegalArgumentException: For input string: "this field is invalid"
at o.e.x.s.AbstractXContentParser.toLong(AbstractXContentParser.java:189)
at o.e.x.s.AbstractXContentParser.longValue(AbstractXContentParser.java:210)
... 31 more
"""
}
}
}
]
}
}
document字段反映了摄取管道运行之后的文档。- 由于映射不匹配,文档索引失败。
document 字段尝试显示导致失败发生的任何过程的有效输入。这为您提供了重现问题所需的所有信息。
失败数据随着时间的推移可能会在数据流中积聚。为了帮助管理这种积聚,可以对数据流执行的大多数管理操作也可以应用于数据流的失败存储。
数据流对待其失败存储的方式很像一组辅助的 后备索引。多个专用的隐藏索引为失败存储的搜索请求提供服务,而一个索引充当当前的写入索引。您可以使用 rollover API 来滚动更新失败存储。就像数据流中的常规索引一样,将在失败存储中创建一个新的写入索引来接受新的失败文档。
POST my-datastream::failures/_rollover
{
"acknowledged": true,
"shards_acknowledged": true,
"old_index": ".fs-my-datastream-2025.05.01-000002",
"new_index": ".fs-my-datastream-2025.05.01-000003",
"rolled_over": true,
"dry_run": false,
"lazy": false,
"conditions": {}
}
失败存储的保留期使用内部 数据流生命周期 进行管理。失败存储数据适用三十天 (30d) 的保留期。您可以通过调用 get data stream API 来查看失败存储索引的活动生命周期
GET _data_stream/my-datastream
{
"data_streams": [
{
"name": "my-datastream",
"timestamp_field": {
"name": "@timestamp"
},
"indices": [
{
"index_name": ".ds-my-datastream-2025.05.01-000001",
"index_uuid": "jUbUNf-8Re-Nca8vJkHnkA",
"managed_by": "Data stream lifecycle",
"prefer_ilm": true,
"index_mode": "standard"
}
],
"generation": 2,
"status": "GREEN",
"template": "my-datastream-template",
"lifecycle": {
"enabled": true
},
"next_generation_managed_by": "Data stream lifecycle",
"prefer_ilm": true,
"hidden": false,
"system": false,
"allow_custom_routing": false,
"replicated": false,
"rollover_on_write": false,
"index_mode": "standard",
"failure_store": {
"enabled": true,
"rollover_on_write": false,
"indices": [
{
"index_name": ".fs-my-datastream-2025.05.05-000002",
"index_uuid": "oYS2WsjkSKmdazWuS4RP9Q",
"managed_by": "Data stream lifecycle"
}
],
"lifecycle": {
"enabled": true,
"effective_retention": "30d", <3>
"retention_determined_by": "default_failures_retention"
}
}
}
]
}
- 有关失败存储的信息显示在响应的独立字段中。
- 默认情况下,索引由数据流生命周期进行管理。
- 默认存在三十天 (30d) 的有效保留期。
- 当前保留期由默认值决定。
默认保留期遵循任何最大保留值。如果配置的 最大保留期 低于三十天,则将使用最大保留期作为默认值。
您可以通过更新 data_streams.lifecycle.retention.failures_default 集群设置来更新部署中失败存储的默认保留期。其失败存储未配置保留期的新数据流和现有数据流将使用此值来确定其保留期。
PUT _cluster/settings
{
"persistent": {
"data_streams.lifecycle.retention.failures_default": "15d"
}
}
您还可以在数据流的选项上指定数据流的失败存储保留期。这些可以通过新数据流的索引模板指定,或者通过用于现有数据流的 put data stream options API 指定。
PUT _data_stream/my-datastream/_options
{
"failure_store": {
"enabled": true,
"lifecycle": {
"data_retention": "10d"
}
}
}
- 确保失败存储保持启用状态。
- 仅将此数据流的失败存储保留期设置为十天。
失败存储支持使用 modify data stream API 从中添加和移除索引。
POST _data_stream/_modify
{
"actions":[
{
"remove_backing_index": {
"data_stream": "my-datastream",
"index": ".fs-my-datastream-2025.05.05-000002",
"failure_store": true
}
},
{
"add_backing_index": {
"data_stream": "my-datastream",
"index": "restored-failure-index",
"failure_store": true
}
}
]
}
- 移除后备索引的操作。
- 应移除的自动生成的失败存储索引的名称。
- 将
failure_store设置为 true,以使 modify API 目标操作数据流的失败存储。 - 添加后备索引的操作。
- 应添加到失败存储的索引名称。
- 将
failure_store设置为 true,以使 modify API 目标操作数据流的失败存储。
此 API 让您能够对失败存储中的索引进行细粒度控制,允许您管理备份和恢复操作以及隔离失败数据以便以后进行修复。
仅从 Elasticsearch 9.4 开始才支持使用 ::failures 跨集群访问失败存储。