简单生活

  • 一直都在非常深度调研、关注和使用云数据库,其中性能是关注的重点之一。一方面性能是最终成本的重要影响因素,更好的性能,通常意味着使用更少的资源支撑更高的业务量,从而降低整体成本。另外,性能还意味着在极端场景下,数据库的上限支撑能力。

    所以,近期对各个云数据库厂商做了一个较为系统的性能对比,供开发者和企业在云数据库选型时的参考。

    在进行大量测试之后,对主要的云厂商分别选择了一个“企业级规格”(适合生产环境配置的)进行了对比。先看性能对比如下图:

    可以看到:

    • 华为云数据库(红色),在中高并发度时(>=16),性能最强,且高于第二名约18%;
    • 腾讯云数据库(紫色),在低并发时(<=8),性能最强,高于第二名约15%;
    • 百度云数据库(淡蓝色),在中高并发时(>16),性能跃居第二,仅次于华为云;
    • 阿里云数据库(黄色)和谷歌云数据库(绿色)在低并发时也都有不错的表现,高并发之后性能则持续稳定在850 tps。这两家云数据库的响应延迟,表现得也非常接近。
    • 亚马逊云数据库(Amazon RDS,蓝色)和微软Azure云在中低并发时,表现出了较为相近的性能趋势,且性能较低。但是在高并发时,两者都表现出了非常强的扩展性,AWS RDS在96和128并发时,性能超过阿里云、腾讯云、谷歌云等,跃居第三;同样的,微软Azure云的数据库在高并发时也超过了阿里云、谷歌云,也有不错的性能表现。
    (more…)
  • 这是一个云数据库性能的系列文章,包含了:

    在前篇中(参考),较为详细的对比x86和Graviton 2(AWS推出第二代ARM芯片)的性能。Graviton 3实例在今年的4月份支持了RDS数据库(参考)。这里,我们再系统的看看m7g实例(Graviton 3)、m6g实例(Graviton 2)、m5实例(Intel Xeon)、m6i实例(第三代Intel Xeon/Ice Lake)的RDS性能(包括性价比)表现如何。

    测试结论

    参考下图。整体上,在中低并发时,m6i实例(第三代Intel Xeon/Ice Lake)、m5实例(Intel Xeon)性能要比m7g实例(Graviton 3)、m6i实例(第三代Intel Xeon/Ice Lake)实例要略微高一些。即,低并发时,x86实例性能要高出约10%

    在超高并发的时候性能表现:m7g实例 > m6i实例 > m6g实例 ~ m5实例。在超高并发下,m7g、m6i实例表现出了非常强的扩展性和吞吐量,m7g实例吞吐量最高,甚至高出m6i实例10%;相比m6g、m5实例,m7g实例性能则要高出30%

    为了更加直观对比性价比,这里选取了16并发的性能进行对比。m7g实例在16并发下,tps为314,价格为$0.936/小时;m6i实例的tps为336,价格为$0.94/小时。所以,m6i实例(x86)性价比要比m7g实例(Graviton 3)更高,高出约:6%。在超高并发时(128并发),m7g实例(Graviton 3)实例性价比才比m6i实例(x86)要更高,高出约:10%。不过,无论怎样,这与AWS宣称的Graviton实例性价比更高的结论是不一致的。

    测试模型说明

    这里使用了sysbench的读写混合模型(oltp_read_write)进行测试,单表大小为100万,共十个表,单次测试时长为300秒,分别测试了如下的并发度的性能表现:2 4 8 16 24 32 48 64 96 128

    实例配置与价格

    这里关注db.m7g.xlarge、db.m6i.xlarge实例价格,m6g、m5实例的价格可以参考前篇。以东京地区、多可用区实例价格为参考:

    实例配置与之前的测试保持一致。选择了较为常用4c16gb的实例进行测试,各个选项尽量选择默认选项,以更加接近的模拟用户实际场景,具体的,版本是AWS多可用区版、存储默认加密、gp3存储、100GB空间、3000 IOPS、Performance Insight也默认开启。

    详细的测试数据参考

    AWS RDS Graviton 3(db.m7g.xlarge/gp3/100gb/3000iops)

    threads|transactions| queries| time |avg/Latency|95%/Latency
    2|       10847|  216940|300.04|      55.32|     127.81
    4|       25897|  517940|300.00|      46.34|      51.94
    8|       49010|  980200|300.05|      48.97|      55.82
    16|       94335| 1886700|300.05|      50.89|      58.92
    24|      141987| 2839740|300.05|      50.71|      59.99
    32|      185996| 3719920|300.05|      51.62|      62.19
    48|      268264| 5365280|300.05|      53.68|      68.05
    64|      341468| 6829360|300.06|      56.23|      74.46
    96|      446113| 8922260|300.06|      64.56|      92.42
    128|      491663| 9833260|300.09|      78.11|     121.0

    AWS RDS x86(第三代Intel Xeon/Ice Lake)(db.m6i.xlarge/gp3/100gb/3000iops)

    threads|transactions| queries| time |avg/Latency|95%/Latency
    2|       13281|  265620|300.02|      45.18|     112.67
    4|       29635|  592700|300.04|      40.49|      47.47
    8|       53875| 1077500|300.04|      44.55|      53.85
    16|      100785| 2015700|300.07|      47.63|      57.87
    24|      150515| 3010300|300.04|      47.84|      59.99
    32|      193195| 3863900|300.05|      49.69|      63.32
    48|      273454| 5469080|300.08|      52.67|      69.29
    64|      343939| 6878780|300.05|      55.83|      75.82
    96|      408551| 8171020|300.09|      70.50|      99.33
    128|      438708| 8774160|300.06|      87.54|     123.28

    小结

    经过较为详细的测试,可以看到,在RDS数据库的场景下,无论是第二代自研芯片Graviton2,还是第三代Graviton3,相比于x86芯片在性价比上并没有特别明显的优势。而在更加常见的低并发的场景下,x86实例的性价比依旧是更高的。在超高并发时,Graviton3实例虽然表现出了一些性价比优势,但是,如此高的并发,其实在实际应用中,并不常见。

    另外,第三代Graviton3相比第二代Graviton2的性能提升也是非常明显,大概有10~40%的性能提升

    当然,这应该也是符合预期的结论,毕竟在大原则上,处理复杂的负载x86芯片应该更有优势;对简单的场景、更低功耗的场景,Graviton(ARM)芯片是更有优势的。对于数据库来说,涉及到事务处理、磁盘IO、大量的比较判断等,还是比较复杂的。不过,依旧期待未来,Graviton做更多的适配与正对性的优化,以获得更高的性价比,从而降低最终降低使用RDS的成本。

    参考

  • 概述

    在2018年,AWS首次推出Graviton EC2实例,2020年7月AWS RDS正式支持Graviton 2的实例,就在前两天,在最新的AWS re:Invent大会上,AWS已经推出了第四代Graviton 4实例。现在,AWS的Graviton已经较为成熟,也在大量的企业和应用被广泛使用。AWS官方也宣称使用Graviton 2的RDS实例能够有52%的性价比提升(参考)。这里,来通过标准的Sysbench测试来实测一下,看看实际Graviton 2实例的效果。

    与上次阿里云测试相同,这次依旧是使用了同样的测试工具和场景,对较为常用的4c16gb,即db.m6g.xlarge和db.m5.xlarge实例,进行并发数分别为2 4 8 16 24 32 48 64 96 128的测试。

    测试结论

    在性能上,平均来看,x86要比Graviton实例性能高约12.7%;x86规格延迟要比Graviton规格低15%。也注意到,在超高并发的情况下(并发超过96时),Graviton实例与x86实例无论是在性能,还是延迟上,是比较接近的,不过,这时候系统压力太大、延迟太高,对实际使用并没有太大的参考价值。

    为了更加直观的做性价比的比较,这里选取16并发时的数据进行对比。在16并发下,Graviton实例的TPS是275,db.m6g.xlarge价格是$0.836/小时;x86实例的TPS是341,价格是$0.94/小时。那么每100TPS,Graviton价格是0.304,x86是0.275。所以,在16并发时,相比之下,x86规格的性价比更高,高出Graviton实例10%。这个结果与测试之前预期还是非常不一样的,也与AWS宣称的完全不同。

    只有在超高的并发情况下(96/128并发),Graviton实例的吞吐量才与x86接近,这时,Graviton实例才表现出接近10%的性价比优势。但这种高并发在实际场景中并不是常态,所以并没有很强的参考价值。

    这个测试结果与预期的差别比较大,所以后来又再做过一次测试,结果与这次基本相同。所以,性能到底怎样,还是最终要自己实际测试,因为宣传的数据,通常都是非常极端的适配该产品的场景,并不是真实的场景。

    一下两幅图分别是TPS和平均延迟的对比图:

    横坐标是sysbench的并发线程数,纵坐标分别为tps和平均的延迟。

    测试模型说明

    这里使用了sysbench的读写混合模型(oltp_read_write)进行测试,单表大小为100万,共十个表,单次测试时长为300秒,分别测试了如下的并发度的性能表现:2、4、8、10、12、14、16、24、32

    实例配置与价格

    这里选择了较为常用4c16gb的实例进行测试,各个选项尽量选择默认选项,以更加接近的模拟用户实际场景,具体的,版本是AWS默认的8.0.33、多可用区版、存储默认加密、gp3存储、100GB空间、3000 IOPS、Performance Insight也默认开启。完整的选项参考如下:

    AWS的价格分为计算节点价格(CPU与内存)、存储价格、IOPS价格,这里仅关注计算节点价格。存储和IOPS对于ARM和x86实例来说,是相同的。这里的选择的是东京地区、多可用区实例的价格,如下:

    后续,也还将测试基于 io1(Provisioned IOPS SSD) 存储的RDS。

    详细测试数据参考

    AWS RDS Graviton(db.m6g.xlarge/gp3/100gb/3000iops/8.0.33)

    threads|transactions| queries| time |avg/Latency|95%/Latency
          2|       11951|  239020|300.03|      50.21|      55.82
          4|       23322|  466440|300.04|      51.45|      57.87
          8|       43654|  873080|300.05|      54.98|      65.65
         16|       82519| 1650380|300.05|      58.17|      70.55
         24|      120541| 2410820|300.06|      59.74|      73.13
         32|      156680| 3133600|300.07|      61.28|      74.46
         48|      218709| 4374180|300.06|      65.85|      81.48
         64|      269430| 5388600|300.08|      71.27|      90.78
         96|      329366| 6587320|300.07|      87.45|     121.08
        128|      351579| 7031580|300.11|     109.24|     164.45

    AWS x86实例(db.m5.xlarge/gp3/100gb/3000iops/8.0.33)

    threads|transactions| queries| time |avg/Latency|95%/Latency
          2|       13357|  267140|300.03|      44.92|     112.67
          4|       27539|  550780|300.03|      43.57|      50.11
          8|       55330| 1106600|300.04|      43.38|      51.94
         16|      102408| 2048160|300.05|      46.87|      56.84
         24|      145718| 2914360|300.05|      49.41|      61.08
         32|      186619| 3732380|300.05|      51.44|      63.32
         48|      260415| 5208300|300.04|      55.30|      69.29
         64|      306939| 6138780|300.08|      62.56|      82.96
         96|      330131| 6602620|300.09|      87.25|     123.28
        128|      348095| 6961900|300.12|     110.34|     155.80

    小结

    AWS RDS在发布Graviton 2实例时,曾宣传Graviton 2实例有52%的性价比提升。但是在这里的Sysbench混合读写的测试场景下,反而是x86性价比优势更加明显,16并发是,x86性价比要高出Graviton实例10%。而仅是在超高并发时,Graviton实例性价比才比x86高10%。但是,一般我们不会让4c16的实例,运行在如此高的压力下,所以后面这种情况的参考意义并不强。

    虽然AWS曾大量宣传Graviton实例,但是实测下来并没有什么性价比的优势。所以,在数据库应用场景下,使用AWS Graviton实例的必要性,似乎并不高。另外,也注意到,RDS Graviton 3的实例一直都没有推出,也许这是其中的原因之一。

    参考

  • Protected: 最后的一分钟

    ·

    This content is password protected. To view it please enter your password below:

  • This content is password protected. To view it please enter your password below:

  • 概述:mysqldump是MySQL官方自带的备份工具,被广泛使用着。本文详细介绍了如何使用mysqldump获得一个一致的备份,以及可能遇到的一些问题。

    1. 是什么备份的一致性?

    一致性对于备份来说是非常重要的,如果一个备份不具备一致性,那么再恢复之后,可能会让软件出现各种奇怪的问题。我们来详细看看什么是备份的一致性,例如,一个备份流程中,首先耗时一分钟(12:00:00-12:01:00)完成了用户表U表备份,然后继续其他业务表A、B等的备份,于此同时,业务线程开始向用户表U写入新注册用户X的信息,接着,业务线程又向事件表E写入X用户的事件Y信息。接着,备份线程在完成其他业务表之后,开始并完成备份事件表E。

    如果不考虑一致性,在备份事件表E的时候,会记录X用户的事件信息,但是在用户表U中却没有该用户的注册信息,也就出现了不一致的数据。如果事件U表记录的是,企业核心数据,例如账务、计费等信息,恢复这样数据,则难以达到备份与恢复的目的。

    一致性的备份是指,所有备份中的数据,可以对应到数据库在某一时刻的状态。在上面的案例中,就要求,所有备份的数据与用户表U开始备份时刻的数据处于同一个状态。

    2. mysqldump备份的一致性保障方式

    2.1 使用 –lock-tables, -l

    默认情况下,参数–opt是打开的,所以,不加任何相关参数的话,会默认带上参数–lock-tables,该参数,会在备份某个数据库之前,将该数据库的所有的表都加上锁,阻止所有的写入操作,所以,总是可以让单个数据库保持一致的状态。

    2.2 使用–lock-all-tables, -x

    另一个加锁的参数是–lock-all-tables, -x,与–lock-tables差别在于,该参数是在备份任务开始时,将需要备份的所有数据库的所有表,都加上锁,阻止所有的写入操作,所以,使用该参数,就可以获得整个实例级别的一致性,而–lock-tables参数是可以获得单个数据库级别的一致性。当然,如果你的实例中,数据库数量非常多,而且关联性并不大,则还是应该尽量使用-l参数,避免加锁时间过长。

    2.3 使用最常用 –single-transaction

    –single-transaction参数应该是mysqldump备份中最有用的参数了。对于InnoDB表,使用该参数一方面可以获得一致性的数据,另一方面,也不需要在备份期间持续的对数据库进行加锁操作。

    一般来说,使用了该参数,就可以获得一个一致的备份,并且在备份过程中,无需阻塞读取或者写入操作。

    3. 使用–single-transaction的一些例外情况

    因为MySQL两层架构设计,导致了Server层和引擎层在很多功能上并不能很好的契合。在使用–single-transaction参数备份时,如果数据库层正在执行某些DDL,那么还是可能会出现不一致。

    在mysqldump的文档中也明确提到,如果在mysqldump执行过程中,数据库上执行了ALTER TABLE, CREATE TABLE, DROP TABLE, RENAME TABLE, TRUNCATE TABLE等DDL,还是会有不一致出现。因为文档写得比较简单,而一致性又是一个比较大的问题,所以,这里详细探讨一下这种情况。

    3.1 –single-transaction备份时,如果有ALTER TABLE,数据是否还一致?

    在备份的过程中,如果有部分表执行了ALTER TABLE操作,这部分表是否还可以正常备份呢?这样的备份是否有一致性?

    简单的回答,在使用–single-transaction参数备份时,如果执行了ALTER TABLE,并且该操作属于COPY(或INPLACE)类型,那么可能会导致备份数据出现错误,事实上,可能会导致,该表中的数据无法被备份出来。

    这是一个mysqldump的限制。因为与MySQL事务、DDL实现机制、InnoDB事务机制都有较深的关系,所以,并不容易绕过,这个问题的底层原因在很早就已经在Bug系统中汇报了,但是一直都没有好的、彻底的修复策略,参考:MySQL Bug#28432。当然,也可能是修复的代价太高,而收益比较小。

    从原理上,简单的来说,当对InnoDB表做DDL操作时,而且该DDL是一个COPY类型的(ALGORITHM为COPY的时候),MySQL会先对该表加上一个全局的锁,不允许任何的写操作,然后新建好一个临时表(新的结构),然后将原表中的数据拷贝到新的临时表中,完成拷贝之后,然后再将原表删除,并将新的临时表重命名为原表。在这个过程中,所有新拷贝的数据都使用新的事务ID,而原表的数据又被删除了。所以,在这个DDL之前开始的事务,都不再能够读取DDL之后的新表的数据,即便这个新表的数据本身并没有被其他任何事务修改。从事务一致性的角度来看,这应该是不可以被接受的,使用了Repeatable Read隔离级别的事务,在某个时刻开始之后,能够读取的数据,应该总是一致的。所以,也比较明确,这就是MySQL的一个已知的限制。

    3.2 ALTER语句的ALGORITHM到底是COPY、INPLACE,还是INSTANT呢?

    那么一个ALTER TABLE语句的DDL到底是COPY、INPLACE,还是INSTANT呢?这个问题没有一个简单答案,也不再本文的讨论范围之内,详细内容可以参考:

    另外,因为INSTANT是8.0版本才引入的,所以,5.7的版本要么是COPY、要么是INPLACE。

    3.3 延伸说明,ALTER语句对于事务隔离性的破坏

    某些ALTER语句执行时,是会破坏事务的隔离性的。这里也做了一个简单的测试验证:

    在上面的例子中可以看到,如果在实际的备份中,先备份t_b,而另一个线程对t_a进行了ALTER操作的DDL(注:并且是ALGORITHM为COPY)时,备份线程再读取t_a的数据,就会失败,在实际的mysqludmp备份中,就只能备份t_a的表结构(show create table可以执行,且显示的是新的表结构),但无法备份该表的数据。

    3.4 –single-transaction与其他DDL语句

    除了ALTER语句之外,其他还有CREATE TABLE, DROP TABLE, RENAME TABLE, TRUNCATE TABLE等语法,都会破坏InnoDB RR隔离级别下的一致性,所以也都会有类似的问题。这些DDL相比ALTER要更简单一些(没有ALGORITHM选项),如果在mysqldump执行过程中执行这些DDL(如果是上面示例中的顺序),也会有类似的不一致问题,这里就不再详述。

    3.5 –single-transaction与FLUSH TABLES WITH READ LOCK

    mysqldump在–single-transaction和–master-data(–source-data)结合使用的时候,会通过FTWRL命令将数据库锁住,并获取全局的、一致的日志位点。但是,因为MySQL的设计原因,FTWRL比较容易导致数据库阻塞,尤其是数据库的负载比较大的时候,参考:

    所以,如果备份发生在主库,且负载比较大,则会有一定概率阻塞数据库,导致服务不可用。

    4. 小结

    虽然,说了这么多问题。但是,总体上mysqldump和–single-transaction组合起来用,通常都能够帮助你获得一份有效的、一致的备份。

    但是,如果你是负责一个大型系统(数据库非常多)的备份,数据库实例的数量非常多,开发人员也非常多,那么虽然概率小,但依旧一定会遇上这些情况。希望本文能够帮助你理解这种现象,以及尽量避免这种情况的发生。例如,可以考虑在备库/副本上备份,或者使用Xtrabackup的物理备份作为补充等。