PolarDB Serverless弹性能力

PolarDB Serverless是将SIGMOD 2021的论文中成熟的技术最终产品化的结果。借助于全局一致性(高性能模式)无感秒切两大核心技术,无论在跨机扩展还是跨机切换能力方面,都达到了较高水平。本文从实践角度出发,来演示如何测试PolarDB Serverless的弹性能力。

前提条件

已创建ECS实例。建议ECS实例与Serverless集群位于同一地域和可用区。

说明

本测试使用的ECS实例规格为16核64 GB(ecs.g7.4xlarge)。

购买与配置PolarDB集群

PolarDB的Serverless有以下两种形态:

  • Serverless集群:指创建一个新的Serverless集群,从头开始使用Serverless功能。有更大的弹性范围,所有资源完全按Serverless弹性计费。

  • 固定规格集群的Serverless:指在已经创建的普通集群上开启Serverless功能。收费内容包括固定规格费用和弹性费用。

购买集群

本文直接使用Serverless集群进行测试,集群的基础配置如下:

  • 地域:华北2(北京)

  • 数据库引擎PolarDB MySQL版8.0.1

  • 主可用区:华北2 可用区K

以上是新购Serverless集群的一些关键选项,创建集群大约耗时5~10分钟。集群购买成功后,进入PolarDB控制台,集群的系列会显示为集群版(Serverless)。购买Serverless集群的详细操作步骤,请参见创建Serverless集群

说明
  • 只读节点个数伸缩上下限和单节点伸缩上下限在集群创建后可以随时动态修改。因此,创建集群时可以任意选择。

  • 创建Serverless集群时默认会创建数据库代理,数据库代理也会以Serverless形态运行,弹性范围为0.5~32 PCU,随着实际负载动态调整。

  • 无活动暂停功能面向的业务类型比较少。当负载降低时,一般情况下Serverless会降配到最低1 PCU运行。如果在创建Serverless集群时开启了无活动暂停功能,且请求量完全降为0时,集群会自动进入暂停状态以释放资源。如果后续有新的请求接入,需要等待集群快速启动后再发送到数据库执行。

配置白名单

在白名单中配置ECS实例的地址。配置白名单的详细操作步骤请参见设置白名单

创建数据库账号

创建测试使用的数据库账号polartest。创建数据库账号的详细操作步骤请参见创建和管理数据库账号

创建数据库

创建测试使用的数据库sbtest。创建数据库的详细操作步骤请参见创建数据库

扩缩测试

数据准备

测试开始之前,需要为sbtest库准备数据。该测试选择了128张表,每张表1000000行数据。数据准备过程中可能会造成集群规格弹升,所以数据准备完成后建议等待1分钟,直到主节点降回1 PCU后再进行压测。

-- threads不同的线程数可以构造不同的负载,以xxx为例
sysbench /usr/share/sysbench/oltp_read_write.lua --mysql-host=http://xxxx.rwlb.rds.aliyuncs.com --mysql-port=3306 --mysql-user=xxxx --mysql-password=xxxx --mysql-db=sbtest --tables=128 --table-size=1000000 --report-interval=1 --range_selects=1 --db-ps-mode=disable --rand-type=uniform --threads=xxx --time=12000 prepare

请将本命令和后续步骤命令中的XXX替换为PolarDB MySQL版集群的集群地址、端口号、用户名和密码。具体参数说明如下,更多性能测试请参见性能测试方法(OLTP)

参数

说明

--mysql-host

PolarDB MySQL版集群的集群地址。

--mysql-port

PolarDB MySQL版集群的端口号。

--mysql-user

PolarDB MySQL版集群的用户名。

--mysql-password

上述用户名对应的密码。

单节点纵向扩缩测试(Scale-up)

该测试通过Sysbench压测,来验证主节点的规格能够根据负载进行自动伸缩,达到Serverless能力。

Serverless配置

登录PolarDB控制台设置Serverless配置参数页面,将单节点资源弹升上限设置为32,单节点弹升资源下限设置为1,只读节点个数扩展上限只读节点个数扩展下限均设置为0。设置Serverless配置参数详细操作步骤请参见设置Serverless集群资源扩缩策略

image.png

Sysbench压测命令

Sysbench压测使用的命令如下,该测试使用oltp_read_write模式。

-- threads不同的线程数可以构造不同的负载,以xxx为例
sysbench /usr/share/sysbench/oltp_read_write.lua --mysql-host=http://xxxx.rwlb.rds.aliyuncs.com --mysql-port=3306 --mysql-user=xxxx --mysql-password=xxxx --mysql-db=sbtest --tables=128 --table-size=1000000 --report-interval=1 --range_selects=1 --db-ps-mode=disable --rand-type=uniform --threads=xxx --time=12000 run

其中,mysql-host的值需配置为集群地址,并配置--db-ps-mode=disable以确保所有的事务SQL以原始SQL语句的方式执行。

测试结果

首先,简单测试一下16个线程的测试效果。从Sysbench的输出来看,在并发数量固定为16的负载下,随着时间的推移,吞吐量TPS逐步增加,延迟LAT逐步降低,最终达到一个稳定值。这说明PolarDB Serverless触发弹性后,性能获得了提升。

image.png

登录PolarDB控制台性能监控页面可以看到集群页签中展示了Serverless监控指标项。时间范围选择最近的5分钟,可以看到如下监控信息,查看性能监控指标的详细操作步骤请参见查看性能监控指标

image.png

PCU数量从1弹升到5,并保持稳定。在弹升过程中,CPU的使用率随着资源的扩容而逐步降低。内存使用率曲线中每次弹升会有脉冲形状。这是因为每次PCU增加,内存资源会进行扩容,此时的内存使用率会瞬间降低。之后数据库开始利用扩充的内存资源提高计算能力(比如Buffer Pool),因此内存使用率会逐步增加,最终达到一个稳定状态。

停止Sysbench压测,稍等一段时间,再调整合适的时间范围,刷新后的监控信息如下:

image.png

从监控信息中可以看出。随着压力的停止,PCU数量从5逐步阶梯式地降低至1。CPU使用率瞬间降为接近0。由于读写混合测试包含UPDATE请求,当压力停止后,PolarDB还会继续执行purge undo操作。因此,还会占用微量的CPU。再观察内存使用率,每次缩容内存使用率会立即降低,然后再升高一个台阶。这是因为PolarDB缩容之前,会首先调小内存相关参数(如Buffer Pool、Table Open Cache等)来触发回收缓存,故使用率会立刻降低。参数调整完成后,确保内存资源已经被释放,才会真正调小容器的Mem规格,当Mem上限调小后,相当于分母变小,计算出来的内存使用率则会上升。

尝试增加Sysbench压力,将线程数量调整为128个,查看PolarDB弹升到最大规格32 PCU的时间。

image.png

从Sysbench输出可以明显看出TPS和LAT的变化。同样地,压测一段时间后停止Sysbench测试,PCU也会自动缩容。从1 PCU弹升至32 PCU耗时大约需要42秒。缩容相比扩容稍显平缓,耗时大约220秒。

image.png

多节点横向扩缩测试(Scale-out)

PolarDB借助SCC技术实现了全局一致性(高性能模式),可以实现跨节点无损读扩展。Serverless集群会在所有弹出只读节点上默认开启SCC。传统的MySQL主备一写多读集群的只读节点存在Binlog复制延迟问题,一般不转发TP业务的读操作,仅服务报表这类对全局一致性不敏感的业务。同时,由于Binlog复制只会同步已提交事务的日志,只读节点无法处理事务中的写后读。

PolarDB的SCC通过提交事务时间戳技术CTS与事务状态RDMA保持同步,实现低延迟的只读节点读扩展。同时,SCC加上Proxy的高级事务拆分技术,使得跨事务、事务前和事务中的写后读请求都可以轻松扩展到PolarDB的只读节点,且保证全局一致性。最终主节点省下来的资源就可以支持更多的写请求。借助于SCC技术,PolarDB Serverless使用唯一的集群地址访问集群,用户不会受到跨节点的读一致性的问题困扰,即用户无需关心请求是由主节点直接执行,还是被转发到只读节点执行。

Serverless配置

登录PolarDB控制台设置Serverless配置参数页面,将单节点资源弹升上限设置为32,单节点弹升资源下限设置为1,只读节点个数扩展上限设置为7,只读节点个数扩展下限设置为0。设置Serverless配置参数详细操作步骤请参见设置Serverless集群资源扩缩策略

image.png

Sysbench压测命令

Sysbench压测使用的命令如下,该测试使用oltp_read_write模式。

-- threads不同的线程数可以构造不同的负载,以xxx为例
sysbench /usr/share/sysbench/oltp_read_write.lua --mysql-host=http://xxxx.rwlb.rds.aliyuncs.com --mysql-port=3306 --mysql-user=xxxx --mysql-password=xxxx --mysql-db=sbtest --tables=128 --table-size=1000000 --report-interval=1 --range_selects=1 --db-ps-mode=disable --rand-type=uniform --threads=128 --time=12000 run

其中,mysql-host的值需配置为集群地址,并配置--db-ps-mode=disable以确保所有的事务SQL以原始SQL语句的方式执行。

确保主节点在之前的测试结束后已经降至1 PCU,重新发起和扩缩测试一样的Sysbench压力,即使用128个线程进行oltp_read_write压测。

测试结果

登录PolarDB控制台在目标集群的基本信息页面的数据库节点区域,可以看到,在压力执行一段时间后,系统开始自动创建只读节点。

image.png

一段时间后进入稳定状态,系统不再继续创建只读节点。

image.png

进入稳定状态后,Sysbench的输出如下:

image.png

对比之前单节点同压力的测试结果,性能略有下降,QPS从34~35w下降到32~33w。

查看性能监控中的Serverless监控指标项,可以看到类似如下的曲线,查看性能监控指标的详细操作步骤请参见查看性能监控指标

image.png

主节点很快弹升至32 PCU,只读节点创建出来后,开始承担一部分读负载,主节点CPU使用率下降,PCU缩容。由于弹出的只读节点的CPU使用率没有超过弹性阈值的80%,因此,在该压力下只会扩容一个只读节点。

将并发数量增大到2倍,停止Sysbench压力,立即执行256个线程的并发oltp_read_write。等待一段时间,会发现系统开始大量弹出新的只读节点。

image.png

同时查看Sysbench的输出,oltp_read_write的性能也有大幅提升,QPS从32~33w上升至44~46w,从QPS上已经突破了单节点弹性测试的最大吞吐量。这说明成功验证了Serverless scale-out的效果。

image.png

查看Serverless监控信息,会看到存在多个只读节点的曲线。且当新的只读节点弹出后,先前的节点就会逐步降低负载,最终达到一个大致的均衡,这说明Proxy成功将负载均衡到新弹出的只读节点中。由于目前Serverless为了避免频繁的规格震荡,弹升弹降的阈值是一个大区间,同时降配对性能也存在一定的负反馈,因此Proxy很难做到100%的均衡,先降配的PCU最终值会偏低。

image.png

运行一段时间后,停止Sysbench,PolarDB的计算节点首先会自动缩容,大约1~2分钟会逐步降至1 PCU。压力停止之后,只读节点的CPU使用率会立刻降低,而主节点还需要执行purge undo操作,CPU消耗会持续一小段时间,最终降到1 PCU。如果等待较长一段时间,新增的只读节点也会在15~20分钟内逐步回收。为了避免只读节点频繁的弹性震荡,Serverless没有选择立即回收无负载的只读节点。

image.png