一、RDS MySQL
(一)云数据库服务
RDS MySQL是云数据库服务,它将MySQL的部署、运维、弹性、安全等特性封装起来,对外提供一个数据库实例,相对于用户自建数据库,云数据库服务具有更经济、更专业、更高效、更可靠、简单易用等特点,使用户能更专注于核心业务。
- 部署:多种部署架构,满足多可用性要求
1)可用模式:单实例/主备/三节点
2)容灾能力:同城容灾/异地容灾
- 运维:丰富运维功能,大幅降低运维成本
1)自动运维:备份恢复/版本升级/监控报警/故障切换
2)专家服务:性能诊断/优化建议
- 弹性:灵活产品形态,满足系统可扩展性
1)自由弹性:可按需随时升级内存、磁盘空间,紧随业务发展
2)只读实例:横向扩展数据库读能力
- 安全:极高安全等级,保证数据库安全性
1)数据安全:可靠性9个9,RPO=0,秒级的数据恢复和找回
2)数据隐私:数据链路加密、数据落盘加密
接下来,本文会阐述如何在RDS MySQL中实现以上功能。
(二)产品逻辑
上方为RDS MySQL产品逻辑图。
最下层为IAAS层资源抽象,包含硬件、ECS、云盘和下虚拟网络。资源层之上是阿里定制的AliSQL内核,这里还有一些管控功能。再往上是安全防护,包含链路加密、数据加密、访问权限控制等。
最上层的用户控制台是可以让用户操作页面来控制数据库的参数配置、重启切换等。
(三)业务模型
上图为RDS MySQL业务模型图。
VPC表示虚拟网络,VPC中的模块之间网络是互通的。
可以看到中间的实体模块,一个可用区下面包含数个机房,RDS的主实例、备实例或者三节点的不同的节点,是在不同的可用区里面的。
在不同可用区的原因是如果发生某个可用区故障,我们可以快速地把服务切换到另外一个可用区,这是高可用里跨区切换的基本保证。
SLB是网络分发,当外部用户连接进来后,通过这个模块自动分发到主实例。
前文提到我们有读写实例和只读实例,MySQL产品提供了数据库代理模块。代理模块只对用户开放一个连接串,用户连接进来之后,数据库代理可以根据用户的业务请求情况,自动分发到读写实例或者只读实例。
除此之外还有一些公共组件,如密钥管理KMS,数据备份和日志备份的OSS,审计日志SLS,监控数据的云监控,还有管理模块OpenAPI和控制台。
整个实例上面进行操作的原子操作通过OpenAPI提供,然后控制台调用API,进而控制整个集群。
(四)管控架构
云数据库管控架构分为三层,最下层为资源层,负责所有的资源的管理和调度。运维管理层包含许多功能,如备份、恢复和监控等。接入层包含控制台、OpenAPI等。
接下看一下在这个结构下面,RDS MySQL有一些什么特点。
(五)产品优势
1. 经济:IAAS层自动化和成本控制
IASS层是云数据库服务的基石,提供了如下基础的服务。
- 资源预测
1)售卖数据分析
2)库存分析
3)资源利用率分析
- 采购部署
1)一键化部署
2)新机型演进
3)DEVOPS
4)硬件加速(RDMA,25G)
- 故障 & 过保
1)主机故障检测
2)资源争抢问题
3)IOHang检测
4)自动化宕机下线
5)热迁移秒级闪断
- 售卖
1)主备打散
2)售卖水位控制
3)资源隔离
4)资源碎片控制
2. 稳定:完整的监控探测能力和快速恢复能力
- 高可用版主备间心跳同步
- 物理机跨机架、跨ASW部署,主备跨可用区部署能力
- 三节点企业版的三机房部署容灾防脑裂
- 机房级别的容灾切换能力
- 实时备份保证异常情况下服务快速拉起
如上所示,对于主备实例,我们有HA探活模块实时监控主备的健康状态,如果主节点发生故障,可以由备节点很快地进行接管,接管动作由HA自动完成的。
如果不是主备实例,而是单实例,当遇到节点故障,可以通过OSS拉数据的方式恢复实例。
3. 弹性:数据搬迁效率的提升和云原生能力
计算存储结合架构的特点是本地盘宿主机动态流控,切换秒级闪断。
计算存储分离架构的特点是更简洁的扩容流程,计算存储的本地扩容,分钟级的弹性能力。
4. 安全:最严格的安全合规要求
用户数据进来后,会经过三个流程,分别是事前防护、事中保护、事后审计。
- 事前防护
1)专有网络VPC&平滑切换能力
2)传输链路的SSL加密
3)自研AliIpFilter安全模块
- 事中保护
1)支持本地盘TDE和云盘加密等多种介质
2)用户自带密钥加密BYOK能力
3)支持密钥不落盘能力
- 事后审计
1)SQL审计能力
2)API操作记录审计
二、RDS MySQL内核
接下来看一下RDS MySQL数据库内核,在社区版的基础上,我们做了哪些方面的优化。
(一)可诊断度量
可诊断度量即监控,可以全方位、无死角、细粒度地对RDS MySQL 数据库监控,包括实例级、对象级和语句级。
1. 实例级别
Server + InnoDB 55 个指标
PFS.perf_statisitics 内存表
实例级别引入了Server + InnoDB 55个指标,这个输出是PFS.perf_statisitics 内存表,可以看到整个实例级别的运行状态。
2. 对象级别
Table statistics 是业务系统 SCALE 的数据支撑。
Index statistics 是业务系统优化 INDEX 的数据支撑。
3. 语句级别
在语句级别,当某条SQL语句,可能返回时间慢了,运行时间长了,我们可以通过一个语句级别的统计,来查看过程中的哪个步骤导致这些问题。
如上图所示,通过这些值可以帮助我们优化SQL。
(二)稳定性提升
在业务中经常遇到稳定性的问题。当实例运行的时候,当遇到压力大的情况,我们允许运行时间适当增加,但不希望系统出现很剧烈的波动,因此针对稳定性问题,我们根据线上遇到的情况做了各种优化,下面举例说明。
1. Safe to Execute DDL Under High Load
下面说一下InnoDB缓存Buffer Pool的管理。
它把所有表的对象的配置放在一起管理,当我们需要做DDL操作时,需要在Buffer Pool里把每个配置先扫描一遍,然后做相应的动作,如刷盘,做完之后才能进行下一步DDL动作。
但是当Buffer Pool比较大的时候,这个过程会比较慢。
首先影响的就是DDL语句本身,它的时间会比较长。第二是当它频繁扫描Buffer Pool时,会对其他Session造成影响,这样就会造成Session抖动,延迟比较大。这里我们做了一个优化,跟踪每个Table的每个对象配置的使用情况,然后在做相应操作的时候,可以瞬间完成。
下图是一个测试数据,可以看到性能得到很大提升。
2. 大表异步删除防止IO抖动
当遇到大表删除的情况,比如一个IBD文件大小为数百GB或上T,原生社区版删除这个表是直接删除,这会对文件系统造成非常大的冲击。如果这个机器上还运行了其他的应用或实例,会造成比较大的影响。
大表异步删除防止IO抖动的特性原理也比较简单。当删大文件时,我们分步骤一点一点删掉。DDL做完之后,会把IBD文件临时管理起来,然后少量分批进行删除,如下图所示。
同时,我们可以实时查询后台 IDB file 的 truncate 过程,看到系统里面当前有多少表在执行异步删除。
3. BP Online Resize: Expand Or Shrink Buffer Pool Freely
Buffer Pool在调大的时候,对系统没有什么影响,但如果是Buffer Pool由大变小,它会对系统的运行稳定性造成很大影响。
Adjust Buffer Pool Size Dynamically By Work Load
上图绿色的线是社区版在Buffer Pool调小时的表现,尖刺抖动非常明显,对业务吞吐率造成巨大波动。蓝色线是优化完了之后的表现,波动明显减弱,对业务的影响大幅减少。可以看到,RDS MySQL在做Buffer Pool在线扩缩容是比较平滑的。
4. Advanced Thread Pool
MySQL默认一个Session对应一个线程,这种模式如果是在短连接或者并发比较大的场景,由于系统里面的线程比较多,并发上线和业务性能会受到影响。
我们知道,线程池并不是适用于所有的场景,比如大SQL或大的DDL。
如上图所示,RDS MySQL对线程池做了优化,无论业务负载是短平快的负载,还是较大SQL,或者是长链接与短链接,线程池默认打开。
Performance Stable
5. SQL Outline
当遇到业务SQL在运行过程中,可能会因为如下原因导致执行计划并不是最优。
传统的解决方法可能是更新表的统计信息,或者改一下SQL加一些hint,但这些方法需要修改业务语句。
RDS MySQL提供了SQL Outline,可以在线干预SQL查询计划的制作过程。
它的功能与hint类似,但是不需要改应用上SQL语句,可以直接通过下方这些命令,把相应的功能加进去,主要是针对一些业务不方便在线改动SQL的场景。
灵活的接口设计和持久化保证
6. Concurrency Control
如果我们在某个短时间段之内频繁更新某一行或几行数据后,默认情况以事务锁的并发机制来控制并发,这种模式的排队调度机制会对系统造成较大的额外开销。
但是如果我们能识别出这些语句,让这些语句排队执行,那么这方面的调度开销就可以完全消除。
RDS MySQL控制SQL并发是通过添加规则的方式,这样不需要改用户语句,直接就把这个规则打上去,然后运行的时候,它会自动识别这些规则,并把这些规则应用上去。
方便快捷查看并发控制规则和运行情况
(三)安全性保证
1. Transparent Data Encryption
数据安全性主要是针对数据隐私,概念上就是透明加密的功能。
在RDS MySQL中,用户可以上传自己密钥到阿里云平台,密钥由用户自己管理,而不是由阿里云生成。
2. Recycle Bin
Recycle Bin表示回收站/垃圾站。
- Recycle Bin 设计
1)Drop / Truncate 对象自动回收
2)回收站对象支持 restore 还原
3)回收站可灵活设置保留时常
4)主备间可设置不同的保留周期
Recycle Bin 操作
3. Flashback Query
FlashBack Query 快速找回数据
当遇到误操作删除数据、不带 Where 条件的更新、业务回档、多语句忘记显式开启事务等情况,在历史数据还在的情况下,可以通过Flashback Query迅速把数据库的状态恢复到之前的某一个时间点。
(四)性能提升
1. Binlog In Redo
在MySQL带Binlog事务提交的过程中,数据落盘有两次,Redo一次,Binlog一次。在高并发压力较大的情况之下,这两个Sink对IO的负载比较大,造成性能瓶颈。
优化方案是把Binlog的Sink省略掉,这会带来一个问题,Binlog表如果不能保证及时落盘的话,最终这个数据一致性是是得不到保证的。
我们在写Redo的时候,把Binlog的内容同时写到Redo里面,然后再Sink Redo,这样就能够保证只Sink一次Redo,Binlog的数据还是安全的。如果不是高可用模式的话,Binlog和Redo不需要开双翼,在不影响性能和数据可靠性的前提之下,可以保证数据的安全性。
上图为测试指标,可以看到在16和32并发的时候,性能提升非常明显。
2. Faster Query cache
Query cache是语句级别的结果集缓存,可以理解为一条SQL过来,如果它之前已经跑过了,结果还在,我们就可以直接返回。
社区版之前有Query cache的功能,在这基础之上我们做了几个方面的优策略调整:
- 并发控制
调整前:全局锁机制
调整后:无锁 Hash
- 内存管理
调整前:内存预分配
调整后:内存灵活分配
- 缓存机制
调整前:全路径访问和置换
调整后:自适应访问和置换
由于这个功能会占用一定内存,因此系统默认不开启。如果用户的业务是读写平均或者读操作较多,可以在控制台开启这项功能。
3. Logical Row ID
当InnoDB建一张表时,如果不指定组件,那么它的数据会通过Binlog复制到备库,之后回放的时候是进行全标扫描,导致性能很差。
InnoDB索引组织方式是一个索引组织表,即使没有指定组件,它里面还是会自动生成一个Row ID。以这个Row ID作为Key来组织加速,但是Row ID并没有在Binlog里面把Row ID的信息传到Slave,Row ID只是一个节点内部的一个信息,只是用来组织自己的数据,主备节点之间没有关系,我们没办法利用这个Row ID来当做组件来加速日志的回放。
我们优化的主要思路就是把Row ID通过Binlog带到备库,备库再去回放的时候,Row ID就可以理解为是一个PK。
目前RDS MySQL在线上的实例非常多,在上线这个功能的时候,需要兼容已有的实例,这个功能上线之后,对所有的新数据都可生效,对老数据可以自动跳过去,然后进行兼容。
(五)企业级三节点
企业级三节点模式在电商行业中应用非常广泛,因为电商对数据是丢失零容忍的态度。
在主备模式之下,主备之间如果是以同步方式或半同步方式进行日志同步,当遇到备节点故障,如果复制方式不降为异步的话,主节点也不能写,否则可能造成主备数据不一致。
这个问题的根本原因是如果只有两个节点,当一个节点故障,那么另一个节点肯定也不能写了。所以一个很直观的想法就是再加节点,假如加三个节点,当这三个节点中的多数派已经写进去了,那么整个集群还是可以工作的,在保证数据不丢失的情况下,还要尽可能保证集群的可用性。
这种模式抽象出来就是,有三个节点,三个节点是通过一次性协议来维护节点之间的角色和状态,然后再进行日志的分发,在保证数据不丢失的情况之下,最大可能性的保证集团集群的可用性。
在电商行业,节点数可能大于三,这些节点部署在不同的地点,这种配置方式非常灵活,当一个节点故障,其他节点可以提供不间断的服务,从而保证业务正常运行。