AWS是怎么改写 MySQL的?
五倍吞吐量的提升,跨可用区的六副本,低于一分钟的宕机恢复,兼容 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的?的更多相关文章
- 关于mysql字段时间类型timestamp默认值为当前时间问题
今天把应用部署到AWS上发现后台修改内容提交后程序报错,经过排查发现是更新数据的时候,有张数据表中的一个timestamp类型的字段默认值变成了"0000-00-00 00:00:00.00 ...
- GPL协议的MySQL数据库
网络上多数朋友担心甲骨文会对MySQL软件采用收费模式,多数朋友也不清楚MySQL开源到底是什么模式,开源=免费嘛?是很多的疑问?MySQL是遵守双重协议的,一个是GPL授权协议,一个是商用授权协议( ...
- php改写session到数据库
session改写mysql 在调用 session_start();的地方改用实例化本类即可new SessionDB(); session_set_save_handler( array($thi ...
- MySQL 0Day漏洞出现 该漏洞可以拿到本地Root权限
2016年9月12日, legalhackers.com网站发布了编号为CVE-2016-6662的0day漏洞公告 .由于该漏洞可以获得MySQL服务器的Root权限,且影响MySql5.5.5.6 ...
- 数据库对比:选择MariaDB还是MySQL?
作者 | EverSQL 译者 | 无明 这篇文章的目的主要是比较 MySQL 和 MariaDB 之间的主要相似点和不同点.我们将从性能.安全性和主要功能方面对这两个数据库展开对比,并列出在选择数据 ...
- MySQL运行计划初探
-Mysql运行计划总结– 1 运行计划概述 先看看一个运行计划 mysql> explain SELECT * FROM EMP , DAO_OBJECTS t1 , DAO_OBJECTS ...
- Entity Framework Core For MySql查询中使用DateTime.Now的问题
背景 最近一直忙于手上澳洲线上项目的整体迁移和升级的准备工作,导致博客和公众号停更.本周终于艰难的完成了任务,借此机会,总结一下项目中遇到的一些问题. EF Core一直是我们团队中中小型项目常用的O ...
- MySQL数据库基础-JAVA
数据库 MySQL初步 MySQL基础认知 (Oracle真的是走哪祸害到哪23333) Java多用MySQL和Oracle SQLServer也收费,但是还行,比Oracle便宜,一个差不多3w多 ...
- MYSQL渗透测试
部分来源于:先知社区 MYSQL-getshell篇 通过日志getshell 查看日志的物理路径(绝对路径) show variables like '%general%'; 打开日志记录内容 se ...
随机推荐
- linux搭建FTP服务器并整合Nginx
操作系统:Centos7 1.1.服务器配置 # 关闭SELINUX,把SELINUX=enforcing改为SELINUX=disabled,reboot重启服务器生效 vim /etc/sysco ...
- 一对一voip,直播连麦,在线会议,兼容webrtc,IM音视频
功能 IM消息系统 一对一 高清音视频实时通信,可无缝切换P2P传输,节省服务器带宽 一对多互动直播 多对多在线会议 手机实时录屏传输 高度定制化 网络检测,动态码率与动态帧率,抗网络抖动,微信级效果 ...
- PHP读取文本文件(TXT)
<? header("content-type:text/html;charset=utf-8"); $file = "demo.txt"; ###判断该 ...
- 基于【CentOS-7+ Ambari 2.7.0 + HDP 3.0】搭建HAWQ数据仓库——安装配置OPEN-SSH,设置主机节点之间免密互访
配置root用户免密互访(为了方便,各台系统中使用统一的证书文件)一.安装Open-SSH 1,查询系统中是否安装了openssh [root@]# opm -qa |grep ssh 如已安装,则列 ...
- 我的订单页面List
<%@ page language="java" contentType="text/html;charset=UTF-8"%> <%@ ta ...
- shell 递归枚举文件并操作
递归枚举文件并操作 #!/bin/bash CURDIR=$(cd $(dirname $0); pwd) export GOPATH=$CURDIR/.. echo GOPATH=$GOPATH c ...
- Nestjs 接口验证
class-validator Nestjs yarn add class-transformer class-validator main.ts import { NestFactory } fro ...
- 怎么用js实现jq的removeClass方法
1.addClass:为指定的dom元素添加样式. 2.removeClass:删除指定dom元素的样式. 3.toggleClass:如果存在(不存在),就删除(添加)一个样式. 4.hasClas ...
- eclipse中的快捷键的使用
- C语言定义的操作mysql数据库的接口
编写的环境:centos7系统下,对mysql的衍生mariadb进行数据库的操作,包含设置访问数据库的参数,查询数据库和增删改数据库的三个功能.对于查询数据库,我这里允许不返回查询结果,用于判断查询 ...