Uber 的 Docker Mysql 应用

背景介绍

Uber的MySQL集群规模很大,超过1000个集群,共有4000多个数据库服务器。

问题

起初是使用Puppet管理,写了很多脚本,再加上一些人工操作,在集群数量比较小时,这个管理方法比较实用,但现在这个规范已经完全不适用了,所以需要其他的管理方案。

对于MySQL集群的管理,有几点基本的需求:

  • 可以在每个主机上运行多个数据库
  • 全自动化
  • 有一个统一入口来管理所有数据中心中的所有集群

解决方案

最后决定基于Docker设计一套解决方案,命名为 Schemadock

在Docker容器中运行MySQL,形成一个一个的节点,这些节点如何构成集群拓扑结构,由配置文件来定义。

例如有一个集群 Cluster A,配置文件中便会对其进行说明,指定包含了几个数据库,是哪几个,哪个是 master。

节点有了,拓扑结构说明书也有了,谁来按照说明把集群构建起来呢?由另一个重要角色 agents 代理 来完成。

Schemadock 中还有一个中心化的服务,进行整体的维护和监控,检查各个实例的状态和偏差。

为什么选用Docker

通过容器化的方式,使得在一台主机上运行多个数据库非常容易,可以是不同版本不同配置的,甚至一台主机上可以运行一个小型集群,这样就节省了很多主机资源。

因为MySQL是运行在容器中,容器运行在主机中,对于主机来讲,他们的功能统一了,就是运行容器,所以主机的角色一致了,可以移除Puppet中的依赖关系了。

Docker非常便于测试,在测试环境中就可以执行起集群搭建步骤,实验所有的操作流程。

Docker虽好,但Uber也给出了一点建议:

在规模不够大时,不要轻易使用Docker,因为使用Docker之后,你需要处理更多的事情,例如 镜像的构建管理、容器的监控、Docker升级、日志处理、网络规划 ……,所以,规模较小时,使用 PuppetAnsible 这类的工具就够用了,例如Uber的情况,MySQL集群数量在16个以下时,用 Puppet 管理就比较轻松。

无状态的MySQL镜像

MySQL镜像被设计为完全无状态的,构建镜像时,不会包含任何逻辑,比如复制逻辑、状态检查等,创建出来的容器就是无状态的,容器的具体角色是通过环境变量来指定,使容器与逻辑分离。

数据也不在容器中,是挂载在主机目录下的。

这样,容器是非常独立的,这会带来很多好处,例如:

  • 某个容器出现问题后,不再复用,直接删掉,用同样的参数创建一个新的容器。
  • 升级MySQL非常简单,使用新版本的镜像创建容器,替代老版本容器。
  • 配置的变化很容易控制。

容器编排和拓扑配置

MySQL镜像需要被启动为容器,指定容器的角色,并放置到复制拓扑结构中的正确位置。

这些工作由 agents 来完成,每台主机中都会运行一个 agent,接收目标说明信息,根据说明来创建和配置容器。

说明信息示例:

“schemadock01-mezzanine-mezzanine-us1-cluster8-db4”: {

   “app_id”: “mezzanine-mezzanine-us1-cluster8-db4”,

   “state”: “started”,

   “data”: {

     “semi_sync_repl_enabled”: false,

     “name”: “mezzanine-us1-cluster8-db4”,

     “master_host”: “schemadock30”,

     “master_port”: 7335,

     “disabled”: false,

     “role”: “minion”,

     “port”: 7335,

     “size”: “all”

 }

}

含义是主机schemadock01上会运行一个Mezzanine数据库,角色是从服务器,端口为7335,可以占用主机所有资源,其master是schemadock30:7335

agents 是一个无限循环运行的进程,每30秒执行一次,每次循环中会根据目标说明来检查实际状况是否正确。

例如:

  • 检查容器是否正常运行,如果没有,就根据说明创建一个,并配置好。
  • 检查容器是否在正确的复制拓扑位置,如果不是,就对其进行调整,例如:之前的一个从服务器要变更为master,就需要确保其是安全的,会检查旧master是否为只读,并且GTID是否被全部接收并执行,如果是,就移除和旧master的连接并变为可写。
  • 根据角色检查一系列参数,例如,master应该是可写的。
  • 启动或关闭一些支持型的容器,如 心跳和死锁的监控。

在创建MySQL复制关系时是有序的,但 agents 是不关心其管理的容器间的顺序的。

例如正常的构建复制过程这样的:

  1. 创建master,并等待其就绪
  2. 创建第一个slave,连接到master
  3. 重复创建slave

agents 工作时,不会先找角色为master的来配置,先遇到谁就配置谁。

如果先遇到了slave,配置时发现master还没有,就停止配置,继续处理下一个,然后等下一个工作循环中再次检查其master是否就绪,如果就绪了,就继续配置,完成了对这个容器的工作。

例如下图:

执行DB3时,DB1还不可用,就等着,直到某个工作循环中发现DB1可用时才配置完成。

小结

通过以上内容,我们可以对Uber的MySQL Docker方案有个大概了解,主要由以下4部分构成:

  1. 无状态的MySQL容器
  2. 整体集群拓扑结构的配置文件
  3. agents,每台主机上的工作者,负责本机上容器的创建、配置、状态检查与修正
  4. 服务中心,负责整体的维护和监控

实现了最初的目标:单机运行多数据库、自动化、统一管理入口。

2016年初开始迁移到Docker,到现在已经运行着1500台Docker服务器,2300个MySQL数据库。

内容整理自Uber官方博客,原文地址:https://eng.uber.com/dockerizing-mysql

原文发布于微信公众号 - 性能与架构(yogoup)

原文发表时间:2016-11-03

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Laoqi's Linux运维专列

KVM部署篇

89440
来自专栏EAWorld

DevOps的支撑服务:K8s容器管理与应用部署

? 大家好,本期微课堂介绍在新一代数字化企业云平台中对于Kubernetes的学习以及使用的总结。 ? 本次分享分为两部分: 1.介绍Kubernetes是什...

69470
来自专栏编程坑太多

『中级篇』Docker 水平扩展和负载均衡(40)

PS:Docker的scale 可以扩展,也可以所有,他们自动来控制的。web=10 可以改成5 其中的6,7,8,9,10就被删除了。

64330
来自专栏云计算

Docker 业务流程的概述以及用处

[本文由Yaron Parasol编写]

24160
来自专栏编程坑太多

『中级篇』如何在mac上安装docker(五)

20620
来自专栏编程坑太多

『中级篇』Docker 水平扩展和负载均衡(40)

PS:Docker的scale 可以扩展,也可以所有,他们自动来控制的。web=10 可以改成5 其中的6,7,8,9,10就被删除了。

12730
来自专栏极客日常

利用Katacoda免费同步Docker镜像到Docker Hub

安装kubernetes的时候,我们需要用到 gcr.io/google_containers 下面的一些镜像,在国内是不能直接下载的。如果用 Self Hos...

1.1K20
来自专栏杂文共赏

使用DCHQ自动部署和管理Docker Cloud /虚拟Java微服务

本文演示了一个在云或虚拟平台上,用于自动化部署和管理Docker Java微服务应用程序的解决方案。我们通过扩展现有项目Chris Richardson的示例—...

22240
来自专栏编程坑太多

『中级篇』Docker-Stack部署wordpress(49)

PS:docker-stack 就是通过yml类似docker-compose的文件来进行多机的部署。

10620
来自专栏糊一笑

教你使用docker部署淘宝rap2服务

1.3K40

扫码关注云+社区

领取腾讯云代金券