使用带有 Java 17 的 elasticsearch 8.4.3 和一个由 3 个节点组成的集群,其中 3 个节点符合主节点条件,我们从以下情况开始:
然后我们开始一项创建新索引 products-2023-01-12-1520 的作业,最后在客户端使用 elastic-rest-client 和 alias API,我们进行以下调用:
于 2023-01-12 16:27:26,893:
POST /_aliases
{"actions":[
{
"remove": {
"alias":"current-products",
"index":"products-*"
}
},
{
"add":{
"alias":"current-products",
"index":"products-2023-01-12-1520"}
}
]}
我们在 26 毫秒后收到以下响应,HTTP 响应代码为 200:
{"acknowledged":true}
但是看看我们最终得到的结果,我们仍然有带有 current-products 别名的旧索引。
我不明白为什么会发生这种情况,而且这种情况并不是 100% 都会发生(大约 10 次索引中发生了 2 次)。 这是一个已知的错误吗?还是常规行为?
编辑@warkolm:
截至目前索引之前的 GET /_cat/aliases?v:
alias index filter routing.index routing.search is_write_index
current-products products-2023-01-13-1510 - - - -
您更新别名的方式似乎可能存在问题。当您使用“删除”和“添加”操作对 _aliases 端点执行 POST 请求时,Elasticsearch 将根据执行请求时索引的当前状态更新别名。
但是,可能有其他进程或操作同时修改索引或别名,这可能会导致冲突或不一致。此外,当您在“删除”操作的“索引”字段中使用通配符 (*) 时,它将从与模式匹配的所有索引中删除别名,这可能不是预期的行为。
为了避免此问题,您可以尝试使用索引别名 API 而不是 _aliases 端点。此 API 允许您对别名执行原子更新,这意味着仅当所有操作成功时才会更新别名,如果任何操作失败则将回滚。此外,您可以显式指定要从中删除别名的索引,而不是使用通配符。
以下是如何使用指数别名 API 更新别名的示例:
POST /_aliases
{
"actions": [
{ "remove": { "index": "products-2023-01-12-0900", "alias": "current-products" } },
{ "add": { "index": "products-2023-01-12-1520", "alias": "current-products" } }
]
}
这样,别名只会从特定索引“products-2023-01-12-0900”中删除,并添加到特定索引“products-2023-01-12-1520”中。这有助于避免同时修改索引或别名的其他进程或操作可能导致的任何冲突或不一致。
此外,建议使用等于或高于 8.4.3 的 Elasticsearch 版本,因为它修复了许多错误,这些错误可能是导致您遇到问题的原因。
总之,您遇到的问题可能不是已知错误,但如果多个进程同时修改索引或别名,并使用索引别名 API 并指定确切的索引来删除或添加索引,则这是一种常规行为别名可以帮助避免这个问题。
我正在寻找这个主题,并发现我有一个重大的记忆缺陷。
所以,上下文..我有一个每 5 分钟运行一次的 Logstash 管道,我根据相同的索引更新多个别名,并在每个别名上使用特定的过滤器。
每当我由于业务组织变化而必须更改过滤器时,我都会通过
POST _aliases
进行更改,但奇怪的是,这些更改在一段时间后没有得到维护。
我在 interwebz 上搜索了“别名更新到以前版本的别名 - elasticsearch”,发现了这个超级相似的案例!
然后我想起了我的背景:P
不知道这是否可能是任何人的情况,但我发现将其放在此处很重要,以防其他人可能忘记该重要配置。