首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    如何解决热点数据更新问题

    一 背景 某个业务线商品开放用户申请免费试用,当某个商品特别吸引人时,比如iPhone6 。肯定有一大波人为了少卖一个肾而疯狂去抢申请资格。更有甚者利用机器人申请注册,于是简单的申请操作变成了秒杀行为。大量请求同时更新数据库中的同一个商品的申请次数,update 操作给表加上行锁,导致后面的请求全部排队等待前面一个update完成,释放行锁后才能处理下一个请求。大量后来请求等待,占用了数据库的连接。一旦数据库连接数被占满,就会导致后来的全部请求因拿不到连接而超时,业务请求出现无法及时处理的情况,数据库系统的RT会异常飙高,业务层由于等待出现超时,app 层的连接耗尽,一系列的雪崩效应! 二 解决方案 从上面的背景分析,解决热点数据并发更新需要注意核心问题: 减少直接对db层数据热点的并发更新,或者提供MySQL 更新同一行的吞吐量。本文从业务和数据库的设计层面来规划.同时也希望大家提更好的解决思路。 1 前端层面 前端是整个流量的入口, 正常业务访问时系统表现平稳,但是当有人恶意请求时,需要加上流控措施,比如常见的 a 需要用户回答问题,填写验证码,移动图像等等,防止或者减少有机器人来恶意请求。 b 页面上采用防止机器人的判断 两秒以内的成功请求一律拒绝。 c 通过设置nginx ,对同一个ip源的请求次数做限制,防止机器人来申请。 优点 有效减少或者防止有人利用机器人恶意请求 缺点 存在一定的误杀率,错杀了正常的请求。 2 应用层 应用程序接收前端前端请求,进行一系列的数据库操作,在我们规避了恶意请求之后如果还是有大量的数据库写访问请求,我们需要 a 对业务做降级 限制接口的调用次数,降低对数据库的请求压力。选择异步更新请求次数,弱化该商品申请次数的展现。类似于阅读次数,申请次数 ,与金额,库存无关的功能点。 b 通过异步更新来避免直接写数据库 。 应用使用分布式缓存(比如Tair/Redis)来存储某项商品的申请次数或者某人的申请次数,以商品id/user_id 或者将where 条件作为key,申请试用人数为value/符合某项具体条件的 count结果为value, 有用户申请成功则更新申请试用人数。不需要查询和实时写数据库,每隔一定时间/次数将结果写入数据库。 优点:该方法依赖于缓存,读写速度快,不需要实时更新数据库,减轻数据库并发写的压力; 缺点:缓存不是100%稳定,很容易丢,即使采用持久化的缓存,在高并发下有时也可能会出现异常,穿透缓存到db ,导致前端业务展现问题。 3 数据库层 a 将热点数据拆分,分在不同的库不同的表中,分散热点数据,减轻数据库并发更新热点带来的RT升高和应用连接等待时能保证业务能够正常访问其他商品表,损失局部可用性。 优点:实时读写数据库,前端展示数据的准确性。 缺点:业务逻辑稍显复杂。 b 限流补丁 针对某些特定的sql语句 从MySQL 层面加以限制,当系统thread_running达到一定值或者某个sql执行时间超过一定阈值则拒绝该sql的执行。(阿里内部已经实现限流版本)

    00

    Mysql 查看修改连接数最大并发数

    show variables like '%max_connections%'; 查看最大连接数 set global max_connections=1000 重新设置,重启失效 打开my.ini,修改max_connections=1000(默认为100),永久生效 show status like 'Threads%'; +-------------------+-------+ | Variable_name     | Value | +-------------------+-------+ | Threads_cached    | 58    | | Threads_connected | 57    |   ###这个数值指的是打开的连接数 | Threads_created   | 3676  | | Threads_running   | 4     |   ###这个数值指的是激活的连接数,这个数值一般远低于connected数值 +-------------------+-------+ Threads_connected 跟show processlist结果相同,表示当前连接数。准确的来说,Threads_running是代表当前并发数 show full processlist 如果是root帐号,你能看到所有用户的当前连接。如果是其它普通帐号,只能看到自己占用的连接 命令:show status like '%下面变量%'; Aborted_clients 由于客户没有正确关闭连接已经死掉,已经放弃的连接数量。  Aborted_connects 尝试已经失败的MySQL服务器的连接的次数。  Connections 试图连接MySQL服务器的次数。  Created_tmp_tables 当执行语句时,已经被创造了的隐含临时表的数量。  Delayed_insert_threads 正在使用的延迟插入处理器线程的数量。  Delayed_writes 用INSERT DELAYED写入的行数。  Delayed_errors 用INSERT DELAYED写入的发生某些错误(可能重复键值)的行数。  Flush_commands 执行FLUSH命令的次数。  Handler_delete 请求从一张表中删除行的次数。  Handler_read_first 请求读入表中第一行的次数。  Handler_read_key 请求数字基于键读行。  Handler_read_next 请求读入基于一个键的一行的次数。  Handler_read_rnd 请求读入基于一个固定位置的一行的次数。  Handler_update 请求更新表中一行的次数。  Handler_write 请求向表中插入一行的次数。  Key_blocks_used 用于关键字缓存的块的数量。  Key_read_requests 请求从缓存读入一个键值的次数。  Key_reads 从磁盘物理读入一个键值的次数。  Key_write_requests 请求将一个关键字块写入缓存次数。  Key_writes 将一个键值块物理写入磁盘的次数。  Max_used_connections 同时使用的连接的最大数目。  Not_flushed_key_blocks 在键缓存中已经改变但是还没被清空到磁盘上的键块。  Not_flushed_delayed_rows 在INSERT DELAY队列中等待写入的行的数量。  Open_tables 打开表的数量。  Open_files 打开文件的数量。  Open_streams 打开流的数量(主要用于日志记载)  Opened_tables 已经打开的表的数量。  Questions 发往服务器的查询的数量。  Slow_queries 要花超过long_query_time时间的查询数量。  Threads_connected 当前打开的连接的数量。  Threads_running 不在睡眠的线程数量。  Uptime 服务器工作了多少秒。

    02

    MySQL中show语法

    1. show tables或show tables from database_name; -- 显示当前数据库中所有表的名称。  2. show databases; -- 显示mysql中所有数据库的名称。  3. show columns from table_name from database_name; 或show columns from database_name.table_name; -- 显示表中列名称。  4. show grants for user_name; -- 显示一个用户的权限,显示结果类似于grant 命令。  5. show index from table_name; -- 显示表的索引。  6. show status; -- 显示一些系统特定资源的信息,例如,正在运行的线程数量。  7. show variables; -- 显示系统变量的名称和值。  8. show processlist; -- 显示系统中正在运行的所有进程,也就是当前正在执行的查询。大多数用户可以查看他们自己的进程,但是如果他们拥有process权限,就可以查看所有人的进程,包括密码。  9. show table status; -- 显示当前使用或者指定的database中的每个表的信息。信息包括表类型和表的最新更新时间。  10. show privileges; -- 显示服务器所支持的不同权限。  11. show create database database_name; -- 显示create database 语句是否能够创建指定的数据库。  12. show create table table_name; -- 显示create database 语句是否能够创建指定的数据库。  13. show engines; -- 显示安装以后可用的存储引擎和默认引擎。  14. show innodb status; -- 显示innoDB存储引擎的状态。  15. show logs; -- 显示BDB存储引擎的日志。  16. show warnings; -- 显示最后一个执行的语句所产生的错误、警告和通知。  17. show errors; -- 只显示最后一个执行语句所产生的错误。  18. show [storage] engines; --显示安装后的可用存储引擎和默认引擎。

    02

    组复制性能 | 全方位认识 MySQL 8.0 Group Replication

    为了让一个复制组正常使用消息分段功能,所有组成员必须运行MySQL 8.0.16或以上版本,并且组使用的组复制通信协议版本必须支持消息分段。可以使用group_replication_get_communication_protocol() UDF检查组使用的通信协议版本是多少,UDF 返回版本号字符串代表了组支持的最老的MySQL Server版本。MySQL 5.7.14的版本支持压缩消息,MySQL 8.0.16的版本支持消息分段。如果所有组成员都运行在MySQL 8.0.16以上版本,并且组中不需要运行更低版本的组成员,则可以使用group_replication_set_communication_protocol UDF()来设置通信协议版本为MySQL 8.0.16及其以上,这样就能够确保消息分段功能在组中所有成员上正常运行。有关更多信息,请参见"4.1.4. 设置组的通信协议版本”。

    03
    领券