Docker 1.12:多副本,单数据库

Posted

技术标签:

【中文标题】Docker 1.12:多副本,单数据库【英文标题】:Docker 1.12: Multiple replicas, single database 【发布时间】:2017-01-04 21:49:43 【问题描述】:

随着 Docker 1.12 引入新的“swarm 模式”,我们一直在尝试将我们的应用程序迁移到容器上并利用 swarm 模式的编排和集群。

我们的应用程序需要运行一些初始数据库脚本才能启动。 我们没有将数据库打包到我们的 dockerized 应用程序中,以便它可以遵循无状态微服务架构,并且多个容器最终将与单个(目前)数据库实例进行通信。

在创建服务时,我们不能将--replicascreate service 命令一起使用,因为多个实例会尝试在单个数据库上创建表并失败。虽然我们的脚本会检查数据库是否已设置并跳过创建,但由于所有容器同时启动,因此无法使用。

我们找不到任何 等待 类型的机制,我们可以利用 docker 来解决这个问题。如果我们只能在第一个容器创建数据库(并公开端口)时启动第二个容器,那会很好,但是我们如何为此配置容器间通信呢?

或者,flywaydb 之类的工具可以在某些方面提供帮助吗?

这应该如何在生产中使用?

【问题讨论】:

您能否更改您的数据库设置以创建设置等待的写入锁或写入锁样式“正在创建”状态?然后只有第一个容器进行设置,其他容器等待。或者,您可以将数据库设置与启动分开 如果我理解你的话,你想让数据库服务的副本都连接到同一个数据存储吗?如果是这种情况,那真的是不可取的,特别是如果所有副本都可以写入公共存储。像 Postgres 这样的数据库有各种基于主/从设置的选项 (postgresql.org/docs/9.2/static/high-availability.html)。如果您对防止节点故障更感兴趣,则可以在每个节点上使用一个卷指定仅 1 个数据库任务,该卷安装相同的外部数据存储)。如果 db/node 死亡 swarm 将在其他地方重新创建它。 【参考方案1】:

来自Flyway FAQ:

多个节点可以并行迁移吗? 是的! Flyway 使用数据库的锁定技术来协调多个节点。这确保即使您的应用程序的多个实例尝试同时迁移数据库,它仍然可以工作。完全支持集群配置。

【讨论】:

我不完全确定这是否有效。我创建了一个简单的多线程程序并仅使用 flyway.migrate() 运行了一个 V1__initial.sql,但它仍然失败并出现“表已存在”错误。你能给我一些指导吗?谢谢。 是的,这按预期工作。使用 flyway 迁移脚本运行 4 个任务的 ECS 服务运行良好。【参考方案2】:

没有简单的方法可以在容器之间进行协调。它基本上需要一个分布式锁解决方案。第一个拿到锁的容器可以创建db,其他没有拿到锁的容器需要等待。

在 AWS 中,您可以利用 DynamoDB。 DynamoDB 支持条件更新。容器首先尝试使用“attribute_not_exists(yourKey)”在 DynamoDB 中创建锁定密钥。第一个创建将成功,其他创建将被拒绝。第一个容器需要在 DynamoDB 中创建另一个键以指示数据库已准备就绪。其他容器只是等到创建就绪键。

或者您可以在您的服务部署脚本中执行此操作。该脚本可以创建具有 1 个副本的服务。然后继续检查是否创建了 db。如果是,则扩展服务,例如docker service update yourservicce --replicas 5

【讨论】:

以上是关于Docker 1.12:多副本,单数据库的主要内容,如果未能解决你的问题,请参考以下文章

Docker Swarm 使用NFS 搭建 S3 (minio)多副本

Docker 1.12 集群

docker version 1.12+ swarm 集群

设计理念复制

Docker - Upgrade from 1.12 to 1.13

docker 1.12 版本 的新特性