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升级、日志处理、网络规划 ……,所以,规模较小时,使用 Puppet、Ansible 这类的工具就够用了,例如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 是不关心其管理的容器间的顺序的。
例如正常的构建复制过程这样的:
- 创建master,并等待其就绪
- 创建第一个slave,连接到master
- 重复创建slave
agents 工作时,不会先找角色为master的来配置,先遇到谁就配置谁。
如果先遇到了slave,配置时发现master还没有,就停止配置,继续处理下一个,然后等下一个工作循环中再次检查其master是否就绪,如果就绪了,就继续配置,完成了对这个容器的工作。
例如下图:
执行DB3时,DB1还不可用,就等着,直到某个工作循环中发现DB1可用时才配置完成。
小结
通过以上内容,我们可以对Uber的MySQL Docker方案有个大概了解,主要由以下4部分构成:
- 无状态的MySQL容器
- 整体集群拓扑结构的配置文件
- agents,每台主机上的工作者,负责本机上容器的创建、配置、状态检查与修正
- 服务中心,负责整体的维护和监控
实现了最初的目标:单机运行多数据库、自动化、统一管理入口。
2016年初开始迁移到Docker,到现在已经运行着1500台Docker服务器,2300个MySQL数据库。
内容整理自Uber官方博客,原文地址:https://eng.uber.com/dockerizing-mysql
- Requests库作者Kenneth Reitz的另一神作!虚拟环境及包管理工具Pipenv!
- 你写的单例真的对吗
- TensorFlow layers模块用法
- Spark算子详解及案例分析(分类助记)
- Spark详解07广播变量BroadcastBroadcast
- TensorFlow验证码识别
- python selenium2 开发环境搭建
- 聊聊同步辅助类CountDownLatch
- Java多线程编程笔记之Condition
- python selenium2示例 - 生成 HTMLTestRunner 测试报告
- python selenium2示例 - email发送
- pyhton-----break语句
- python unittest使用基本过程
- 基于unittest集成你的selenium2测试
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 【crossbeam系列】3 crossbeam-deque:work-stealing算法
- 【Rust日报】2020-08-21 RustConf研讨会在线举办
- 了解不同架构思维,赏析架构之美
- 【Rust日报】2020-08-22 google/autocxx - 高度自动化的rust调用c++,而且安全,时尚
- 【Rust日报】2020-08-24 理解 Rust 的切片
- 猿实战05——手把手教你拥有自己的代码生成器
- Java单元测试——容器内部测试
- Java单元测试——框架(三)——testNG
- Nginx系列:后端服务应用健康检测
- 那些大厂必问的Handler和Binder,有必要去研究么?
- 欢迎来到 TreeMap 的吐槽大会
- OMG,12 个精致的 Java 字符串操作小技巧,学它
- Nginx系列:安全下载模块
- 5分钟入门GANS:原理解释和keras代码实现
- 使用ML 和 DNN 建模的技巧总结