五倍吞吐量的提升,跨可用区的六副本,低于一分钟的宕机恢复,兼容 MySQL协议,这是 AWS 推出 Aurora 数据库时给出的数据。

这种量级的提升不可能是小修小补,大都是在架构上有了变革性的突破才能达到,坊间流传了很多Aurora 性能提升的秘密,在 Sigmod'17 上Amazon 终于自己发了一篇论文介绍了在云环境下如何重新打造数据库这种传统软件。很多的传统软件都可以看一下上云是不是只是装一个软件那么简单。

数据持久性

尽管 Aurora 的性能数据很亮眼,但对于数据库来说最基本的要求还是一旦数据写入成功就不能丢,数据的持久性才是第一位的。多副本是解决数据持久性的常用办法,AWS 采用了基于 quorum 投票的协议来管理副本。简单说就是如果有 N 个副本,则一次写数据要求至少写入(N/2)+1 个节点才算写入成功,剩下的节点通过相互之间的一致性协议可以达到共同的状态,而读数据则要求至少从 N/2 个节点中读出相同的数据才能决定哪个数据是最新的。(www.alauda.cn)

对于一个 3 副本的 quorum 系统,读写的 quorum 数都是 2 ,这也是一个比较常见的高可用系统选择的 quorum 数。但是这个副本数放在大规模多组户的系统里是不能保证数据的持久性的。因为在大规模系统中,节点出问题是每时每刻都会发生的,如果只有三副本的话,基本上每时每刻都会有一个用户的系统处在 2/3 的健康状态。AWS 的 3 副本是分布在 3 个不同的可用区的,如果一个可用区出了故障,那么所有的数据库副本就会变成 2/3 的健康状态,这种情况下任意一个机器的故障都会导致一个用户的 quorum 健康数变为 1/3,这时候就没有办法判断数据是否一致了。

所以 Aurora 采用的是六副本,每个可用区两副本。这种架构可以保证写入操作可以容忍一个可用区不可用的情况 4/6,而读数据可以容忍一个可用区外加一台机器不可用的情况 3/6。一旦出现了一个可用区加一台机器不可用的 3/6 情况,写数据会被禁止,但是由于读数据可以进行可以很快的根据读出的数据再恢复出一个副本达到 4/6 状态恢复写入。

数据分片

现在来想一下出现了一个 AZ 加一台机器挂掉的情况,这时我们需要重建一个副本,那么重建的时间就取决于数据库副本文件有多大,随着数据库增长,恢复时间也会线性增加。这个对一个发展越来越好的业务是不能接受的,所以需要尽可能降低数据恢复时间。恢复时间过长还会带来另一个隐患就是在恢复的过程中如果又有一个机器故障,那么数据就没办法直接通过其他副本来恢复了,而恢复时间越长这个风险越大。从 CAP 的角度来看  Aurora 作为一个利用分布式存储的数据库是选择了 CP,但是如果可用性出了问题能在极短的时间恢复,那么从实际使用角度也就和 CAP 系统差不多了。

一个直接的做法就是把副本分片,这样一个副本就可以散落在多台机器,这样一台机器挂的情况下我们就不需要恢复完整的副本,只需要恢复机器上的分片就可以。另一方面由于数据进行了分片,读数据的时候也可以利用多台主机的 IO 带宽,对性能也有提升。AWS 采用了 10G 的分片大小,这样在万兆网络的内网环境下,恢复一个分片可以在 10s 内完成,这样在比较极端的 1AZ+1 出故障的情况下,可以保证 10s 内恢复数据库读写。

这种数据分片的方式保证了数据库有很高的可用性,从运维角度来说就可以对这个系统进行rolling update 了。比如想要升级底层的操作系统和软件,可以直接把机器下线进行升级,上面的分片都会很快在别的机器上进行重建,然后再把机器加回集群升级下一个。发现某台机器硬件有异常也不需要做手工的数据迁移,直接把机器下线送修。另外当出现数据热点的时候也可以直接将这个热点机器的其他分片标记为不可用把分片迁移走,来避免某一个用户的行为造成其他用户的性能下降。这些都是分片带来的好处。

副本的副作用

前面说了多副本带来的数据持久和高可用,但是多副本并不是没有代价的。本来磁盘 IO 的速度就慢,多个副本之间即使是并行的写入操作,latency 也会变成最慢的节点的 latency,随着副本数的增多,抖动会变得更大。另外在云环境下的数据库和传统环境下数据库很重要的一点不同就是计算和存储是分离的,这种情况下读数据可以从本地缓存中拿,而写数据就需要网络 IO,由于存储分散在了多台机器上可以并行利用磁盘带宽,瓶颈就来到了网络。

而 MySQL 自己的一些 IO 机制主要是针对本地磁盘设计的,很多优化方法并不适用于网络存储,此外 MySQL 自己的一些事务和故障恢复的机制,会造成写放大的问题。来看一下 MySQLmirror 机制下的 IO 流程:

可以看到数据库一次写入除了要把数据写入还有 log, binlog,double-write,frm-file 这些东西要写入,而且需要在 master 上完成后才能再去 mirror 上执行同样的过程,等到 mirror 完成后一次请求才能结束。如果直接用 MySQL 的 mirror 机制那么上面提到的 6 副本系统实际上写入需要满足 6/6 才能成功,延迟会极大的加大。如果 AWS 采用这种机制,吞吐量不降到六分之一就算万幸了,更不要提五倍的提升了。这大概也是 AWS 想要自己搞数据库的原因,那么该怎么搞呢?

Log 即数据

要说 AWS 比起 Oracle(MySQL 现在的爹)做 MySQL 有什么优势的话那就是虽然数据库我没你们熟,但是底层的系统硬件我们都可以自己控制呀。看一下上面那张 IO 流程图,其实很多 log 都是怕底层存储出问题,机器突然断电造成数据不一致和考虑如何进行恢复才生成的。此外这里的一些数据是有冗余的,比如数据库在写入数据前都要先写入 WAL 再进行数据页的写入,至于为什么要这么做可以参考 《WAL 是如何保证数据库事务一致性的》,这里只要知道通过 WAL 我们是可以重建数据的,只是这样做读数据效率会比较低所以数据库都会再写一次完整数据到硬盘,保证读的效率。

另外由于 MySQL 自己本身不能更改存储系统的功能,所以镜像功能需要自己控制实现,所有的数据同步都要过 MySQL 这个用户层程序去控制,而这些同步的功能又会占用大量的资源开销影响正常的读写操作,相当于每写一次数据,资源开销是原来的多倍。此外在故障恢复的时候 MySQL 在启动时需要话大量的时间对比日志和实际数据状态的差异,就行数据修复,这个过程也会导致故障恢复时间的延长。

AWS 的解决方式就是既然WAL 里已经包含了所有的数据,那么我就不同步其他的东西了,只同步 log 就可以了。MySQL 去控制同步过程效率低,我底层的 EBS 自己就带同步功能啊,根本不需要 MySQL 再去控制,MySQL 基本只需要老老实实的做 SQL 相关的工作就可以了。数据库的故障恢复,存储系统可以自己进行数据恢复,MySQL只需要把引擎启动起来就可以了。总结来说就是 MySQL 之前之所以慢是因为文件系统有很多缺陷需要很多额外的功夫来保证数据写入能成功,现在 AWS 给了一个及其完善的文件系统,数据写入了就能成功,断电了也能自己恢复,还能自己做多副本,那么 MySQL 自己要做的事情就少了,性能自然也就上去了。现在的流程就简化成了:

所有的 Replica 节点不需要将数据写入磁盘了,数据同步由底层的 EBS 系统来做。Replica 节点只需要接收 Primay 的 Log 信息来更新本地的缓存和一些全局的配置。Primary 的写入操作也不再需要各种各样的 log 写入,只需要把 WAL 给底层存储系统,存储系统会自动的写入到一定的 quorum 节点上。而有了这些 log,存储系统会自动的去做 checkpoint, 备份和故障恢复,而且这些耗时的操作都是在后台默默的异步执行的,不需要前台的 MySQL 引擎。这样写入操作的 IO 量和操作路径都显著变少了,AWS 才能把 MySQL 的性能在云环境里提升那么多。

再加上分片的存储将磁盘 IO 的压力分散,读写性能都得到了显著提升,放两张图来感受一下:

AWS是怎么改写 MySQL的?的更多相关文章

  1. 关于mysql字段时间类型timestamp默认值为当前时间问题

    今天把应用部署到AWS上发现后台修改内容提交后程序报错,经过排查发现是更新数据的时候,有张数据表中的一个timestamp类型的字段默认值变成了"0000-00-00 00:00:00.00 ...

  2. GPL协议的MySQL数据库

    网络上多数朋友担心甲骨文会对MySQL软件采用收费模式,多数朋友也不清楚MySQL开源到底是什么模式,开源=免费嘛?是很多的疑问?MySQL是遵守双重协议的,一个是GPL授权协议,一个是商用授权协议( ...

  3. php改写session到数据库

    session改写mysql 在调用 session_start();的地方改用实例化本类即可new SessionDB(); session_set_save_handler( array($thi ...

  4. MySQL 0Day漏洞出现 该漏洞可以拿到本地Root权限

    2016年9月12日, legalhackers.com网站发布了编号为CVE-2016-6662的0day漏洞公告 .由于该漏洞可以获得MySQL服务器的Root权限,且影响MySql5.5.5.6 ...

  5. 数据库对比:选择MariaDB还是MySQL?

    作者 | EverSQL 译者 | 无明 这篇文章的目的主要是比较 MySQL 和 MariaDB 之间的主要相似点和不同点.我们将从性能.安全性和主要功能方面对这两个数据库展开对比,并列出在选择数据 ...

  6. MySQL运行计划初探

    -Mysql运行计划总结– 1 运行计划概述 先看看一个运行计划 mysql> explain SELECT * FROM EMP , DAO_OBJECTS t1 , DAO_OBJECTS ...

  7. Entity Framework Core For MySql查询中使用DateTime.Now的问题

    背景 最近一直忙于手上澳洲线上项目的整体迁移和升级的准备工作,导致博客和公众号停更.本周终于艰难的完成了任务,借此机会,总结一下项目中遇到的一些问题. EF Core一直是我们团队中中小型项目常用的O ...

  8. MySQL数据库基础-JAVA

    数据库 MySQL初步 MySQL基础认知 (Oracle真的是走哪祸害到哪23333) Java多用MySQL和Oracle SQLServer也收费,但是还行,比Oracle便宜,一个差不多3w多 ...

  9. MYSQL渗透测试

    部分来源于:先知社区 MYSQL-getshell篇 通过日志getshell 查看日志的物理路径(绝对路径) show variables like '%general%'; 打开日志记录内容 se ...

随机推荐

  1. 蜕变成蝶~Linux设备驱动中的阻塞和非阻塞I/O

    今天意外收到一个消息,真是惊呆我了,博客轩给我发了信息,说是俺的博客文章有特色可以出本书,,这简直让我受宠若惊,俺只是个大三的技术宅,写的博客也是自己所学的一些见解和在网上看到我一些博文以及帖子里综合 ...

  2. TeamViewer 版本v13.2.26558 修改ID

    TeamViewer 使用频繁后会被判定为商业用途,不可用.此软件的账号和设备mac地址绑定. 修改TeamViewer ID后可以重新开始使用.下述方法可以成功修改TeamViewer ID. Wi ...

  3. Pointer-network的tensorflow实现-1

    pointer-network是最近seq2seq比较火的一个分支,在基于深度学习的阅读理解,摘要系统中都被广泛应用. 感兴趣的可以阅读原paper 推荐阅读 https://medium.com/@ ...

  4. [转]Python中__repr__和__str__区别

    class Test(object): def __init__(self, value='hello, world!'): self.data = value >>> t = Te ...

  5. 没钱买windows怎么办?

    ReactOS是一个与 Windows 环境二进制兼容的操作系统. 同时,他是一款开源.免费的操作系统.

  6. wpgcms---循环导航

    使用wpgcms的时候,在后台设置了导航菜单,那么在前端是如何循环呢? 第一种:简便方法 {% set array = [ {name:'移动APP',icon:'icon-yidongAPP',co ...

  7. 创建多进程Process

    注册一个进程: from multiprocessing import Process import os def func(args): # 在子进程里面.args接收一个参数,如果要接受多个参数使 ...

  8. Java课程寒假之《人月神话》有感之一

    一.焦油坑 以前上课的时候,老师讲过早期的程序由于工作量不大,大多只需要几个人完成,随着软件规模的不断扩大,代码量直线上升,仅仅一两个人可能没有办法完成这样的任务,多以开始形成了团队的规模,焦油坑说的 ...

  9. php跨域发送请求原理以及同步异步问题

    <script async type="text/javascript" src="http://lisi.com/data.php?flag=1"> ...

  10. 16 css实现模糊背景

    --------------------- 本文来自 csu_zipple 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/csu_passer/article/det ...