博客
关于我
MySQL 到底能不能放到 Docker 里跑?
阅读量:797 次
发布时间:2023-02-10

本文共 4122 字,大约阅读时间需要 13 分钟。

MySQL 到底能不能放到 Docker 里跑?

前言

最近几月,我经常看到 MySQL 能不能放到 Docker 里跑的各种讨论。每个人都有自己的说法,但我认为这些讨论的落地意义不大。对错并非靠讨论决定,而是需要实践来证明。于是,同程旅游也开始了 MySQL 的 Docker 化实践,目前已经有超过一千多个 MySQL 实例在 Docker 平台上稳定运行。通过这一实践,我们的 DB 运维能力发生了质的提升,DBA 不再用担心删库跑路的问题。

当然,这并不意味着之前的讨论结论就是绝对正确的。我们只是在学飞行的小鸟,仍有很长的路要走。因此,我们将在本文中分享我们在 MySQL Docker 化上的实践经验。

背景介绍

同程旅游早期的数据库主要使用 MSSQL ,但这一产品虽然 UI 操作很棒,批量和自动化管理却很难做,人力成本较高。后来我们逐渐将 MSSQL 替换为 MySQL ,但仍然使用传统的运维方式管理,导致大部分工作都需要人肉运维。

MSSQL 的优点之一是 UI 操作很棒,尤其是在资源有限的年代里,可以在高可用实例上运行多个库,人肉运维完全可以应对。然而,MSSQL 的缺陷也不少,例如水平拆分困难,容易成为系统的瓶颈。

我们采取了 MySQL+中间件的组合方式进行水平拆分,解决了瓶颈问题。但水平拆分带来了数据库实例数量大幅上升的问题。例如,1024 分片需要 32 个 node,一主一从是必须的,这样至少需要 64 个实例,再加上应急扩展和备份用的节点,实例数量更多。

单机多实例运行 MySQL 的需求让我们思考资源隔离和限制的实现方案。KVM 对 DB 的隔离性能影响太大,不适用于生产环境。cgroups 虽然隔离性较低,但对我们的需求来说足够,然而实现资源限制和额外管理进程较为复杂。因此,最终我们选择了 Docker 作为资源隔离方案。

平台实现过程

站在巨人的肩膀上

我认为评价一款数据库的优劣,不仅要看数据库本身,还要看其周边生态是否健全,例如高可用方案、备份方案、日常维护难度等。同样,对于云平台也是如此。

我们进行了短平快的试错工作,将平台分为多个版本开发。第一个版本开发周期较短,主要用于试验,尽量利用现有的开源产品或对开源产品进行二次开发,满足定制化需求。以下是我们使用的部分开源产品和技术。

容器调度系统选择

容器调度的开源产品主要有 Kubernetes 和 Mesos,但我们没有选择这些。主要原因是我们内部已经开发了一套基于 Docker 的资源管理和调度系统,至今已稳定运行两年多。我们认为适合自己现状的需求才是较好的选择。当机会到来时,我们可能会考虑 Kubernetes 的方案。

工作原理

我们以创建集群为例说明工作原理。当平台发起一个创建集群的任务时,首先根据集群规模(一主一从还是一主多从,或者分片集群)确定需要创建的实例数量,然后根据需求筛选规则从现有资源池中匹配可用资源,依次创建主从关系、创建高可用管理、检查集群复制状态、推送集群信息到中间件,最后同步到 CMDB。

以上每一步都是通过服务端发送消息到 agent,由 agent 执行对应脚本完成的。这种方式的优势在于 DBA 更了解数据库,能够参与项目开发,提升开发效率。开发只需要写前台逻辑,DBA 负责后端具体执行指令。

资源调度分配原则

经过对同程多年 DB 运维数据的分析,我们总结了以下经验:

  • CPU 较大超卖 3 倍,内存不超卖;
  • 同一机房优先选择资源最空闲的机器;
  • 主从角色不允许在同一台机器上;
  • 若有 VIP 需求的主从端口需要一致,无 VIP 需求直接对接中间件的无端口一致的限制;
  • 分片的集群将节点分布在多台物理机上。

产品分类

核心功能

备份恢复系统

我们使用 Percona 的 xtrabackup 进行备份。通过流备份方式将数据备份到远端备份服务器,备份服务器有多台,分别按照所属机房划分。

我们提供了手工备份和定时备份来满足不同场景需求。多实例备份需要关注磁盘 IO 和网络,我们的备份策略限制了单个物理机上的并行备份数量,并对机房备份任务队列的并行度进行控制。

我们后来改造了备份存储方式,直接将备份流入分式存储。

监控告警系统

传统的 Zabbix 在上线前使用,但其后端数据库成为瓶颈。后来我们选择了 TSDB Prometheus,性能极强,适合监控系统使用。Prometheus 缺点是没有集群功能,但我们通过业务层面进行 DB 拆分,实现了分布式存储及扩展。

Prometheus 的优势在于单机性能强大,但也有两面性。我们通过 Consul 集群实现服务发现和配置共享,结合 Prometheus 实现监控节点注册。监控客户端以 agent 形式存在,Prometheus 通过 HTTP 协议获取 agent 端采集到的数据。

监控指标画图方面,Grafana 是度量仪表盘和图形编辑器的绝佳选择。我们打通了云平台和 Grafana 的关联,用户在云平台需要查看实例或集群信息,只需点击按钮即可。

告警管理分为告警发送、告警接收人管理、告警静默等功能。Prometheus 提供了 alertmanager,我们通过 webhook 的方式让 alertmanager 将告警信息发送到云平台的告警 API。

慢日志分析系统

慢日志的收集是通过 pt-query-digest 每小时进行本地分析,分析完成后将结果写入慢日志存储的数据库。用户可以在界面点击慢日志分析,查看该实例的慢日志分析结果。分析完成后可以在 UI 界面点击慢日志查看,集成了 explain、查看 table status 等功能。

集群管理

集群管理是平台的核心功能之一,占据了整个平台 70% 的工作。我们的设计思路是以集群为单位操作,这样可以避免在一个页面上显示过多无用信息,减少误操作的可能性。图中展示了部分功能,还有许多未展示的功能。

高可用

我们采用了目前最流行的 MySQL 高可用方案 MHA。MHA 的优缺点不在此讲,但我们对其进行了调整,支持 MariaDB 的 GTID。使用 GTID 后,灵活切换是一个方面,另外一个方面是 sync_master_info 和 sync_relay_log_info 可以不设置为 1。

切换时调整相关参数

我们在切换时调整 sync_binlog 和 innodb_flush_log_at_trx_commit 参数,默认设置为双 1。这样相对数据最安全,但 IO 也较高。云服务的多实例部署会导致一台物理机上既有 master 又有 slave。我们不希望 slave 产生太高的 IO 影响到同机器的其他 slave,因此主机设置双 1,slave 可以不这样设置。但是切换后原来的 slave 可能会变成 master,因此我们默认 slave 非双 1,在 MHA 切换时会自动将新 master 的这两个参数设置为 1。

哨兵部署在多个点,哨兵是一个简单的 API 服务,带上响应的参数可以请求到指定的实例。当 MHA manager 检测到有 Master 无法连接时,会触发 secondary check 机制,带着 master 相关信息请求哨兵节点的 API,根据哨兵节点返回情况,若超过半数无法连接则切换,否则放弃切换。

高可用切换对接 DB 中间件

DB 中间件和 DB 通过物理 IP 连接,当发生高可用切换时将的 Master IP、Master port 信息推送到 DB 中间件控制中心,DB 中间件拿到配置后立刻下发并生效。

实例、库迁移

迁移功能初衷是为了将平台外的实例或者库迁移到平台里面来。后来发现这个功能可挖掘的空间很大,比如可以做平台内库表拆分等需求。实现原理也很简单,用 mydumper 将指定数据备份下来以后,再用 myloader 恢复到指定数据库。

这是一个全量的过程,增量复制我们用自己开发的一个支持并行复制的工具,支持等幂处理。没有用原生复制的原因是,若要将源实例多个库中的一个库迁移到目标实例,原生复制就需要对 binlog 做过滤,这里面涉及到配置修改,实例重启,所以果断不考虑。

实现过程并没有高大上,但完全满足需求。当然 mydumper 和 myloader 也有一些问题,我们做了小改动以后才能实现。后面计划用流的方式做数据导出导入。

迁移完成后,增量无延迟的情况下,大家关心数据一致性问题,我们提供了自研的数据校验工具。实测 300G 数据校验时间约为 2 至 3 分钟,快慢取决于开多少线程。

屏蔽底层物理资源

对用户来讲,平台提供的是一个或一组数据库服务,不需要关心后端的实例是在哪台机器上。资源计算和调度全部由系统的算法进行管理。

提升资源利用率 (CPU、内存)

通过单机多实例,CPU 资源可超卖,提高资源利用率。内存资源未超卖,但可以控制到每个实例的内存使用,确保每个实例都能有足够的内存。若有剩余内存,继续分配容器即可,不 OOM 的情况下压榨内存资源。

提升运维效率

效率的提升得益于标准化以后带来的自动化。批量运维的成本很低。以前部署一套分片集群需要花费将近 6 个小时 (不包含对接中间件的 1 到 2 个小时),而现在只需要 5 分钟即可部署完成。并且部署完成以后会将提供一套中间件 +DB 分片集群的服务。

精细化管理

平台上线后有效提高了资源利用率,同时我们按照 1 库 1 实例的方式,可以有效避免不同库的压力不均导致相互影响的问题。并且性能监控也能精准到库级别。

结语

以上这些只是一个开始,后面还有很多功能需要完善,下面是近期策划的一些功能,其中有些已经在后版中开发完成。随着功能的不断迭代,我们会打造一个更加完美的私有云平台。

数据库私有云平台的上线对同程 DB 来说,意味着一个时代的结束,也意味着一个时代的开始。结束的是传统运维低效、高成本的运维时代,开始的是一个低成本、高效率、高保障的运维时代。我们相信未来会更美好!

转载地址:http://dzbfk.baihongyu.com/

你可能感兴趣的文章
MySQL 的 varchar 水真的太深了!
查看>>
mysql 的GROUP_CONCAT函数的使用(group_by 如何显示分组之前的数据)
查看>>
MySQL 的instr函数
查看>>
MySQL 的mysql_secure_installation安全脚本执行过程介绍
查看>>
MySQL 的Rename Table语句
查看>>
MySQL 的全局锁、表锁和行锁
查看>>
mysql 的存储引擎介绍
查看>>
MySQL 的存储引擎有哪些?为什么常用InnoDB?
查看>>
Mysql 知识回顾总结-索引
查看>>
Mysql 笔记
查看>>
MySQL 精选 60 道面试题(含答案)
查看>>
mysql 索引
查看>>
MySQL 索引失效的 15 种场景!
查看>>
MySQL 索引深入解析及优化策略
查看>>
MySQL 索引的面试题总结
查看>>
mysql 索引类型以及创建
查看>>
MySQL 索引连环问题,你能答对几个?
查看>>
Mysql 索引问题集锦
查看>>
Mysql 纵表转换为横表
查看>>
mysql 编译安装 window篇
查看>>