数据分片 现在来想一下出现了一个 AZ 加一台机器挂掉的情况,这时我们需要重建一个副本,那么重建的时间就取决于数据库副本文件有多大,随着数据库增长,恢复时间也会线性增加。这个对一个发展越来越好的业务是不能接受的,所以需要尽可能降低数据恢复时间。恢复时间过长还会带来另一个隐患就是在恢复的过程中如果又有一个机器故障,那么数据就没办法直接通过其他副本来恢复了,而恢复时间越长这个风险越大。从 CAP 的角度来看 Aurora 作为一个利用分布式存储的数据库是选择了 CP,但是如果可用性出了问题能在极短的时间恢复,那么从实际使用角度也就和 CAP 系统差不多了。
这种数据分片的方式保证了数据库有很高的可用性,从运维角度来说就可以对这个系统进行 rolling update 了。比如想要升级底层的操作系统和软件,可以直接把机器下线进行升级,上面的分片都会很快在别的机器上进行重建,然后再把机器加回集群升级下一个。发现某台机器硬件有异常也不需要做手工的数据迁移,直接把机器下线送修。另外当出现数据热点的时候也可以直接将这个热点机器的其他分片标记为不可用把分片迁移走,来避免某一个用户的行为造成其他用户的性能下降。这些都是分片带来的好处。
另外由于 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 的性能在云环境里提升那么多。