【问题标题】:How to avoid timing problems when running db:migrate on multiple nodes?在多个节点上运行 db:migrate 时如何避免时序问题?
【发布时间】:2015-03-14 04:53:27
【问题描述】:

我目前正在第一次学习如何使用 Capistrano 部署 Rails 应用程序。我看到 capistrano/rails 的默认流程包括在“发布”新符号链接之前在主机上运行 db:migrate。但是,当同时在多个 Web 节点上运行部署时,我会遇到一些时间问题。

  1. 如果您在旧版本的应用程序仍在运行时迁移数据库,则旧代码会与更改的数据库通信,这可能会导致未定义的行为。
  2. 如果您在运行迁移之前关闭应用,但每个节点上的部署速度不同,则一个节点可能仍在运行旧应用,而另一个节点已经在运行迁移。
  3. 如果两个节点同时调用 db:migrate,您会不会因为它们都认为新的迁移尚未运行(通过查阅表格)而陷入竞争状态,然后两者都尝试同时运行迁移?

在我看来,唯一合理的解决方案是尝试将默认流程重新设计为以下三个阶段:

  1. 每个节点上的正常部署流程直到但不包括 db:migrate 任务——所以现在安装了新版本,运行了捆绑程序,编译了资产,建立了链接,一切准备就绪(但尚未通过当前符号链接发布)。最后的附加步骤:停止旧应用。
  2. 在所有主机完成第 1 阶段后,然后仅在一个节点上运行 db:migrate(可能是随机选择的,或者只是列表中的第一个)。
  3. 完成后,在所有主机上恢复正常流程的后半部分,并在 deploy:published 任务之后添加一个用于再次启动应用程序的任务。

我现在对自己的推理有点缺乏信心,因为虽然我搜索了文档并在谷歌上搜索了帖子,但我还没有真正看到任何人谈论这些多节点问题,即使我不得不假设它影响了几乎所有人......

【问题讨论】:

    标签: ruby-on-rails deployment capistrano database-migration rails-migrations


    【解决方案1】:

    您不会在多个节点上运行 rake db:migrate。您仅在 1 个节点上运行它。请记住,db migrate 迁移数据库,该数据库由应用程序中的所有节点共享,因此在不同节点上同时运行它绝对是一个坏主意。

    我将我的数据库迁移与我的数据迁移分开以获得更快的部署,然后我执行两种不同类型的部署: 1) 数据库迁移和整个应用程序的一些停机时间 2)没有数据库迁移,并且没有停机时间(新的dynos在旧的dynos运行时旋转,在他们启动路由器后将新的流量切换到新的dynos,然后关闭旧的dynos)

    (当然我是在 Heroku 的上下文中做的,这是不同但相同的基本思想)

    还请记住,在运行 db:migrate 之后重新启动所有节点是绝对必要的,因此您的 capistration 脚本应该考虑到这一点。

    【讨论】:

    • 感谢 IRC 的一些帮助并深入研究源代码,我发现 deploy:migrate 任务仅在主机组的主节点上运行,其角色由 :migration_role 定义。因此,还有用于处理该问题的内置支持。我只需要在所有 Web 节点上停止/启动应用程序之前和之后添加任务,我想我会没事的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-21
    • 1970-01-01
    • 2012-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多