Elasticsearch 的 Liquibase 或 Flyway 数据库迁移替代方案

我对ES很陌生。我一直在尝试搜索数据库迁移工具很长时间,但我找不到一个。我想知道是否有人可以帮助我指出正确的方向。

我将使用Elasticsearch作为我项目中的主要数据存储。我想对所有映射和配置更改/数据导入/数据升级脚本进行版本控制,我在项目中开发新模块时运行这些脚本。

过去,我使用像Flyway或Liquibase这样的数据库版本控制工具。

是否有任何框架/脚本或方法可以与ES一起使用来实现类似的东西?

是否有人有任何使用脚本手动执行此操作的经验,并至少运行迁移脚本升级脚本。

提前致谢!


答案 1

从这个角度来看/需求,ES有一个巨大的局限性:

  • 尽管具有动态映射,但ES不是无模式的,而是模式密集型的。如果此更改与现有文档冲突,则无法更改映射(实际上,如果任何文档具有新映射影响的非空字段,这将导致异常)
  • ES 中的文档是不可变的:一旦您索引了一个文档,您只能检索/删除。围绕这一点的语法糖是部分更新,这使得线程安全的删除+索引(具有相同的id)在ES端

在你的问题中,这意味着什么?基本上,您不能拥有适用于ES的经典迁移工具。以下是可以简化ES工作的方法:

  • 使用严格映射(和/或 ,请查看映射文档)。这将保护您的索引/类型"dynamic": "strict"index.mapper.dynamic: false

  • 意外地使用错误的类型动态映射

  • 在数据映射关系中遗漏某些错误时获得显式错误

  • 您可以获取实际的ES映射并将其与数据模型进行比较。如果您的PL具有足够高的ES级别库,那么这应该很容易

  • 您可以利用索引别名进行迁移


所以,一点点经验。对我来说,目前合理的流程是这样的:

  • 所有数据结构在代码中描述为模型。这个模型实际上也提供了ORM抽象。
  • 索引/映射创建调用是简单模型的方法。
  • 每个索引都有别名(即 ),它指向实际索引(即 )。newsnews_index_{revision}_{date_created}

每次部署代码时,您

  1. 尝试放置模型(类型)映射。如果它没有错误,这意味着你已经
  • 放置相同的映射
  • 放置映射是旧字段的纯超集(仅提供新字段,旧字段保持不变)
  • 没有文档在受新映射影响的字段中具有值

所有这些实际上意味着你很高兴使用你拥有的映射/数据,只是像往常一样使用数据。

  1. 如果 ES 提供了有关新映射的异常,则
  • 使用新映射创建新索引/类型(命名为 likename_{revision}_{date}
  • 将别名重定向到新索引
  • 启动发出快速重新索引的批量请求的迁移代码 在此重新编制索引期间,您可以通过别名正常安全地为新文档编制索引。缺点是历史数据在重新编制索引期间部分可用。

这是经过生产测试的解决方案。关于这种方法的警告:

  • 如果您的读取请求需要一致的历史数据,则无法执行此操作
  • 您需要对整个索引重新编制索引。如果每个索引有1种类型(可行的解决方案),那么它很好。但有时您需要多类型索引
  • 数据网络往返。有时可能是疼痛

总结一下:

  • 尝试在模型中具有良好的抽象性,这总是有帮助的
  • 尝试使历史数据/字段保持陈旧状态。只需在构建代码时牢记这个想法,这比一开始听起来更容易
  • 我强烈建议避免依赖利用 ES 实验工具的迁移工具。这些可以随时更改,就像工具一样。river-*

答案 2

推荐