PolarDB auto_inc 场景性能优化之路

本文涉及的产品
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
简介: 在数据库的使用场景中, 最常见的场景是并发插入或者导入数据场景, 在该场景中并不指定自增id, 由数据库自动生成自增id, 然后插入到数据库中, 因此我们也叫auto_inc 场景的数据插入.典型的业务场景如: 游戏行业开服过程中的大批的登录注册场景, 电商活动中给商家后台推单场景等等.我们看看PolarDB 是如何优化针对这种并发插入场景进行优化的.背景知识:在这种并发

在数据库的使用场景中, 最常见的场景是并发插入或者导入数据场景, 在该场景中并不指定自增id, 由数据库自动生成自增id, 然后插入到数据库中, 因此我们也叫auto_inc 场景的数据插入.

典型的业务场景如: 游戏行业开服过程中的大批的登录注册场景, 电商活动中给商家后台推单场景等等.

我们看看PolarDB 是如何优化针对这种并发插入场景进行优化的.

背景知识:

在这种并发插入场景中, 自增id 是递增的, 因此插入的时候其实是插入到btree 最右边的Page 中去的.

直观感受上这种场景是插入到btree 最右一个page, 真的是这样么?

其实不是, 这种场景并不能保证插入数据是连续的, 因此有可能要插入的值比最右Page 最小值小, 插入右边第2个page. 因此这种场景其实是插入最右的多个page.

原因是thread 获得auto_inc 值以后, 到真正进行insert 这一段代码并没有加锁, 因此thread 获得auto_inc 以后被调度走, 反而后面获得auto_inc thread 先进行最后的insert 操作.

所以这样的场景是允许出现的: 并发Insert 时, 后续有可能插入比当前 auto_inc value 小的行

因为这个原因允许Level 0 存在多个page 同时进行插入情况, 允许我们有性能优化的空间. 否则仅仅插入最右page, 就相当于排队对最右Page 进行插入, 没有优化空间.

因此会出现以下场景

image-20230312042949995

在上图中, 此时有3个thread 进行乐观插入, 插入的value 14, 25, 36. 那么此时可以持有各自page x lock, 实现3 个page 同时并发插入.

如果thread = 1, 那么只有最右page 进行插入, 性能一定是不如3个page 同时并发插入来得好.

理论上允许同时插入的leaf page 越多, 并发越高, 性能越好.

那么如果实现允许同时插入的leaf page 越多呢?

尽早进行SMO 操作, 最右Page 尽早分裂, 那么就有更多未被插满的Page 允许用户同时进行插入

所以接下来我们的优化点就是

尽早进行SMO 操作

尽早进行SMO 操作

尽早进行SMO 操作

那么在并发插入场景中, InnoDB 中实际情况是怎样的?

image-20230312043008614

在我们测试中, 发现可能存在因为调度问题造成auto_inc 差值差不多能够造成同时3~4 个page 允许同时插入, 上图也是这样的初始场景.

阶段1: 当前有3个thread 分别乐观插入到3个不同的level 0 leaf page 中, 并持有3个 leaf page x lock. 同时还有N 个thread 持有Level 1 page s lock, 等待在level 0 leaf page x lock 上, 即等当前3 个thread 完成插入以后N 个thread再进行插入.

阶段2: 此时SMO thread 要进行悲观插入, 持有index sx lock 和 Level 2 page x lock, 等待在持有Level 1 Page 的x lock 上, 但当前Level 1 page 上面已经有N 个乐观插入持有page s lock 在等待

阶段3: SMO thread 需要等待之前N 个乐观插入thread完成以后(这里最右Page 的乐观插入大概率是失败, 因为这次SMO 操作就是为了做最右Page 的SMO, 那么乐观插入失败以后会转换成悲观插入), 获得了Level 1 Page x lock, 然后再等待Level 0 leaf page 上的X lock 以后, 完成加锁操作然后进行SMO 操作, SMO 完成.

这里可以看到SMO thread 需要等待N 个Thread 完成乐观插入尝试以后, 才可以进行SMO 操作, 并发度越高, 乐观插入thread 越多, 那么SMO thread 等待的时间越长, SMO 越不能尽早执行, 导致性能无法提升.

那么为什么限制了Innodb_thread_concurrency 以后, 可以获得更好的性能呢?

从上面的分析可以看到, 其实在auto_inc 场景, 允许并发插入的page 并不多, 差不多只有3~4 个page 允许同时插入, 过多的线程会导致SMO 线程必须等这些乐观插入线程插入尝试完成以后才能进行插入, 乐观插入thread 越多, 等待的时间越长. 最理想的情况是此时最右Page 上没有乐观插入在等待, 那么SMO thread 可以不需要等待任何thread, 实现了尽早进行SMO 操作 这个目标. 而限制了Innodb_thread_concurrency 相当于限制了这里乐观插入thread 数目, 因此实现了更好的性能.

实际测试中Innodb_thread_concurrency = 8 就可以几乎最好的性能了.

1678689543197-aa2a84c1-7296-4b91-af05-40dd12c93940

那么Blink-tree 如何改进这种情况呢?

我们分析现有InnoDB Btree 版本存在的问题的时候提出解决方案通过设置 Innodb_thread_concurrency = 8 来降低并发进入到InnoDB thread num 从而保证高性能的插入, 但是Innodb_thread_concurrency = 8 太低, 正常系统使用的过程中还有查询操作, 因此实际上很少会进行这样的设置, 那么Blink-tree 最后是如何实现允许大量并发线程并能够实现高性能auto_inc 插入呢?

  1. Blink-tree 天然允许SMO 并发, 现有InnoDB Btree 同一时刻只能允许一个SMO 进行, 允许了SMO 并发执行相当于尽早进行SMO 操作
  2. 增加了SMO thread 还不够, 如果SMO thread 和上述InnoDB btree 实现一样, 需要等待乐观插入完成才能进行SMO 操作, 那么其实多个SMO 操作也是串行的, 仅仅增加一点提前执行SMO 的时间.

    因此我们在Blink-tree 上实现锁的优先级调度, 从而实现尽早进行SMO 操作.

    在上述阶段3 中SMO thread 需要和乐观插入thread 去争抢执行优先级, 导致SMO thread 执行效率不高. 通过锁的优先级调度, 给SMO thread 最高优先级, 先唤醒等待在Page x lock 上的SMO thread, 然后再唤醒等待在address lock 上的乐观insert thread, 从而实现尽早进行SMO 操作

具体实现方式如下图所示:

image-20230312051344937

Blink-tree 通过Lock coupling 进行加锁, 即使在悲观插入场景中, 对Level 1 依然是 S lock.

阶段1: 当前有3个SMO thread 正在并发进行SMO. 因为Blink-tree 实现SMO 和Btree 类似, 需要持有中右page lock, 因此只有SMO 1 能够执行, 而SMO 2/SMO 3 等待在右Page Xlock 上.

阶段2: 有N thread 尝试进行乐观插入操作, 乐观插入的时候发现Page 1/2/3 都在进行SMO 操作, 只有Page 4 没有, 因此想插入Page 1/2/3 threads 放弃当前Page s lock, 等待在Page 1/2/3 的address lock 上. 想插入Page 4 thread 等在Page 4 x lock 上.

阶段3: SMO 1 执行完成SMO, 通知SMO 2 进行, 然后唤醒等待在Page 1 address lock 上的乐观插入thread, 由于SMO 2 还在进行中, 持有Page 1 X lock, 因此乐观插入thread 需要等SMO 2执行结束才可以执行. 等SMO 2执行结束通知SMO 3执行, 同时唤醒等待在Page 2 address lock 上的乐观插入, 但是由于SMO 3正在进行中, 持有Page 2 X lock, 因此乐观插入Page 2 因为SMO 3 持有Page 2 X lock, 是无法进行的. 但是此时对Page 1 乐观插入已经可以进行了.最后等SMO 3 也完成, Page 2/3 的乐观插入也就可以进行了

可以看到blink-tree 通过增加并发SMO thread 同时引入锁的优先级调度从而实现尽早进行SMO 操作. 从而实现比InnoDB Btree 更高的性能.

这里其实还有一个与InnoDB Btree 实现的区别, 等待在address 唤醒之后的乐观插入 thread 执行的依然是乐观插入操作, 而InnoDB Btree 在等待Page lock 被唤醒之后执行的是悲观插入操作. 悲观插入加锁的范围广开销大, 因此性能进一步退化.

具体测试场景的数据如下:

img

总结:

可以看到在Blink-tree 场景中. 在并发auto_inc场景中, Blink-tree 是官方Btree版本的2倍, 同时比开启 Innodb_thread_concurrency 也有13% 左右提升.

那么Bw-tree 如何改进这种情况呢?

看下一篇文章...

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
2月前
|
存储 SQL 安全
应用案例|开源 PolarDB-X 在互联网安全场景的应用实践
中盾集团采用PolarDB-X云原生分布式数据库开源版本,有效解决了大数据量处理、复杂查询以及历史数据维护等难题,实现了业务的高效扩展与优化。
|
3月前
|
关系型数据库 MySQL 分布式数据库
PolarDB MySQL多场景评测
本次评测将围绕指定场景中的灵活弹性和无感秒切展开,对于自选场景中的安全和DB+AI也进行了简单体验。
221 3
PolarDB MySQL多场景评测
|
2月前
|
关系型数据库 MySQL 分布式数据库
【开发者评测】PolarDB MySQL场景评测获奖名单公布
PolarDB MySQL场景评测获奖名单公布!!
|
3月前
|
存储 算法 Cloud Native
【PolarDB-X列存魔法】揭秘TPC-H测试背后的性能优化秘籍!
【8月更文挑战第25天】阿里巴巴的云原生数据库PolarDB-X以其出色的性能、可靠性和扩展性闻名,在多种业务场景中广泛应用。尤其在列存储模式下,PolarDB-X针对分析型查询进行了优化,显著提升了数据读取效率。本文通过TPC-H基准测试探讨PolarDB-X列存执行计划的优化策略,包括高效数据扫描、专用查询算法以及动态调整执行计划等功能,以满足复杂查询的需求并提高数据分析性能。
98 1
|
3月前
|
关系型数据库 MySQL Serverless
PolarDB MySQL Serverless:灵活弹性场景深度评测
本文深入评测了阿里云PolarDB MySQL Serverless的灵活弹性场景。作为阿里云专业运维工程师,笔者从多个角度对产品进行了全面分析: 产品特性:介绍了PolarDB MySQL Serverless的核心优势,包括动态弹性、高可用性和按量付费模式。 操作体验:详细描述了集群创建过程和控制台监控功能,突出了其简化运维的特点。 弹性能力:通过三个测试场景验证了产品在不同负载下的自动扩缩容能力,展示了其快速响应和性能稳定性。 API与文档:评估了API的易用性和文档的完整性,并提出了改进建议。 优劣分析:总结了产品的主要优势,如极致弹性和成本效益,同时指出了一些潜在的改进空间。 整体
|
3月前
|
存储 关系型数据库 MySQL
再探PolarDB —— PolarDB MySQL 四大场景下的全方位评测
本文全面评测了阿里云PolarDB MySQL在四大关键场景下的表现:Serverless极致弹性、列存索引(IMCI)、弹性并行查询(ePQ)以及无感秒切高可用。通过官方提供的免费体验资源,我们深入了解了PolarDB MySQL的核心能力和性能。Serverless极致弹性列存索引(IMCI弹性并行查询(ePQ)无感秒切高可用此外,文章还介绍了PolarDB MySQL在数据备份和HTAP(混合事务/分析处理)场景下的优势,包括灵活的备份策略、高效的全量和库表恢复方式,以及通过IMCI支持的HTAP能力。这些特性共同构成了PolarDB MySQL作为一款先进的云数据库服务的强大竞争力。
|
3月前
|
存储 关系型数据库 大数据
PolarDB 大数据处理能力及其应用场景
【8月更文第27天】随着数据量的爆炸性增长,传统的数据库系统面临着存储和处理大规模数据集的挑战。阿里云的 PolarDB 是一种兼容 MySQL、PostgreSQL 和高度可扩展的关系型数据库服务,它通过其独特的架构设计,能够有效地支持海量数据的存储和查询需求。
101 0
|
4月前
|
人工智能 关系型数据库 MySQL
探索和体验云原生数据库PolarDB MySQL版在AI场景中的应用
探索和体验云原生数据库PolarDB MySQL版在AI场景中的应用
181 0
|
1月前
|
关系型数据库 MySQL 分布式数据库
零基础教你用云数据库PolarDB搭建企业网站,完成就送桌面收纳桶!
零基础教你用云数据库PolarDB搭建企业网站,完成就送桌面收纳桶,邀请好友完成更有机会获得​小米Watch S3、小米体重称​等诸多好礼!
零基础教你用云数据库PolarDB搭建企业网站,完成就送桌面收纳桶!
|
2月前
|
关系型数据库 MySQL Serverless
探索PolarDB MySQL版:Serverless数据库的灵活性与性能
本文介绍了个人开发者对阿里云PolarDB MySQL版,特别是其Serverless特性的详细评测体验。评测涵盖了产品初体验、性能观测、Serverless特性深度评测及成本效益分析等方面。尽管试用过程中遇到一些小问题,但总体而言,PolarDB MySQL版表现出色,提供了高性能、高可用性和灵活的资源管理,是个人开发者和企业用户的优秀选择。
下一篇
无影云桌面