踩坑无数,美团点评高可用数据库架构演进

标签: | 发表时间:2017-12-28 22:46 | 作者:
出处:http://mp.weixin.qq.com

本文介绍最近几年美团点评 MySQL 数据库高可用架构的演进过程,以及我们在开源技术基础上做的一些创新。


同时,也和业界其他方案进行综合对比,了解业界在高可用方面的进展和未来我们的一些规划和展望。


MMM


在 2015 年之前,美团点评(点评侧)长期使用 MMM(Master-Master replication manager for MySQL)做数据库高可用。


因此我们积累了比较多的经验,但也踩了不少坑,可以说 MMM 在公司数据库高速发展过程中起到了很大的作用。


MMM 的架构如下:

如上图所示,整个 MySQL 集群提供 1 个写 VIP(Virtual IP)和 N(N>=1)个读 VIP 的对外服务。


每个 MySQL 节点均部署有一个 Agent(mmm-agent),mmm-agent 和 mmm-manager 保持通信状态,定期向 mmm-manager 上报当前 MySQL 节点的存活情况(这里称之为心跳)。


当 mmm-manager 连续多次无法收到 mmm-agent 的心跳消息时,会进行切换操作。


mmm-manager 分两种情况处理出现的异常:

  • 出现异常的是从节点,mmm-manager 会尝试摘掉该从节点的读 VIP,并将该读 VIP 漂移到其他存活的节点上,通过这种方式实现从库的高可用。

  • 出现异常的是主节点,如果当时节点还没完全挂,只是响应超时,则尝试将 Dead Master 加上全局锁(flush tables with read lock),在从节点中选择一个候选主节点作为新的主节点,进行数据补齐。

    数据补齐之后,摘掉 Dead Master 的写 VIP,并尝试加到新的主节点上。将其他存活的节点进行数据补齐,并重新挂载在新的主节点上。


主库发生故障后,整个集群状态变化如下:

mmm-manager 检测到 master1 发生了故障,对数据进行补齐之后,将写 VIP 漂移到了 master2 上,应用写操作在新的节点上继续进行。


然而,MMM 架构存在如下问题:

  • VIP 的数量过多,管理困难(曾经有一个集群是 1 主 6 从,共计 7 个 VIP)。某些情况下会导致集群大部分 VIP 同时丢失,很难分清节点上之前使用的是哪个 VIP。

  • mmm-agent 过度敏感,容易导致 VIP 丢失。同时 mmm-agent 自身由于没有高可用,一旦挂掉,会造成 mmm-manager 误判,误认为 MySQL 节点异常。

  • mmm-manager 存在单点,一旦由于某些原因挂掉,整个集群就失去了高可用。

  • VIP 需要使用 ARP 协议,跨网段、跨机房的高可用基本无法实现,保障能力有限。


同时,MMM 是 Google 技术团队开发的一款比较老的高可用产品,在业内使用的并不多,社区也不活跃,Google 很早就不再维护 MMM 的代码分支。


我们在使用过程中发现大量 Bug,部分 Bug 我们做了修改,并提交到开源社区。


MHA


针对于此,从 2015 年开始,美团点评对 MySQL 高可用架构进行了改进,全部更新为 MHA,很大程度上解决了之前 MMM 遇到的各种问题。


MHA(MySQL Master High Availability)是由 Facebook 工程师 Yoshinori Matsunobu 开发的一款 MySQL 高可用软件,从名字就可以看出,MHA 只负责 MySQL 主库的高可用。


当主库发生故障时,MHA 会选择一个数据最接近原主库的候选主节点(这里只有一个从节点,所以该从节点即为候选主节点)作为新的主节点,并补齐和之前 Dead Master 差异的 Binlog。数据补齐之后,即将写 VIP 漂移到新主库上。


整个 MHA 的架构如下(为简单起见,只描述一主一从):

这里我们对 MHA 做了一些优化,避免一些脑裂问题。


比如 DB 服务器的上联交换机出现了抖动,导致主库无法访问,被管理节点判定为故障,触发 MHA 切换,VIP 被漂到了新主库上。


随后交换机恢复,主库可被访问,但由于 VIP 并没有从主库上摘除,因此 2 台机器同时拥有 VIP,会产生脑裂。


我们对 MHA Manager 加入了向同机架上其他物理机的探测,通过对比更多的信息来判断是网络故障还是单机故障。


MHA+Zebra(DAL)


Zebra(斑马)是美团点评基础架构团队开发的一个 Java 数据库访问中间件。


它是在 c3p0 基础上包装的美团点评内部使用的动态数据源,包括读写分离、分库分表、SQL 流控等非常强的功能,它和 MHA 配合,成为了 MySQL 数据库高可用的重要一环。


如下是 MHA+Zebra 配合的整体架构:

以主库发生故障为例,处理逻辑有如下两种方式:

  • 当 MHA 切换完成之后,主动发送消息给 Zebra monitor,Zebra monitor 更新 ZooKeeper 的配置,将主库上配置的读流量标记为下线状态。

  • Zebra monitor 每隔一段时间(10s ~ 40s)检测集群中节点的健康状况,一旦发现某个节点出现了问题,及时刷新 ZooKeeper 中的配置,将该节点标记为下线。


一旦节点变更完成,客户端监听到节点发生了变更,会立即使用新的配置重建连接,而老的连接会逐步关闭。


整个集群故障切换的过程如下(仅描述 Zebra monitor 主动探测的情况,第一种 MHA 通知请自行脑补^_^)。

由于该切换过程还是借助于 VIP 漂移,导致只能在同网段或者说同个二层交换机下进行,无法做到跨网段或者跨机房的高可用。


为解决这个问题,我们对 MHA 进行了二次开发,将 MHA 添加 VIP 的操作去掉,切换完之后通知 Zebra monitor 去重新调整节点的读写信息(将 Write 调整为 new master 的实 IP,将 Dead Master 的读流量摘除)。


整个切换就完全去 VIP 化,做到跨网段、甚至跨机房切换,彻底解决之前高可用仅局限于同网段的问题。


上述切换过程就变成了如下图:

然而,这种方式中的 MHA 管理节点是单点,在网络故障或者机器宕机情况下依然存在风险。


同时,由于 Master-Slave 之间是基于 Binlog 的异步复制,也就导致了主库机器宕机或者主库无法访问时,MHA 切换过程中可能导致数据丢失。


另外,当 Master-Slave 延迟太大时,也会给数据补齐这一操作带来额外的时间开销。


Proxy


除了 Zebra 中间件,美团点评还有一套基于 Proxy 的中间件和 MHA 一起配合使用。


当 MHA 切换后,主动通知 Proxy 来进行读写流量调整,Proxy 相比 Zebra 更加灵活,同时也能覆盖非 Java 应用场景。


缺点就是访问链路多了一层,对应的 Response Time 和故障率也有一定增加。


未来架构设想


MHA 架构依然存在如下两个问题:

  • 管理节点单点

  • MySQL 异步复制中的数据丢失


针对于此,我们在部分核心业务上使用 Semi-Sync,可以保证 95% 以上场景下数据不丢失(依然存在一些极端情况下无法保障数据的强一致性)。


另外,高可用使用分布式的 Agent,在某个节点发生故障后,通过一定的选举协议来选择新的 Master,从而解决了 MHA Manager 的单点问题。


针对上述问题,我们研究了业界的一些领先的做法,简单描述如下。


主从同步数据丢失


针对主从同步的数据丢失,一种做法是创建一个 Binlog Server,该 Server 模拟 Slave 接受 Binlog 日志,主库每次的数据写入都需要接收到 Binlog Server 的 ACK 应答,才认为写入成功。


Binlog Server 可以部署在就近的物理节点上,从而保证每次数据写入都能快速落地到 Binlog Server。


在发生故障时,只需要从 Binlog Server 拉取数据即可保证数据不丢失。


分布式 Agent 高可用


针对 MHA 管理节点单点问题,一种做法是让 MySQL 数据库集群中每个节点部署 Agent,当发生故障时,每个 Agent 均参与选举投票,选举出合适的 Slave 作为新的主库,防止只通过 Manager 来切换,去除 MHA 单点。


整个架构如下图所示:

MGB 结合中间件高可用


上述方式某种程度上解决了之前的问题,但是 Agent 和 Binlog Server 却是新引入的风险,同时 Binlog Server 的存在,也带来了响应时间上的额外开销。


有没有一种方式,能够去除 Binlog Server 和 Agent,又能保证数据不丢失呢 ?答案当然是有的。


最近几年,MySQL 社区关于分布式协议 Raft 和 Paxos 非常火,社区也推出了基于 Paxos 的 MGR 版本的 MySQL,通过 Paxos 将一致性和切换过程下推到数据库内部,向上层屏蔽了切换细节。


架构如下(以 MGR 的 single-primary 为例):

当数据库发生故障时,MySQL 内部自己进行切换。切换完成后将 topo 结构推送给 Zebra monitor,Zebra monitor 进行相应的读写流量变更。


不过,该架构存在与 Binlog Server 同样的需要回复确认问题,就是每次主库数据写入,都需要大多数节点回复 ACK,该次写入才算成功,存在一定的响应时间开销。


同时,每个 MGR 集群必须需要奇数个数(大于 1)的节点,导致原先只需要一主一从两台机器,现在需要至少三台,带来一定的资源浪费。


但不管怎么说,MGR 的出现无疑是 MySQL 数据库又一次伟大的创新。


结语


本文介绍了美团点评 MySQL 数据库高可用架构从 MMM 到 MHA+Zebra 以及 MHA+Proxy 的演进历程,同时也介绍了业界一些高可用的做法。


数据库最近几年的发展突飞猛进,数据库的高可用设计上没有完美的方案,只有不断的突破和创新,我们也一直在这条路上探索更加优秀的设计与更加完美的方案。


作者:金龙

简介:2014 年加入新美大,主要从事相关的数据库运维,高可用和相关的运维平台建设。

编辑:陶家龙、孙淑娟

出处:本文由美团点评技术团队微信公众号授权转发

精彩文章推荐:

京东京麦:微服务架构下的高可用网关与容错实践

日存储量超10TB,海量数据挑战下腾讯全链路日志监控平台实践

饿了么高稳定、高性能、高可用、高容错API架构实践!

相关 [无数 美团 数据库] 推荐:

踩坑无数,美团点评高可用数据库架构演进

- -
本文介绍最近几年美团点评 MySQL 数据库高可用架构的演进过程,以及我们在开源技术基础上做的一些创新. 同时,也和业界其他方案进行综合对比,了解业界在高可用方面的进展和未来我们的一些规划和展望. 在 2015 年之前,美团点评(点评侧)长期使用 MMM(Master-Master replication manager for MySQL)做数据库高可用.

美团数据库高可用架构的演进与设想 -

- -
本文介绍最近几年美团MySQL数据库高可用架构的演进过程,以及我们在开源技术基础上做的一些创新. 同时,也和业界其它方案进行综合对比,了解业界在高可用方面的进展,和未来我们的一些规划和展望. 在2015年之前,美团(点评侧)长期使用MMM(Master-Master replication manager for MySQL)做数据库高可用,积累了比较多的经验,也踩了不少坑,可以说MMM在公司数据库高速发展过程中起到了很大的作用.

新一代数据库TiDB在美团的实践

- - IT瘾-geek
近几年,基于MySQL构建的传统关系型数据库服务,已经很难支撑美团业务的爆发式增长,这就促使我们去探索更合理的数据存储方案和实践新的运维方式. 而随着分布式数据库大放异彩,美团DBA团队联合基础架构存储团队,于 2018 年初启动了分布式数据库项目. 在立项之初,我们进行了大量解决方案的对比,深入了解了业界的 scale-out(横向扩展)、scale-up(纵向扩展)等解决方案.

美团 MySQL 数据库巡检系统的设计与应用

- - IT瘾-dev
我们生活中随处可见各种巡检系统,比如电力巡检、消防检查等,正是这些巡检工作,我们才能在稳定的环境下进行工作、生活. 巡检对于数据库或者其他IT系统来说也同样至关重要,特别是在降低风险、提高服务稳定性方面起到了非常关键作用. 为了保障数据库的稳定运行,以下核心功能组件必不可少:. 图1 数据库运维保障核心功能组件 其中,数据库巡检作为运维保障体系最重要的环节之一,能够帮助我们发现数据库存在的隐患,提前治理,做到防患于未然.

超大规模数据库集群保稳系列之三:美团数据库容灾体系建设实践 - 美团技术团队

- -
我们通常会把故障分为三大类,一是主机故障,二是机房故障,三是地域故障. 每类故障都有各自的诱发因素,而从主机到机房再到地域,故障发生概率依次越来越小,而故障的影响却越来越大. 容灾能力的建设目标是非常明确的,就是要能够应对和处理这种机房级和地域级的大规模故障,从而来保障业务的连续性. 近几年,业界也发生了多次数据中心级别的故障,对相关公司的业务和品牌产生了非常大的负面影响.

美团点评数据库高可用架构的演进与设想

- - 美团点评技术团队
本文介绍最近几年美团点评MySQL数据库高可用架构的演进过程,以及我们在开源技术基础上做的一些创新. 同时,也和业界其它方案进行综合对比,了解业界在高可用方面的进展,和未来我们的一些规划和展望. 在2015年之前,美团点评(点评侧)长期使用MMM(Master-Master replication manager for MySQL)做数据库高可用,积累了比较多的经验,也踩了不少坑,可以说MMM在公司数据库高速发展过程中起到了很大的作用.

写了一个小 wiki 玩具 in web.py,无数据库,默认支持 markdown 标记

- wang - python.cn(jobs, news)
我用写了一个轻量 wiki 玩具名为 ZWiki (大小写敏感), 仅仅是因为妹子回家无聊,它不会像 mediawiki 那么庞大、强大和臃肿. - 基于 web.py 写,部分脏活粗暴直接调用 find grep 来干. - 支持 markdown 标记. - 不用数据库,粗暴直接读写文本文件,你可以用 Firefox + It's all text + 任意编辑器更新 wiki ,或者直接 修改对应的文本文件.

数据库sharding

- - 数据库 - ITeye博客
当团队决定自行实现sharding的时候,DAO层可能是嵌入sharding逻辑的首选位置,因为在这个层面上,每一个DAO的方法都明确地知道需要访问的数据表以及查询参数,借助这些信息可以直接定位到目标shard上,而不必像框架那样需要对SQL进行解析然后再依据配置的规则进行路由. 另一个优势是不会受ORM框架的制约.

数据库索引

- - CSDN博客推荐文章
索引是由用户创建的、能够被修改和删除的、实际存储于数据库中的物理存在;创建索引的目的是使用户能够从整体内容直接查找到某个特定部分的内容. 一般来说,索引能够提高查询,但是会增加额外的空间消耗,并且降低删除、插入和修改速度. 1.聚集索引:表数据按照索引的顺序来存储的. 2.非聚集索引:表数据存储顺序与索引顺序无关.

数据库事务

- - 数据库 - ITeye博客
事务传播发生在类似以下情形:. 假设methodB的配置是:. 如果methodA在事务里,那么methodB也在这个事务中运行. 如果methodA不在事务里,那么methodB重新建立一个事务运行. 如果methodA在事务里,那么methodB也在这个事务中运行. 如果methodA不在是事务里,那么methodB在非事务中运行.