TPCC测试究竟意味着什么

本文涉及的产品
云原生数据库 PolarDB 分布式版,标准版 2核8GB
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
简介: 最近分布式数据库领域可谓非常之火(也可能是非常之卷),特别的,很多人会关注TPCC的测试结果,也有不少产品会投入很多精力在TPCC的优化上。我们首先需要搞明白的是,我们从TPCC的测试结果,究竟能得出对这个分布式数据库什么样的评价。

最近分布式数据库领域可谓非常之火(也可能是非常之卷),特别的,很多人会关注TPCC的测试结果,也有不少产品会投入很多精力在TPCC的优化上。

我们首先需要搞明白的是,我们从TPCC的测试结果,究竟能得出对这个分布式数据库什么样的评价。

TPCC代表了什么

undefined

TPCC的业务场景其实很简单,本文中我们关注其中几个重要的概念即可:

  1. 仓库(Warehouse),有很多的仓库,每个仓库有很多的商品(Item),每个商品在每个仓库有自己的库存数目。仓的数目很多,比如一般测试都是1000仓起步(这个与一些电商平台是不一样的,例如淘宝,核心单元可能就个位数)。
  2. 买家(Customer),绝大多数情况下,买家只会从绑定的一个仓库买东西;少数情况下,买家才会从其他仓库买东西

基于这样的业务特征,所以在数据库的设计上,很容易想到将数据库按照仓库的ID(wid)进行分片。这种分片可以确保大多数的事务可以在单个分片内完成。

例如假设我们有这样一份TPCC的测试报告:

  • TPMC:100,000,000(1亿)
  • 数据库使用机器:222台(Intel Xeon Platinum 8163,42C84T712G)
  • Transaction Mix Percent Number

    • New-Order 45%

      • Percentage of Home order-lines 99.000%
      • Percentage of Remote order-lines 1.000%,每个订单有10个商品,所以有10%的下单涉及到分布式事务
    • Payment 43%

      • Percentage of Home Transactions 85%
      • Percentage of Remote Transactions 15%
    • Order-Status 4%
    • Delivery 4%
    • Stock-Level 4%

我们可以做如下的解读:

  1. TPMC就是指每分钟下单(New-Order)的数量。是一般情况大家最关注的指标,也是TPCC官方进行性能排名使用的指标。
  2. 下单和支付(Payment)两种事务的数量,占了总事务量的45%+43%=88%。
  3. 90%的下单操作是单机事务,85%的支付操作是单机事务,分布式事务合计占比45%*10%+43%*15%=11%。整个集群分布式事务的TPS是:100,000,000*11%/60=18万TPS
  4. 按机器数做下平均,每台机器贡献的单机TPMC是1亿/222*89%=40万,分布式TPMC是1亿/222*11%=5万,加起来是45W

可以看出,TPCC中,TPMC指标中最大头是单机事务贡献的。但是,这种单机事务其实是无法体现分布式特有的一些问题的,例如,节点之间无需互相传递数据,也无需对事务的状态进行协调等。

这里的第一个结论是,TPCC可以很好的体现一个数据库的单机性能,但是它无法很好的体现一个分布式数据库的分布式事务能力(性能、扩展性,甚至在一些不严格的测试中,连一致性也无法验证)

如果真的像TPCC一样,严格控制分布式事务的使用,对业务来说代表了什么?

代表业务永远都要去考虑分区键这个东西,只有业务能划出很统一的分区键,才能尽可能的去减少分布式事务。

无论一个分布式数据库号称多么“先进”,只要它需要你去设计分区键,那其实它就是个“伪”分布式数据库。使用这样的数据库,和使用分库分表中间件+单机数据库没有太明显的区别。

事实上,分库分表中间件+单机数据库除了这11%的分布式事务无法实现,TPCC的其他指标诸如性能、扩展性都能做的很好。只要加足够多的机器,一样能跑到很高的TPMC,这个过程会是非常线性的。只是那11%的分布式事务,阻止了分库分表+单机数据库的方案。

这里的第二个结论是,如果你的业务愿意像使用中间件“谨慎并良好的设计每个表的分区键,避免分布式事务”一样去使用分布式数据库,那么每台机器承载的TPMC(上例中的45万)是很好的参考依据,集群的总TPMC(上例中的1亿)并没有太大的参考价值

如果要看单机TPMC,我们可以与一些传统单机数据库做下对比,其单机能达到的TPMC是什么样的水平呢,我们找几份数据看一下。

  • 数据1:

这一份对官方的PG11做的测试(https://developer.aliyun.com/article/698138),在类似的机器配置中,可以跑到103W的TPMC。

  • 数据2:

TPCC官方榜单上有很多单机数据库的数据,其TPMC普遍在百万级以上(甚至是十多年前的古董级CPU)。

这样看起来非常巨大的数字(1亿TPMC),比较下来,除了机器规模着实吓人之外,和中间件+单机数据库比似乎并没有什么优势。更别说,为了提升TPMC,通常还会使用存储过程来封装TPCC的事务,而这种用法对一般业务来说侵入性太强,很少场景会使用。

也许你会说,还有11%的分布式事务呢,这是中间件+单机的方案解决不了的。

这里的问题是,11%的分布式事务一定代表着强依赖分区键,我想,大多数业务应该不想总是要想着分区键的概念吧,因为这个东西实在太难选了。

诚然,TPCC的模型对分区键的选择是非常非常友好的,每个主要(ITEM\WAREHOUSE\CUSTOMER\ORDER)的表都能按照WAREHOUSE ID进行分区。但在实际的业务中,你会发现情况远比这个复杂的多,比如:

  1. 很多电商系统的订单表会有两个查询维度,卖家和买家,选哪个当分区键?
  2. 做社保系统,缴费表按照人的id和按照企业的id去查都很常见,选哪个当分区键?
  3. 有一堆的业务代码需要去改,在SQL里带上分区键,这怎么改?

...

自然,我们想知道,什么样的技术,才能让你“忘掉”分区键这个东西呢。

二级索引与分区键

广义的“分区键”的概念,其实并不是分布式数据库特有的。

我们在单机数据库中,例如MySQL中,数据存储成了一棵一棵B树。如果一个表只有主键,那它只有一棵B树,例如:

CREATE TABLE orders(
    id int,
    seller_id int,
    buyer_id int,
    primary key (id)
);

这个表唯一的B树是按照主键(id)进行排序的。如果我们的查询条件中带了id的等值条件例如where id=1,那么就可以在这棵树上快速的定位到这个id对应的记录在哪里;反之,则要进行全表扫描。

B树用于排序的Key,通过二分查找可以定位到一个叶子节点;分区键通过哈希或者Range上的二分查找,可以定位到一个分片。可以看出它们都是为了能快速的定位到数据。

如果我们要对上面的表做where seller_id=1来查询,在MySQL中,我们并不需要将seller_id设为主键。更加自然的方式是,在seller_id上创建一个二级索引:

CREATE INDEX idx_seller_id ON orders (seller_id);

每个二级索引在MySQL中都是一棵独立的B Tree,其用于排序的Key就是二级索引的列。

也就是说,当前t1这张表,有两颗B Tree了,主键一棵,idx_seller_id一棵,分别是:

id->seller_id,buyer_id
seller_id->id

当使用where seller_id=1进行查询是,会先访问idx_seller_id这颗B树,根据seller_id=1定位到叶子节点,获取到id的值,再使用id的值到主键那颗B树上,找到完整的记录。

二级索引实际上是通过冗余数据,使用空间与提升写入的成本,换取了查询的性能。

同时,二级索引的维护代价并不是非常的高,一般情况下可以放心的在一个表上创建若干个二级索引。

同理,在分布式数据库中,想让你“忘掉”分区键这个东西,唯一的方法就是使用分布式二级索引,也称为全局索引(Global Index)。并且这个全局索引需要做到高效、廉价、与传统二级索引的兼容度高。

全局二级索引

我们在数据分布解读(一)中介绍过全局索引:

Global Index,也称为全局索引,由一组同构的Partition构成。
Global Index包含两种类型的字段,Key字段与Covering字段,Key字段为索引字段,其余字段为Covering字段。
Global Index有Partition Key与分区算法两个属性,其Partition Key是Global Index的Key字段。
......
对于Key字段的查询,CN可以直接定位到对应的Partition。

全局二级索引同样也是一种数据冗余。例如,当执行一条SQL:

INSERT INTO orders (id,seller_id,buyer_id) VALUES (1,99,1000);

如果orders表上有seller_id这个全局二级索引,可以简单理解为,我们会分别往主键与seller_id两个全局索引中执行这个insert,一共写入两条记录:

INSERT INTO orders (id,seller_id,buyer_id) VALUES (1,99,1000);
INSERT INTO idx_seller_id (id,seller_id) VALUES (1,99);

其中orders主键索引的分区键是id,idx_seller_id的分区键是seller_id。

同时,由于这两条记录大概率不会在一个DN上,为了保证这两条记录的一致性,我们需要把这两次写入封装到一个分布式事务内(这与单机数据库中,二级索引通过单机事务来写入是类似的)。

当我们所有的DML操作都通过分布式事务来对全局索引进行维护,我们的二级索引和主键索引就能够一直保持一致的状态了。

好像全局索引听起来也很简单?

实则不然,一个可以广泛使用的全局索引,以下条件缺一不可,不然只能是个玩具。

索引的强一致性、高性能与分布式事务

索引一定要是强一致的,例如:

  • 不能写索引表失败了,但是写主表成功了,导致索引表中缺数据
  • 同一时刻去读索引表与主表,看到的记录应该是一样的,不能读到一边已提交,一边未提交的结果
    ...

这里对索引的一致性要求,实际上就是对分布式事务的要求。

由于全局索引的引入,100%的事务都会是分布式事务,对分布式事务的要求和“强依赖分区键类型的分布式数据库”完全不同了,要求变得更高:

  1. 至少需要做到SNAPSHOT ISOLATION以上的隔离级别,不然行为和单机MySQL差异会很大,会有非常大的数据一致性风险。目前常见的方案是HLC、TrueTime、TSO、GTM方案,如果某数据库没有使用这些技术,则需要仔细甄别。
  2. 100%的分布式事务相比TPCC模型10%的分布式事务,对性能的要求更高,HLC、TSO、TrueTime方案都能做到比较大的事务容量,相对而言,GTM由于更重,其上限要远远低于同为单点方案的TSO(TSO虽然是单点,但由于有Grouping的优化,容量可以做的很大)。
  3. 即使用了TSO/HLC等方案,优化也要到位,例如典型的1PC、Async Commit等优化。不然维护索引增加的响应时间会很难接受。

与单机索引的兼容性

单机数据库中,索引有一些看起来非常自然的行为,也是需要去兼容的。

例如:

  • 能通过DDL语句直接创建索引,而不是需要各种各样的周边工具来完成。
  • 前缀查询,单机数据库中,索引是可以很好的支持前缀查询的,全局索引应该如何去解这类问题?
  • 热点问题(Big Key问题),单机数据库中,如果一个索引选择度不高(例如在性别上创建了索引),除了稍微有些浪费资源外,不会有什么太严重的问题;但是对于分布式数据库,这个选择度低的索引会变成一个热点,导致整个集群的部分热点节点成为整个系统的瓶颈。全局索引需要有相应的方法去解决此类问题。

面向索引选择的查询优化器

我们知道,数据库的优化器核心工作机制在于:

  1. 枚举可能的执行计划
  2. 找到这些执行计划中代价最低的

例如一个SQL中涉及三张表,在只考虑左深树的情况下:

  • 在没有全局索引的时候,可以简单理解为,执行计划的空间主要体现在这三张表的JOIN的顺序,其空间大小大致为3x2x1=6。执行计划的空间相对是较小的,优化器判断这6个执行计划的代价也会容易很多。(当然优化器还有很多工作,例如分区裁剪等等,这些优化有没有索引都要做,就不多说了)。
  • 在有全局索引的时候,情况就复杂多了。假设每个表都有3个全局索引,那执行计划空间的大小大致会变成(3x3)x(2x3)x(1x3)=162,这个复杂度会急剧的上升。相应的,对优化器的要求就会高的多。优化器需要考虑更多的统计信息,才能选择出更优的执行计划;需要做更多的剪枝,才能在更短的时间内完成查询优化。

所以我们可以看到,在没有全局索引的“分布式数据库”或者一些中间件产品中,其优化器是很羸弱的,大多是RBO的,它们根本就不需要一个强大的优化器,更多的优化内容实际上被单机优化器给替代了。

其他

索引的创建速度,索引回表的性能,索引的功能上的限制,聚簇索引,索引的存储成本等等,其实也都极大的影响了全局索引的使用体验,这里鉴于篇幅原因,就不继续展开了。

索引的数量

对全局索引的这些要求,本质来源于全局索引的数量。

透明性做的好的数据库,所有索引都会是全局索引,其全局索引的数量会非常的多(正如单机数据库中一个表一个库的二级索引数量一样)。数量多了,要求才会变高。

而,这些没有全做好的分布式数据库,即使有全局索引,你会发现它们给出的用法依然会是强依赖分区键的用法。

它们会让创建全局索引这件事,变成一个可选的、特别的事情。这样业务在使用全局索引的时候会变的非常慎重。自然,全局索引的数量会变成的非常有限。

当全局索引的数量与使用场景被严格限制之后,上述做的不好的缺点也就变得没那么重要了。

PolarDB-X的透明分布式

PolarDB-X实现了非常优秀的分布式事务与全局索引,满足上文提到了对全局索引的要求,做到了透明分布式。

在透明分布式模式下(CREATE DATABASE中指定mode='auto'),所有的索引都是全局索引,应用无需关心分区键的概念。

例如,我们的建表语句,与单机MySQL完全一致,并不需要指定分区键:

create table orders (
   id bigint, 
   buyer_id varchar(128) comment '买家', 
   seller_id varchar(128) comment '卖家',
   primary key(id),
   index sdx(seller_id),
   index bdx(buyer_id)
)

undefined

创建全局索引也与单机MySQL创建二级索引的体验一致,全程是Online的:

CREATE INDEX idx_seller_id ON orders (seller_id);

PolarDB-X的全局索引是强一致的,其数据一致性体验与单机MySQL没有明显差异,提供了符合MySQL语义的RC与RR的隔离级别。

同时,PolarDB-X在索引的维护、优化器上也做了大量的工作,确保索引能高效的创建、维护,优化器能正确的生成使用索引的执行计划。

PolarDB-X的分区算法,也能很好的处理索引中产生的热点、数据倾斜等问题,参考:https://yuque.antfin.com/coronadb/kaswnf/ixsvfi

结语

我们的结论是:

  • TPCC的业务逻辑非常契合分库分表的架构,90%的事务是单机事务。对于TPCC的测试结果,建议更多的关注其平均到每台机器的TPMC。
  • 使用全局索引的数据库,才有可能做到真正的透明;没有全局索引的数据库,和分库分表没有本质区别,都要应用自己去设计分区键。
  • 全局索引的写入必然是分布式事务,对分布式事务的性能、一致性有很高的要求。对于一个透明的分布式数据库,100%的事务都是分布式事务。
  • 全局索引的数量很关键,透明的分布式数据库,所有索引都是全局索引,数量会非常多。

需要指定分区键的分布式数据库在五六年前还是比较流行的,但在现代,透明分布式是一个合格的分布式数据库必须提供的能力。

它能够极大的减轻应用的迁移成本,例如不需要修改应用中的SQL带上分区键,不需要为每个表都设计一个分区键等;同时,也能极大的减轻开发人员的学习成本,让开发人员能将精力集中在满足业务需求上,例如,可以沿用使用单机数据库时SQL优化的经验,通过加索引的手段去改善SQL的执行性能。

相关实践学习
快速体验PolarDB开源数据库
本实验环境已内置PostgreSQL数据库以及PolarDB开源数据库:PolarDB PostgreSQL版和PolarDB分布式版,支持一键拉起使用,方便各位开发者学习使用。
目录
相关文章
|
OceanBase 存储 数据库
蚂蚁金服OceanBase挑战TPCC | TPC-C基准测试之存储优化
OceanBase的TPC-C测试技术解读第五篇
3497 0
蚂蚁金服OceanBase挑战TPCC | TPC-C基准测试之存储优化
|
OceanBase 数据库 存储
|
存储 数据库 SQL
蚂蚁金服OceanBase挑战TPCC | TPC-C基准测试之SQL优化
蚂蚁金服自研数据库 OceanBase 登顶 TPC-C 引起业内广泛关注,为了更清楚的展示其中的技术细节,我们特意邀请 OceanBase 核心研发人员对本次测试进行技术解读。
1636 0
蚂蚁金服OceanBase挑战TPCC | TPC-C基准测试之SQL优化
|
数据库 OceanBase 测试技术
蚂蚁金服OceanBase挑战TPCC | 测试流程解析
蚂蚁金服自研数据库 OceanBase 登顶 TPC-C 引起业内广泛关注,为了更清楚的展示其中的技术细节,我们特意邀请 OceanBase 核心研发人员对本次测试进行技术解读。
6007 0
蚂蚁金服OceanBase挑战TPCC | 测试流程解析
|
OceanBase SQL 数据库
蚂蚁金服OceanBase挑战TPCC丨TPC-C基准测试之链路层优化
本篇文章是 OceanBase 的 TPC-C 测试技术解读的最后一篇,为方便阅读,我们将系列文章整理成PDF电子书发布在“蚂蚁金服科技”官方公众号上。
3002 0
|
弹性计算 关系型数据库 测试技术
PostgreSQL 11 1Kw TPCC , 1亿 TPCB 7*24 强压耐久测试
标签 PostgreSQL , tpcc , tpcb 背景 TPCC, TPCB是工业标准的OLTP类型业务的数据库测试,包含大量的读、写、更新、删除操作。 7*24小时强压耐久测试,主要看数据库在长时间最大压力下的 性能、稳定性、可靠性。
2259 0
|
弹性计算 关系型数据库 测试技术
PostgreSQL 11 1000亿 tpcb、1000W tpcc 性能测试 - on 阿里云ECS + ESSD (含quorum based 0丢失多副本配置与性能测试)
标签 PostgreSQL , pgbench , tpcb , tpcc , tpch 背景 https://help.aliyun.com/knowledge_detail/64950.html 阿里云ESSD提供了单盘32TB容量,100万IOPS,4GB/s读写吞吐的能力,单台ECS可以挂载16块ESSD盘,组成512 TB的大容量存储。
3154 0
|
弹性计算 关系型数据库 测试技术
PostgreSQL 11 tpcc 测试(103万tpmC on ECS) - use sysbench-tpcc by Percona-Lab
标签 PostgreSQL , tpcc 背景 环境 阿里云虚拟机 [root@pg11-test ~]# lscpu Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: ...
4379 0
|
弹性计算 关系型数据库 测试技术
|
27天前
|
JSON 算法 数据可视化
测试专项笔记(一): 通过算法能力接口返回的检测结果完成相关指标的计算(目标检测)
这篇文章是关于如何通过算法接口返回的目标检测结果来计算性能指标的笔记。它涵盖了任务描述、指标分析(包括TP、FP、FN、TN、精准率和召回率),接口处理,数据集处理,以及如何使用实用工具进行文件操作和数据可视化。文章还提供了一些Python代码示例,用于处理图像文件、转换数据格式以及计算目标检测的性能指标。
52 0
测试专项笔记(一): 通过算法能力接口返回的检测结果完成相关指标的计算(目标检测)
下一篇
无影云桌面