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

41

我对ES还比较新。我一直在寻找一个数据库迁移工具,但一直找不到。我想知道是否有人能够帮我指明方向。

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

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

有没有任何框架/脚本或方法可以与ES一起使用来实现类似的功能?

有没有人有手动使用脚本并运行迁移脚本或至少升级脚本的经验。

提前致谢!

1个回答

54
从这个角度/需求来看,ES有很大的局限性:
- 尽管具有动态映射,但ES并非无模式而是模式密集型。如果映射的更改与现有文档冲突(实际上,如果任何文档具有新映射影响的非空字段,将导致异常),则无法更改映射。 - ES中的文档是不可变的:一旦索引了一个文档,只能检索/删除。围绕此的语法糖是部分更新,它在ES端实现了线程安全的删除+索引(使用相同的ID)。
在你的问题背景下,这意味着什么呢?基本上,你无法为ES使用传统的迁移工具。以下是可以让你在ES上工作更轻松的方法:
- 使用严格的映射("dynamic": "strict"和/或index.mapper.dynamic: false,请参考映射文档)。这将保护你的索引/类型免受意外动态映射错误类型的影响。
  • 如果您在数据映射关系中遗漏了一些错误,您将得到明确的错误提示

  • 您可以获取实际的ES映射并将其与您的数据模型进行比较。如果您的编程语言有足够高级的ES库,这将非常容易

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


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

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

每次部署代码时,你需要:

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

所有这些实际上意味着你可以继续使用你拥有的映射/数据,就像往常一样处理数据。

  1. 如果ES关于新映射提供了异常,你需要:
  • 创建带有新映射的新索引/类型(命名为name_{revision}_{date}
  • 将别名重定向到新索引
  • 启动迁移代码,通过bulk请求进行快速重新索引 在重新索引期间,您可以通过别名正常地安全地索引新文档。缺点是在重新索引期间,历史数据部分可用。

这是经过生产测试的解决方案。关于这种方法的注意事项:

  • 如果您的读取请求需要一致的历史数据,则无法执行此操作
  • 您需要重新索引整个索引。如果每个索引有1个类型(可行的解决方案),那就没问题。但有时您需要多类型索引
  • 数据网络往返。有时可能会很痛苦

总结一下:
- 在你的模型中尽量保持良好的抽象,这总是有帮助的。 - 尽量保持历史数据/字段的陈旧。在编写代码时要有这个想法,这比起初听起来要容易些。 - 我强烈建议避免依赖于利用ES实验工具的迁移工具。这些工具随时可能发生变化,就像"river-*"工具一样。

有没有自动化这个过程的工具? - kaeff
就我所知,目前我不知道有任何清晰的方法可以在“自动”模式下无缝迁移ES中的数据。但是如果您的数据是不稳定的,请考虑以下两点:1- 好的RDBMS并没有看起来那么糟糕;2- 将ES中的索引切分为更小的索引(如按月、按日、按用户等),以便于迁移/快速切换别名到新的/活跃的数据。 - Slam
需要补充的一点是,在撰写本文时还没有 reindex API。对于不需要复杂应用程序端转换的迁移,ES 端的重新索引速度非常快。 - Slam
在此添加一条对这个有用回答的链接:https://dev59.com/dVcQ5IYBdhLWcg3wEPsK#43374464 - Archit Saxena

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接