Django迁移部署策略与AWS ECS Fargate?

huangapple go评论48阅读模式
英文:

Django migrations deployment strategy with AWS ECS Fargate?

问题

在使用ECS Fargate运行数据库迁移时,建议的部署策略是什么?

可以更新容器命令以在启动gunicorn服务器之前运行迁移。但如果有多个实例正在提供服务,这可能导致并发迁移同时执行。

还需要考虑到已经在运行的镜像。如果我找到了在新镜像上线之前运行迁移的方法,我还必须考虑旧镜像仍在运行旧代码,可能会导致错误或引发奇怪的数据损坏副作用。

我考虑创建一个新的ECS::TaskDefinition。让它运行一个一次性的迁移脚本来执行迁移。然后容器关闭。然后,我会更新所有其他TaskDefinitions,使它们具有依赖关系以等待它完成后再启动。

英文:

What is the recommended deployment strategy for running database migrations with ECS Fargate?

I could update the container command to run migrations before starting the gunicorn server. But this can result in concurrent migrations executing at the same time if more than one instance is provisioned.

I also have to consider the fact that images are already running. If I figure out how to run migrations before the new images are up and running, I have to consider the fact that the old images are still running on old code and may potentially break or cause strange data-corruption side effects.

I was thinking of creating a new ECS::TaskDefinition. Have that run a one-off migration script that runs the migrations. Then the container closes. And I update all of the other TaskDefinitions to have a DependsOn for it, so that they wont start until it finishes.

答案1

得分: 4

  • I could update the container command to run migrations before starting the gunicorn server. But this can result in concurrent migrations executing at the same time if more than one instance is provisioned.

    • 我可以更新容器命令,在启动gunicorn服务器之前运行迁移。但如果提供了多个实例,这可能导致并发迁移同时执行。
  • That is one possible solution. To avoid the concurrency issue you would have to add some sort of distributed locking in your container script to grab a lock from DynamoDB or something before running migrations. I've seen it done this way.

    • 这是一个可能的解决方案。为了避免并发问题,您需要在容器脚本中添加某种分布式锁,以在运行迁移之前从DynamoDB或其他地方获取锁。我曾经看到过这样做。
  • Another option I would propose is running your Django migrations from an AWS CodeBuild task. You could either trigger it manually before deployments, or automatically before a deployment as part of a larger CI/CD deployment pipeline. That way you would at least not have to worry about more than one running at a time.

    • 我提议的另一个选项是从AWS CodeBuild任务中运行Django迁移。您可以在部署之前手动触发它,或者作为更大的CI/CD部署流水线的一部分在部署之前自动运行。这样,您至少不必担心同时运行多个迁移。
  • I also have to consider the fact that images are already running. If I figure out how to run migrations before the new images are up and running, I have to consider the fact that the old images are still running on old code and may potentially break or cause strange data-corruption side effects.

    • 我还必须考虑到图像已经在运行的事实。如果我找到了在新图像启动之前运行迁移的方法,我还必须考虑旧图像仍在旧代码上运行的事实,可能会导致破裂或引发奇怪的数据损坏副作用。
  • That's a problem with every database migration in every system that has ever been created. If you are very worried about it you would have to do blue-green deployments with separate databases to avoid this issue. Or you could just accept some downtime during deployments by configuring ECS to stop all old tasks before starting new ones.

    • 这是每个已创建系统中每个数据库迁移的问题。如果您非常担心这个问题,您可能需要执行使用单独数据库的蓝绿部署以避免此问题。或者您可以在部署期间接受一些停机时间,通过配置ECS在启动新任务之前停止所有旧任务。
  • I was thinking of creating a new ECS::TaskDefinition. Have that run a one-off migration script that runs the migrations. Then the container closes. And I update all of the other TaskDefinitions to have a DependsOn for it, so that they won't start until it finishes.

    • 我考虑创建一个新的ECS::TaskDefinition。让它运行一个一次性迁移脚本来运行迁移。然后容器关闭。然后我会更新所有其他TaskDefinitions,让它们都具有一个DependsOn,以便在它完成之前它们不会启动。
英文:

> I could update the container command to run migrations before starting the gunicorn server. But this can result in concurrent migrations executing at the same time if more than one instance is provisioned.

That is one possible solution. To avoid the concurrency issue you would have to add some sort of distributed locking in your container script to grab a lock from DynamoDB or something before running migrations. I've seen it done this way.

Another option I would propose is running your Django migrations from an AWS CodeBuild task. You could either trigger it manually before deployments, or automatically before a deployment as part of a larger CI/CD deployment pipeline. That way you would at least not have to worry about more than one running at a time.

> I also have to consider the fact that images are already running. If I figure out how to run migrations before the new images are up and running, I have to consider the fact that the old images are still running on old code and may potentially break or cause strange data-corruption side effects.

That's a problem with every database migration in every system that has ever been created. If you are very worried about it you would have to do blue-green deployments with separate databases to avoid this issue. Or you could just accept some down-time during deployments by configuring ECS to stop all old tasks before starting new ones.

> I was thinking of creating a new ECS::TaskDefinition. Have that run a one-off migration script that runs the migrations. Then the container closes. And I update all of the other TaskDefinitions to have a DependsOn for it, so that they wont start until it finishes.

This is a good idea, but I'm not aware of any way to set DependsOn for separate tasks. The only DependsOn setting I'm aware of in ECS is for multiple containers in a single task.

huangapple
  • 本文由 发表于 2023年2月10日 12:00:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/75406805.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定