本人接触互联网也有差不多10个年头,从个人的博客、商城、电商、教育、淘宝客等,手里大大小小的项目也不在少数,接触过的技术栈也是比较多,从.net、php、java、go、python等都有涉猎,接触的规模也是逐渐由小到大,从简单的单机应用部署到SOA架构,再到目前公司业务的K8S集群,助力企业降本增效是每个公司都在倡导的,公司专门还发起了“提案改善”的降本增效活动,号召大家一起助力企业降本增效。
通过这次《TDSQL-C MySQL Serverless助力企业降本增效》的直播学习,可以了解TDSQL-C是如何实现超百万 QPS 的高吞吐、PB 级海量分布式智能存储、Serverless 秒级伸缩。希望可以借此找到契机,为公司的业务助力企业降本增效,同时也是感谢陈老师的精彩分享。
本文将从四个方面进行TDSQL-C MySQL Serverless的探讨,通过观看老师的讲解,结合自我的认知,来分析TDSQL-C MySQL Serverless如何来进行助力企业降本增效。
主要探讨的内容:
传统意义的Serverless是一种云服务提供的方式,是Faas + Baas的一种服务形态。
开发人员可以将其代码简单的打包部署在无服务器,最大化利用云的弹性可扩展性构建自己的应用程序。
传统的企业在进行数字化转型的同时,要将以前的单体式应用进行微服务化。然而,这波未平、下波技术的热潮又来了,现在各大云厂商如腾讯云都在投入重大精力去做serverless(无服务器)服务,云计算正在经历从IAAS —> PAAS —> SAAS —> BAAS&FAAS的过渡。
云数据库也是经过了三个时代的发展,到现在的Serverless数据库可以提供了自动弹性能力、更智能化的运维,极致的成本优化方案,备受大家的关注。
同时,《全球Serverless架构市场》报告预计全球Serverless架构市场的规模预计到2024年将达到140亿美元,市场的前景非常广阔。
目前公司也是在停留在云原生数据库时代,如下为本人负责的产品线所使用的MySQL主从实例的样本。
先思考一下,传统云数据库存在哪些问题点呢?使用Serverless能够解决哪些业务的痛点呢?
传统的云数据库一般是计算和存储往往都在一台单机服务器实例上,因此很难按照等比例的方式去使用数据库,因为计算的比例和存储的比例可能是任何组合方式:
总结来看,传统的云数据库很难做到Serverless的特性,因为很难做到一个弹性伸缩的能力,因为两种资源类型都是在同一台物理机上,可以看到存算一体的架构很容易造成很大的资源浪费和产生碎片。
主从同步是通过Binlog去进行主从的数据同步,延迟也会很高,横向扩展机器的耗时也会更长。
主要原因有以下几点:
TDSQL-C Serverless是采用TDSQL-C云原生数据库的底座,最大的特点就是做了存算分离,资源不是在同一台物理机上。同时,使用的是Redo log的方式去同步,极大的降低了Binlog主从同步延迟概率的情况。
可以很好的进行Serverless化,Serverless化的特点就是哪部分资源不够,就加哪部分资源。
各行各业都在力求提高自己的敏捷性,以便更快的创新和响应变化。企业需要更快速的构建应用程序、快速扩展、支持百万用户、服务全球毫秒级响应,并且能够处理产生的 PB 甚至 EB 级的数据,最后还要支持业务的三高特性(高弹性、高需求和高可用),企业在构建这些应用时会面临一系列的挑战。
TDSQL-C提供了两种形态的产品:
不兼容MySQL5.6,老版本的客户需要注意一下。
TDSQL-C MySQL 版(TDSQL-C for MySQL)是腾讯云自研的新一代云原生关系型数据库。融合了传统数据库、云计算与新硬件技术的优势,为用户提供具备高弹性、高性能、海量存储、安全可靠的数据库服务。TDSQL-C MySQL 版100%兼容 MySQL 5.7、8.0。实现超百万级 QPS 的高吞吐,最高 PB 级智能存储,保障数据安全可靠。
TDSQL-C MySQL 版采用存储和计算分离的架构,所有计算节点共享一份数据,提供秒级的配置升降级、秒级的故障恢复,单节点可支持百万级 QPS,自动维护数据和备份,最高以GB/秒的速度并行回档。
TDSQL-C MySQL 版为用户提供具备超高弹性、高性能、海量存储、安全可靠的数据库服务,可帮助企业轻松应对诸如商品订单等高频交易、伴随流量洪峰的快速增长业务、游戏业务、历史订单等大数据量低频查询、金融数据安全相关、开发测试、成本敏感等的业务场景。
TDSQL-C Serverless架构独特的亮点:
增加了一个恢复感知器,用来保证实例在暂停后能快速去恢复起来。同时,保证首连是不断的。
购买一台TDSQL-C MySQL 5.7 Serverless的数据库实例,实例形态一定要选择“Serverless”,这里选择“北京三区”的主可用区。
下面会讲到Serverless的集群版本,所以,这里选择Serverless的“集群版本”,算力配置读写实例最小是0.25,最大是8的CCU,只读节点也是相同的配置。计费模式的话,计算节点和存储节点都选择按量计费模式。
填写完一些参数值后,就可以实例化一台Serverless的数据库实例出来了。
开启读写实例与只读实例的外网访问权限。
开启完读写实例与只读实例的外网访问权限,就会得到对应的主机名和端口号。
购买一台测试使用的4核8G云服务器用于mysql连接时间和sysbench压测场景。
安装MySQL数据库。
wget https://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022 yum -y install mysql-server
# 暂停服务器后,触发Serverless读写实例服务器自动启动 time mysql -h bj-cynosdbmysql-grp-2bgu5xfe.sql.tencentcdb.com -P24637 -uroot -pxxxx < sql.sql # Serverless读写实例服务器启动后,查看连接时间 time mysql -h bj-cynosdbmysql-grp-2bgu5xfe.sql.tencentcdb.com -P24637 -uroot -pxxxx < sql.sql
当暂停Serverless服务器后,使用mysql连接的方式,去触发Serverless读写实例服务器自动启动,可以看到花了1.215s就完成了自动启动。再次连接花了0.047s,表示后续的连接也是可以正常使用的。
# 暂停服务器后,触发Serverless只读实例服务器自动启动 time mysql -h bj-cynosdbmysql-grp-qny06yxq.sql.tencentcdb.com -P20835 -uroot -pxxxx < sql.sql # Serverless只读实例服务器启动后,查看连接时间 time mysql -h bj-cynosdbmysql-grp-qny06yxq.sql.tencentcdb.com -P20835 -uroot -pxxxx < sql.sql
当暂停Serverless服务器后,使用mysql连接的方式,去触发Serverless只读实例服务器自动启动,可以看到花了5.906s就完成了自动启动,这个要比读写实例要花费更久的时间,再次连接花了0.043s,表示后续的连接也是可以正常使用的。
当暂停Serverless服务器后,开启2个终端工具,分别使用mysql连接的方式,同时去触发Serverless读写实例服务器自动启动。
可以看到2个终端都触发了Serverless自动启动功能,前者使用了1.269s就完成了自动启动,后者使用了1.016s完成了自动启动,这样可以表示,自动启动是可以并发去完成的。也可以防止在项目中因为并发启动而导致问题。
当暂停Serverless服务器后,开启2个终端工具,分别使用mysql连接的方式,同时去触发Serverless只读实例服务器自动启动。
可以看到2个终端都触发了Serverless自动启动功能,前者使用了5.939s就完成了自动启动,后者使用了5.618s完成了自动启动,这样可以表示,自动启动是可以并发去完成的。也可以防止在项目中因为并发启动而导致问题。
当暂停Serverless服务器后,马上进行多次mysql的连接,看看TDSQL-C MySQL Serverless是会马上自动启动吗?
当暂停Serverless服务器后,马上执行第一个mysql进行连接,可以看到第一个窗口执行了0.040s,第二个窗口执行了2.694s,说明在第一次时,还是走的接入层,而第二次是服务器暂停后,马上处罚了自动启动功能,走的是恢复感知器。
在暂停Serverless服务器时,多点击几次会有一个报错提示。
大部分常见的Serverless厂商的弹性方案,在创建的时候,提前给一个标识好的规格,当负载的瓶颈达到一定预设置的值后,再将触发分配第二个阶段的规格的实例,这样做会存在很大的弊端:
TDSQL-C Serverless采用资源最大化提供,提前把资源最大的规格上限提供,这部分资源都预置给用户:
总结,TDSQL-C Serverless会把资源最大化的提供给用户,瞬时能够做到满载,更像是“事前弹性”的弹性方式。
集群级Serverless一主多从的架构,资源细粒度更高,各节点可独立弹性:
集群级Serverless一主多从的架构,数据库proxy代理能够进行读写分离,进行负载均衡:
举个数据库proxy代理的场景:
需要注意的是,只读节点是不能写入数据。
sysbench --db-driver=mysql --mysql-host=bj-cynosdbmysql-grp-2bgu5xfe.sql.tencentcdb.com --mysql-port=24637 --mysql-user=root --mysql-password=xxxx --mysql-db=sysbench_db --table_size=20000 --tables=200 oltp_write_only prepare sysbench --db-driver=mysql --mysql-host=bj-cynosdbmysql-grp-2bgu5xfe.sql.tencentcdb.com --mysql-port=24637 --mysql-user=root --mysql-password=xxxx --mysql-db=sysbench_db --table_size=20000 --tables=200 --events=0 --time=600 --threads=500 --percentile=95 --report-interval=1 oltp_write_only run sysbench --db-driver=mysql --mysql-host=bj-cynosdbmysql-grp-2bgu5xfe.sql.tencentcdb.com --mysql-port=24637 --mysql-user=root --mysql-password=xxxx --mysql-db=sysbench_db --table_size=20000 --tables=200 oltp_write_only cleanup
准备造需要的数据。
测试的时候,遇到报错:Too many connections
在TDSQL-C MySQL Serverless控制台的参数设置中,找到“max_connections”值,并将其由80改为100000。
接着测试中又发现报错:Can’t create more than max_prepared_stmt_count statements(current value: 16382),修改“max_prepared_stmt_count”参数,由16382改为1048576。
清理测试数据。
这里需要说明一下,写入测试数据是在读写库,但是测试在只读库。
sysbench --db-driver=mysql --mysql-host=bj-cynosdbmysql-grp-2bgu5xfe.sql.tencentcdb.com --mysql-port=24637 --mysql-user=root --mysql-password=xxxx --mysql-db=sysbench_db --table_size=20000 --tables=200 oltp_read_only prepare sysbench --db-driver=mysql --mysql-host=bj-cynosdbmysql-grp-qny06yxq.sql.tencentcdb.com --mysql-port=20835 --mysql-user=root --mysql-password=xxxx --mysql-db=sysbench_db --table_size=20000 --tables=200 --events=0 --time=600 --threads=500 --percentile=95 --range_selects=0 --skip-trx=1 --report-interval=1 oltp_read_only run sysbench --db-driver=mysql --mysql-host=bj-cynosdbmysql-grp-qny06yxq.sql.tencentcdb.com --mysql-port=20835 --mysql-user=root --mysql-password=xxxx --mysql-db=sysbench_db --table_size=20000 --tables=200 oltp_read_only cleanup
只读库测试的时候,发现又出现了Too many connections,难道读写库和只读库是2套参数配置吗?
在参数设置中,确实能看到有2套的参数设置,同理,找到“max_connections”值,并将其由80改为100000。修改“max_prepared_stmt_count”参数,由16382改为1048576。
如果想要看读写库与只读库共同的折线图,可以多选2种实例即可。
sysbench --db-driver=mysql --mysql-host=bj-cynosdbmysql-grp-2bgu5xfe.sql.tencentcdb.com --mysql-port=24637 --mysql-user=root --mysql-password=xxxx --mysql-db=sysbench_db --table_size=20000 --tables=200 oltp_read_write prepare sysbench --db-driver=mysql --mysql-host=bj-cynosdbmysql-grp-2bgu5xfe.sql.tencentcdb.com --mysql-port=24637 --mysql-user=root --mysql-password=xxxx --mysql-db=sysbench_db --table_size=20000 --tables=200 --events=0 --time=600 --range_selects=0 --threads=500 --percentile=95 --report-interval=1 oltp_read_write run sysbench --db-driver=mysql --mysql-host=bj-cynosdbmysql-grp-2bgu5xfe.sql.tencentcdb.com --mysql-port=24637 --mysql-user=root --mysql-password=xxxx --mysql-db=sysbench_db --table_size=20000 --tables=200 oltp_read_write cleanup
sysbench --db-driver=mysql --mysql-host=bj-cynosdbmysql-grp-2bgu5xfe.sql.tencentcdb.com --mysql-port=24637 --mysql-user=root --mysql-password=txy123.. --mysql-db=sysbench_db --table_size=20000 --tables=150 oltp_read_write prepare sysbench --db-driver=mysql --mysql-host=bj-cynosdbmysql-grp-2bgu5xfe.sql.tencentcdb.com --mysql-port=24637 --mysql-user=root --mysql-password=txy123.. --mysql-db=sysbench_db --table_size=20000 --tables=150 --events=0 --time=600 --threads=500 --percentile=95 --report-interval=1 oltp_read_write run sysbench --db-driver=mysql --mysql-host=bj-cynosdbmysql-grp-2bgu5xfe.sql.tencentcdb.com --mysql-port=24637 --mysql-user=root --mysql-password=txy123.. --mysql-db=sysbench_db --table_size=20000 --tables=150 oltp_read_write cleanup
首先在不用实例的时候,会对实例做一个暂停的动作,当使用的时候,再把实例拉起来,这就是恢复感知器的作用,对外官宣用户首连登录成功时长是小于2000ms的。
在之前使用的过程中,发现一个问题,对性能要求比较高的客户,在使用的过程中,在缩容过程中,会发现毛刺,这里指的是超过100ms的慢查询。
在扩缩容的过程中,主要发现有3个瓶颈:
IO的瓶颈的解决方案:
MUTEX锁如何优化?
全局锁瓶颈如何优化?
通过以上的几种方式,现在毛刺的数量是下降到100%,整个缩容过程中,也不会存在毛刺的现象。
计费的模式:
CCU的付费模式提供2种:
对比同规格包年包月刊例价最高降低25%,资源包的方式也是为了福利企业和用户使用的计费方式。
以下为在整个测试过程中,所产生的费用,也是根据你的弹性CCU来计算的,当然还有存储的费用。
从上面的账单可以发现一个规律,所有的存储费用是产生在读写实例上,只读库可以共享数据。读写库和只读库都是分别单独进行费用收费的。
当然,也可以像前面提到的购买资源包的方式来进行绑定到实例上,可以近一步的节省费用。
很多业内不使用就不收费,去帮助用户降低成本,都是去降低计算节点的成本。
现在对于腾讯云来说,当实例暂停之后,也是在收取用户的存储费用,下一步,真的要做serverless化的话,不仅要降低计算成本,不使用不收计算的费用,同时,存储的费用也应该尽可能的压缩,包括做到极尽不去收用户的钱。
这部分是在的底部架构做了一个归档存储池,现在都是用共享分布式存储池,采用删副本形式。
这种方式能够保证当实例暂停之后,数据都能及时做一个归档,这样可以进一步尽量去压缩存储成本,经过计算归档存储成本最高可降低80%的存储费用。
有低频访问的业务,个人博客、论坛、微信小程序、云开发、微信云托管,这部分是低频访问,不需要去购买一个比较大的规格放在那里,有可能平时都不怎么使用,Serverless很适合低频访问的业务场景。
其次,就是开发测试环境,这部分场景有很大的共性,比如周一至周五工作时间使用,周未包括下班时间不使用,针对这一部分,就可以不使用不收费,对Serverless也是很好的应用场景。
再者,就是活动类的场景,比如说一些大促,这种活动或游戏突然会成为一个暴品,不及时进行一个低延扩容操作,很有可能导致负载跟不上,节点直接就打爆,serverless本身具有自动弹性的能力,所以,无需关心提前做一个扩容的能力,同时,也不需要为额外的资源去进行付费,当高负载来了之后,可以立马瞬时的弹到一个比较大的规格,这部分是很适合活动类的场景。
如果做微信开发,包括微信小程序,对微信云托管比较熟悉,微信云托管现在采用MySQL的数据库,就是TDSQL-C Serverless所支撑的,目前已经为接近50万小程序开发者提供了一站式开发云服务,使用Serverless云服务器的方式,能够即使即用,能够快速的去使用,快速的去分配数据库资源,发布的速度也很快,如果实际体验微信云托管资源的话,如果想要使用数据库的话,可以他的创建资源时间差不多在2s内,就可以立马帮你分配一个数据库实例。
另外一个腾讯乐享平台,是一个社区平台,很大的特点就是因为大部分的用户都是比较小的客户,可能用的规格最大也不会超过1核2G,在这样的规格下面,如果给每个用户都去分配一个实例的话,导致资源浪费特别严重,而且还有很多僵尸实例,他们就采用把所有用户都归纳到一个实例上面去,通过不同的用户去访问不同的库,去做这样的一个访问,但是这样会导致很差的隔离性,同时,也会有安全性的危险,使用Serverless可以很好的去帮助乐享平台解决针对很多小用户,不经常使用的业务场景,帮助腾讯乐享降低成本80%以上。
在之前的公司(因为是外包需要快速出活的原因),接触了微信云托管的应用,当时,记得最大的特点就是开箱即用、按量来收费,非常适合个人和中小型业务公司来使用,比较意外的是,原来云数据也是可以按量来收费,目前接触的公司业务都是包年来购买的。