服务器之家:专注于服务器技术及软件下载分享
分类导航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|数据库技术|

服务器之家 - 数据库 - Mysql - 双十一大促是怎么做MySQL热点数据高效更新的?

双十一大促是怎么做MySQL热点数据高效更新的?

2023-07-15 01:00未知服务器之家 Mysql

MySQL的热点数据更新问题,一直都是行业内的一个难题,对于秒杀场景至关重要。一旦处理不好,就可能会导致数据库被打垮。 通常来说,对于热点问题,都是选择使用Redis来抗,比如秒杀场景借助他的单线程高并发能力来做预扣

MySQL的热点数据更新问题,一直都是行业内的一个难题,对于秒杀场景至关重要。一旦处理不好,就可能会导致数据库被打垮。

通常来说,对于热点问题,都是选择使用Redis来抗,比如秒杀场景借助他的单线程高并发能力来做预扣减。

常规方案

但是,引入Redis又会带来数据不一致的问题,进而会导致超卖和少卖,如果一定要在MySQL这个层面上,抗住高并发的热点数据并发更新,有什么方案呢?拿库存扣减举例

1、库存拆分,把一个大的库存拆分成多个小库存,拆分后,一次扣减动作就可以分散到不同的库、表中进行,降低锁粒度提升并发。

    优点:实现较简单

    缺点:存在碎片问题、库存调控不方便

2、请求合并,把多个库存扣减请求,合并成一个,进行批量更新。

    优点:简单

    缺点:适用于异步场景,或者经过分析后认为可以合并的场景

3、把update转换成insert,直接插入一次占用记录,然后异步统计剩余库存,或者通过SQL统计流水方式计算剩余库存。

    优点:没有update,无锁冲突

    缺点:insert时控制不好容易超卖、insert后剩余库存不好统计

企业级方案

除了上面这三个方案外,重点介绍一个很多大公司在用的,扛了618/双11等大促的高并发的秒杀的方案。

那就是改造MySQL

主要思路就是,针对于频繁更新或秒杀类业务场景,大幅度优化对于热点行数据的update操作的性能。当开启热点更新自动探测时,系统会自动探测是否有单行的热点更新,如果有,则会让大量的并发 update 排队执行,以减少大量行锁造成的并发性能下降。(另外我出了一份Java面试宝典,类似的方案有很多)

也就是说,他们改造了MySQL数据库,让同一个热点行的更新语句,在执行层进行排队。这样的排队相比update的排队,要轻量级很多,因为他不需要自旋,不需要抢锁。

这个方案的好处就是开发不需要做额外的事情,只需要开启热点检测就行了。缺点就是改造MySQL数据库有成本。不过现在很多云上数据库都支持了。

效果如何?

比如阿里云的数据库在做过改造之后,就做过单行热点数据更新测试。

本示例中,分别使用两个实例进行测试(高可用版和三节点企业版),规格码为rds.mysql.st.v52和mysql.st.12xlarge.25。

  • 实例版本:MySQL 5.7
  • 实例规格:90核720GB(独占物理机型)
  • 实例系列:高可用版和三节点企业版
  • 实例存储类型:本地盘
  • 实例模板:高性能参数模板

测试数据为单表,表内100行记录。表结构如下:

CREATE TABLE `sbtest1`
(
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT   
,`k` INT(10) UNSIGNED NOT NULL DEFAULT '0'   
,`c` CHAR(120) NOT NULL DEFAULT ''   
,`pad` CHAR(60) NOT NULL DEFAULT ''   
,PRIMARY KEY (`id`)   
,KEY `k_1` (`k`)
)
ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT
CHARSET=utf8 MAX_ROWS=1000000

对id=100的记录进行并发更新,SQL如下:

UPDATE sbtest1 SET k=k+1 WHERE id=100

测试的Lua脚本如下:

pathtest = string.match(test,"(.*/)")
if pathtest then
   dofile(pathtest .."common.lua")
else
   require("common")
end
function thread_init(thread_id)
   set_vars()
end
function event(thread_id)
   local table_name
   table_name ="sbtest".. sb_rand_uniform(1, oltp_tables_count)
   rs = db_query("begin")
   rs = db_query("update /*+commit_on_success rollback_on_fail target_affect_row(1) */ sbtest1 SET k=k+1 WHERE id=100")
   rs =db_query("commit")
end

测试结果

实例类型

单行记录更新峰值(TPS)

RDS高可用版

1.2万

RDS三节点企业版

3.1万

参考资料:

腾讯云数据库MySQL热点更新:

https://cloud.tencent.com/document/product/236/63239

阿里云数据库Inventory Hint: 

http://www.zzvips.com/uploads/allimg/toizrjp5t5t.html

延伸 · 阅读

精彩推荐
  • MysqlMySQL 8.0.23 主要更新一览(新特征解读)

    MySQL 8.0.23 主要更新一览(新特征解读)

    这篇文章主要介绍了MySQL 8.0.23 主要更新一览(新特征解读),需要的朋友可以参考下...

    ActionTech6212021-04-04
  • MysqlMySQL操作数据库和表的常用命令新手教程

    MySQL操作数据库和表的常用命令新手教程

    这篇文章主要介绍了MySQL操作数据库和表的常用命令新手教程,本文总结的命令都是控制mysql必须掌握的、常用的命令,需要的朋友可以参考下 ...

    果冻想3332020-04-21
  • MysqlMySQL开启事务的方式

    MySQL开启事务的方式

    本篇文章给大家分享MySQL 是如何开启一个事务的,原文通过两种方式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参...

    程序员小航5392021-08-24
  • MysqlCentos7安装和配置Mysql5.7

    Centos7安装和配置Mysql5.7

    网上关于Linux安装mysql数据库的教程数不胜数,但是,大多教程都是漏洞百出。今天,为了帮助各位需要的人,从而写下Centos7安装配置mysql5.7的教程。 ...

    LCode丶5712020-08-27
  • MysqlMySQL进阶SELECT语法篇

    MySQL进阶SELECT语法篇

    从这个基本语法可以看出,最简单的SELECT语句是SELECT select_list,实际上利用这个最简单的SELECT语句,你也可以完成许多你期待的功能,首先你能利用它进行...

    mysql技术网2872019-10-21
  • Mysql我常用的免费MySQL图形化管理工具

    我常用的免费MySQL图形化管理工具

    Navicat虽然好用,但是需要花钱,如果不想破解,就只能考虑别的免费工具了。下面谈谈我常用的免费MySQL管理工具。 ...

    今日头条7812019-12-08
  • MysqlMySQL悲观锁与乐观锁的实现方案

    MySQL悲观锁与乐观锁的实现方案

    我们知道Mysql并发事务会引起更新丢失问题,解决办法是锁,所以本文将对锁(乐观锁、悲观锁)进行分析,这篇文章主要给大家介绍了关于MySQL悲观锁与乐观锁...

    程序员小潘5142021-12-01
  • Mysql深入mysql外键关联问题的详解

    深入mysql外键关联问题的详解

    本篇文章是对mysql外键关联问题进行了详细的分析介绍,需要的朋友参考下 ...

    MYSQL教程网3712019-12-29