比如秒杀场景下,运行端优化的外围理路普通分为如下几步:
从下面的流程来看,数据库是承载了最外围的数据分歧性保证。只管在业务端会做比拟多的流控,但为了偏心起见还是会有超越现有库存的并发恳求瞬间流入到数据库中,要求数据库在满足在高并发下也能保证库存扣减不出现正数(出现超卖)。针对繁多商品的秒杀促销,极速、频繁降级此商品的库存值,这件商品的数据行咱们就称为"热点行"。
由于数据库在操作数据行时会加锁,大并发的降级操作造成行锁争抢,形成线程沉积,不可处置新的恳求,数据库成为业务链路中的瓶颈点后,会造成整个业务出现雪崩,数据库解体等重大疑问。
PolarDB-X联合了阿里团体多年的双十一阅历,设计了针对热点行降级的优化打算,以处置此类促锁场景下的热点行降级疑问,本文重要引见下PolarDB-X中允许热点行的优化思绪和基本经常使用。
当咱们购置商品时,一种或许的下单逻辑如下,开启事务后,首先在订单表中拔出一条购置记载,随后在库存表中对该商品启动降级操作,最后审核降级后的结果,假设所有反常,则启动提交,否则启动回滚。
商品依照降级的频率不同,全体可以分为两类:抢手商品和非抢手商品,关于抢手商品的下单即为热点库存降级疑问。
典型的库存扣减模型如下:
setautocommit=0;insert买卖流水表;updaterowfrom库存表;selectrowfrom库存表;//前往库存扣减的结果commit;
显而易见,少量降级抢手商品库存的线程会阻塞在updaterow,由于update的实质为lock-update-unlock,同一期间只能有一个线程对抢手商品库存前启动降级。
这样就会带来两个疑问,第一是同一个MySQL实例下非抢手商品的QPS降低,由于全体数据库的衔接数和资源有限;二是抢手商品的QPS简直归零,由于当少量恳求(线程)会落到MySQL的同一条记载上减库存时,其要求争夺InnoDB的行锁,当一个线程取得了行锁,其余并发线程就只能期待(InnoDB外部还有死锁检测等机制会重大影响性能),因此当并发度越高时,期待的线程就越多,此时tps会急剧降低,rt会飙升。
那么,在热点库存降级这样一个场景中,咱们看下PolarDB-X中是如何设计和优化相似热点降级疑问。
基于热点降级这一不凡场景,咱们第一步可以想到对SQL启动优化,缩小网络交互次数以及持有锁的期间,从而提高TPS。下单环节的网络交互如下所示:
观察上述的交互流程,咱们可以启动如下的优化:
select*/*+commit_on_success,target_affect_rowx*/fromupdate库存表
,其中x为预期的影响行数。
select*/*+commit_on_successrollback_on_failtarget_affect_rowx*/fromupdate库存表
优化后的网络交互如下所示,对比优化前的交互流程,咱们发现网络交互次可以有缩小,最后update操作的持有锁的期间就可以缩短,单位期间内能允许的并发度就可以失掉了优化。
由于在热点行的降级场景中,经过前面的业务模型剖析,对热点行的操作均为该事务的最后一条sql,且口头成功时必然会提交,因此PolarDB-X驳回批处置(组提交)的方式以提高吞吐量,即驳回lock-update-update-...-update-unlock的方式。
全体设计如下图所示:
为了更进一步提高关于热点降级行的处置,启动了两段流水线的设计,其中第一个阶段为打包搜集热点降级sql并启动内存降级,第二个阶段为启动组提交。为了经常使用流水线方式处置这些降级操作,要求经常使用两个口头单元对它们启动分组。当第一个分组搜集终了预备提交时,第二个分组立刻开局搜集降级操作;当第二个分组搜集终了预备提交时,第一个分组曾经提交终了并开局搜集新一批的降级操作,两个分组不时切换,并行口头。
其原理图如下所示:
详细的口头流程为:
整个环节,经过引入了Queue的队列机制,将一批update热点行降级只启动了一次性行锁失掉+内存计算,成功了组提交的成果,从而优化了热点行降级的效率。
setglobalhotspot=on;setglobalhotspot_lock_type=on
setautocommit=0;setdrds_transactiON_policy=xa;UPDATE/*+commit_on_successrollback_on_failtarget_affect_row(number)*/table_referenceSETassignment_list[WHEREwhere_condition];
留意事项
假设该语句成功,则启动提交,连同该语句之前的未提交语句一并提交。
假设该语句失败,则启动回滚,连同该语句之前的未提交语句一并回滚。
校验降级的行数能否合乎预期,若不合乎则降级失败。
典型示例:参与commit_on_success以经常使用组提交等针对热点降级场景的优化(id为主键,经常使用如下语句对id=1的记载启动降级,要求满足有足够库存扣减并降级成功时,则成功智能提交)
例子:setautocommit=0;setdrds_transaction_policy=xa;UPDATE/*+commit_on_successrollback_on_failtarget_affect_row(1)*/table_testSETc=c-1WHEREid=1andc>0;commit/rollback;
留意点:在updatecommit_on_success之后,假设紧跟一条其余dml语句,由于上一条的updatesql曾经会智能提交或回滚,这里会从新开启一个新的事务,不可满足事务保证。
详细的经常使用例子,可参考如何允许热点降级场景
mysql>showglobalstatuslike"%Group_update%";+---------------------------------------+--------+|Variable_name|Value|+---------------------------------------+--------+|Group_update_fail_count|54||Group_update_follower_count|962869||Group_update_free_count|2||Group_update_group_same_count|0||Group_update_gu_leak_count|0||Group_update_ignore_count|0||Group_update_insert_dup|0||Group_update_leader_count|168292||Group_update_lock_fail_count|0||Group_update_mgr_recycle_queue_length|0||Group_update_recycle_queue_length|0||Group_update_reuse_count|23329||Group_update_total_count|2|+---------------------------------------+--------+13rowsinset(0.01sec)
测试表定义
CREATETABLEsbtest(idINTUNSIGNEDNOTNULLPRIMARYKEY,cBIGINTUNSIGNEDNOTNULL);
测试语句(一条便捷的cas原子降级模拟热点行操作,参与hint来触发PolarDB-X的热点行优化)
UPDATE/*+COMMIT_ON_SUCCESSROLLBACK_ON_FAILTARGET_AFFECT_ROW(1)*/sbtestSETc=c+1WHEREid=1;
测试工具:sysbench测试实例:4C16G×2(两节点)
测试结果:
线程数 | 普通降级 | 热点降级 |
---|---|---|
1线程 | ||
4线程 | ||
8线程 | ||
16线程 | ||
32线程 | ||
64线程 | ||
128线程 | ||
256线程 | ||
512线程 |
从测试的结果来看,由于引入了网络优化去除了多余的commit期待,以及基于组提交的兼并降级,随着并发度越高带来的update吞吐会更显著,普通的小规格节点的峰值就可以到达2万+的吞吐量(可撑持阿里双十一的秒杀峰值)
PolarDB-X作为一款散布式数据库,要求协助用户处置海量存储+高并发的场景,散布式架构自身也会由于数据散布不均带来一些分区热点(存储空间、读写流量等),经过火区级别的决裂和负载平衡是可以有效消弭这局部热点。然而热点行不可经过散布式的裁减和调度来处置,肯定依赖于散布式数据库的内核个性,PolarDB-X联合了阿里团体多年的双十一库存高并发的阅历,在数据库内核级别提供了热点行的优化才干。
回忆热点行的降级场景,经常出现于库存、秒杀等场景,经常出现的业务基于redis做为前端缓存、或许基于MQ信息做异步化兼并扣减等操作,之后再对数据库启动保养,也是一个比拟行之有效的打算。然而关于业务来说,要处置redis、MQ信息和数据库之间的数据分歧性,或许会给业务带来肯定的库存超卖等危险。PolarDB-X在数据库级别提供了热点行的优化才干,可以在保证数据分歧性的前提下满足用户对高并发热点行的诉求,会是一种更好的技术选用。
常见的存储方式有以下几种:
1. 硬盘存储:这是最常用的存储方式,它将数据存储在机械硬盘或固态硬盘中。硬盘存储有各种类型,包括机械硬盘(HDD)和固态硬盘(SSD)。HDD使用旋转的磁盘来存储数据,而SSD则使用闪存芯片。SSD比HDD更快,因为它没有机械移动,但价格也更高。
2. 内存存储:内存存储也称为RAM(随机访问内存),它用于存储当前正在使用的数据。RAM的速度非常快,但需要定期刷新数据以防止数据丢失。
3. 云存储:云存储是一种通过网络提供的数据存储服务。用户可以将数据存储在远程服务器上,而无需购买和维护自己的硬件设备。云存储通常使用分布式文件系统,如Google的GFS和Hadoop的HDFS。
4. 数据库存储:数据库存储用于存储和管理大量的结构化数据。数据库系统通常使用SQL进行操作和管理。常见的数据库系统包括关系型数据库(如MySQL、Oracle)、非关系型数据库(如MongoDB、Redis)等。
5. 网络附加存储(NAS):网络附加存储是一种将数据存储在网络服务器上的方式。它通常用于企业内部网络,提供文件共享服务。它使用专用的文件系统(如NFS)来管理数据。
6. 磁盘阵列(RAID):磁盘阵列是一种将多个硬盘组合在一起以提高数据安全性和性能的方式。RAID通过将数据分布在不同的硬盘上,并在需要时重新创建,以提高数据的可靠性和可用性。
在选择数据存储方式时,需要考虑数据的类型、访问频率、数据量、数据重要性和数据丢失的后果等因素。针对不同情况,可以根据应用的需求和预算,选择不同类型的数据库作为数据存储方式。
互联网时代各种存储框架层出不穷,眼花缭乱,比如传统的关系型数据库:Oracle、MySQL;新兴的NoSQL:HBase、Cassandra、Redis;全文检索框架:ES、Solr等。如何为自己的业务选取合适的存储方案,相信大家都思考过这个问题,本文简单聊聊我对Mysql、HBase、ES的理解,希望能和大家一起探讨进步,有不对的地方还请指出。
标签: PolarDB、本文地址: https://yihaiquanyi.com/article/158f96e027a37b94c2d2.html
上一篇:磁极数据库重新定义云端数据库的未来磁极平...