在如今数据库管理中,应对MySQL中的热点数据更新一直是业内的一大挑战,尤其在秒杀等高并发场景中显得尤为重要。如果处理不当,可能会造成数据库系统崩溃。
针对MySQL层面上如何有效应对高并发的热点数据更新问题,特别是像库存扣减这样的情况,有一些解决方案可供考虑:
综上所述,通过以上策略的综合运用,可以有效应对MySQL中高并发热点数据更新的挑战,提升系统的并发处理能力和稳定性。
上述提到的缓存优化、异步处理、乐观锁、悲观锁其实在往期文章中已经有所阐述,详细的可了解文章:
这一次我们主要聊一聊MySQL热点数据是如何更新的。在实际的电商平台中是如何处理这种棘手的问题的。
拆分库存,将原本的大库存分解为多个小库存,这样一次扣减操作可以分散到不同的库或表中进行,从而降低锁的粒度,提高并发性。
设计思路如图:
请求合并策略:将多个库存扣减请求合并为一个请求,以实现批量更新的操作。
Update转换为Insert:通过直接插入一条占用记录的方式,将更新操作转换为插入操作,然后通过异步统计剩余库存或通过SQL统计流水方式计算剩余库存。
除了上述三种方案外,让我详细介绍一种在我们公司内部成功应用并在双十一等高并发场景下表现出色的秒杀方案。该方案也是主流互联网公司主流的解决方案。
该方案针对于中小型企业并不适用,其一是没必要,毕竟并发峰值并没有那么高,其二就是技术人员的自身实力并不稳定,如果去做可能会有风险。
一项终极解决方案是对MySQL数据库进行改造,主要针对频繁更新或秒杀等高并发业务场景,以显著优化热点行数据的更新操作性能。通过启用热点更新自动检测功能,系统会自动检测是否存在单行的热点更新,然后让大量并发的更新操作排队执行,从而减少大量行锁带来的并发性能下降。
具体来说,他们对MySQL数据库进行了改造,使得针对同一热点行的更新语句在执行层面进行排队。这种排队相比于传统的更新操作排队更轻量级,因为它不需要自旋,也不需要争夺锁。
这一方案的优势在于开发人员无需额外操作,只需开启热点检测即可。然而,缺点在于改造MySQL数据库需要投入一定成本。不过,目前许多云数据库已经开始支持这种功能。
这种方法的实施可以有效提升对于热点数据的更新操作性能,为处理高并发场景下的业务提供了一种可靠的技术支持。
其实说了这么多解决方案,其实中小企业中的实际业务场景中并不需要考虑的这么多,毕竟不是所有公司都是BAT。我们只需要如果在必要时刻有一定的解决思路即可,无论是什么方案都是在实际库存业务场景中摸索出来的。架构也是一点点演进优化而来,一口是吃不了一个胖子的。
归根结底要知道的事无论是BAT哪家公司还是其他的互联网大厂,最后一道防线主要仍然依赖于MySQL数据库进行库存扣减操作。这种做法主要基于其可靠性考量,避免了像Redis扣减方案中可能出现的数据不一致和少卖等问题。
之所以MySQL数据库在扣减库存方面被广泛采用,主要是因为其稳定性和数据一致性方面的优势。在高并发的秒杀场景下,确保每一笔交易的准确性和可靠性至关重要,因此选择MySQL作为库存扣减的基础工具被认为是一种最为可靠的做法。
我们实际的解决方案其实在上一篇文章中有提到过,最后保证的库存一致性就是通过对帐系统
在分布式系统中,尽管我们会采用各种分布式事务方案来确保各个系统之间的一致性,但往往情况并非如人所愿。
特别是现在许多公司都采用最终一致性方案,而最终一致性意味着无论是本地消息表、事务消息还是任务重试,系统之间的调用都存在失败的可能性。
一旦发生失败,就需要一套机制来发现这些不一致性问题,这时候就需要进行数据对账。
一般来说,根据对账的时机,对账可以分为两种类型:离线对账和(准)实时对账。
实时对账一般是准实时的,即无法保证无延迟,但通常可以控制在秒级延迟内。而离线对账则通常是在第二天(D+1)进行核对。
对于分布式系统中的数据一致性和对账问题,准实时对账提供了一种在较短延迟内发现不一致性的机制,而离线对账则更侧重于在第二天对数据进行全面核对。这些对账机制在确保系统运行稳定性和数据一致性方面发挥着重要作用。
在金融和商业领域常见的对账机制中,有两种常用的时间标识:D+1和T+1。 D+1中的D代表自然日,包括工作日和节假日,而+1表示在数据发生后的第二天进行核对。这意味着对账操作会在数据发生后的第二天进行,无论是工作日还是节假日。 而T+1中的T代表交易日,通常指的是工作日,因此T+1表示在数据发生后的下一个工作日进行核对。这种对账方式更加关注数据发生后的下一个工作日进行核对,以确保交易的准确性和一致性。 这两种对账机制在金融和商业领域中扮演着重要角色,帮助确保交易数据的准确性和完整性,同时为业务运营提供了有效的监控和核对手段。
在对账技术实现中,通常主要采用两种方法:编写代码核对和编写SQL核对。
编写代码核对是指查找需要比对的两条记录,然后进行字段比对,发现不一致的情况后进行处理。这种方法通常通过定时任务来实现,定时任务会扫描表格或者远程拉取数据,然后在业务代码中进行核对。虽然这种方法比较通用,无论是数据库、文件还是远程接口都可以进行核对,但缺点是随着数据量的增加,代码核对的时效性会变差,而且代码运行可能会出现失败的情况。特别是当数据量巨大时,可能会面临扫表速度慢、内存不足导致OOM等问题。
因此,一般不推荐采用编写代码的方式进行核对。
相比之下,编写SQL是一种更好的方式。由于数据通常存储在数据库(包括数据仓库或大数据框架)中,可以通过SQL查询来进行核对。以下是一个比较两个系统中金额是否一致的SQL示例:
SELECT
A.amount AS amount_A,
B.amount AS amount_B
FROM
table_A A
JOIN
table_B B ON A.id = B.id
WHERE
A.date = '2024-03-09'
AND B.date = '2024-03-09'
AND A.amount <> B.amount;
通过编写SQL进行核对可以利用数据库的强大功能和优化能力,提高核对效率和准确性,尤其适用于数据存储在数据库中的情况。
在进行数据核对时,有多种方案可供选择,具体取决于您的需求和系统架构。以下是一些常见的数据核对方案:
根据具体需求和系统架构,您可以选择适合的数据核对方案来确保数据的一致性和准确性。
当通过SQL语句发现数据不一致时,通常有多种处理方式:
通过以上方式,可以实现职责的明确分工:核对负责核对数据,报警负责发出报警通知。确保有效的报警得到及时处理,避免无效报警影响工作效率,同时保证数据一致性和系统稳定性。