每秒100W请求,12306秒杀业务,架构如何优化?

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 12306类业务,并发量很高,几乎所有的读写锁冲突都集中在少量数据上,难度最大

同样是高并发,社交通讯/微博/12306的架构难度一样吗?同样是高并发场景,三类业务的架构挑战不一样:

  • 社交通讯类业务,用户主要读写自己的数据,访问基本带有uid属性,数据访问锁冲突较小
  • 微博类业务,用户的feed主页由别人发布的消息构成,数据读写有一定锁冲突
  • 12306类业务,并发量很高,几乎所有的读写锁冲突都集中在少量数据上,难度最大
那么对于秒杀类业务,系统上业务上分别能如何优化呢,这是本文要讨论的问题。


系统层面,秒杀业务的优化方向如何?

主要有两项:

(1)将请求尽量拦截在系统上游,而不要让锁冲突落到数据库。
传统秒杀系统之所以挂,是因为请求都压到了后端数据层,数据读写锁冲突严重,并发高响应慢,几乎所有请求都超时,访问流量大,下单成功的有效流量小。
一趟火车2000张票,200w个人同时来买,没有人能买成功,请求有效率为0。 画外音:此时系统的效率,还不如线下售票窗口。
(2)充分利用缓存。
秒杀买票,这是一个典型的 读多写少 的业务场景:
  • 车次查询,读,量大

  • 余票查询,读,量大

  • 下单和支付,写,量小


一趟火车2000张票,200w个人同时来买,最多2000个人下单成功,其他人都是查询库存,写比例只有0.1%,读比例占99.9%,非常适合使用缓存来优化。  

秒杀业务,常见的系统分层架构如何?

image.png


秒杀业务,可以使用典型的服务化分层架构

  • 浏览器/APP),最上层,面向用户

  • 站点层,访问后端数据,拼装html/json返回

  • 服务层,屏蔽底层数据细节,提供数据访问

  • 数据层,DB存储库存,当然也有缓存


这四层分别应该如何优化呢?
一、端上的请求拦截(浏览器/APP) 想必春节大家都玩过微信的摇一摇抢红包,用户每摇一次,真的就会往后端发送一次请求么?
回顾抢票的场景,用户点击“查询”按钮之后,系统卡顿,用户着急,会不自觉的再去频繁点击“查询”,不但没用,反而平白无故增加系统负载,平均一个用户点5次,80%的请求是这么多出来的。
JS层面,可以限制用户在x秒之内只能提交一次请求 ,从而降低系统负载。
画外音:频繁提交,可以友好提示“频率过快”。
APP层面,可以做类似的事情,虽然用户疯狂的在摇微信抢红包,但其实x秒才向后端发起一次请求。 画外音:这就是所谓的“将请求尽量拦截在系统上游”,浏览器/APP层就能拦截80%+的请求。
不过,端上的拦截只能挡住普通用户(99%的用户是普通用户),程序员firebug一抓包,写个for循环直接调用后端http接口,js拦截根本不起作用,这下怎么办?   二、站点层的请求拦截 如何抗住程序员写for循环调用http接口,首先要确定用户的唯一标识,对于频繁访问的用户予以拦截。
用什么来做用户的唯一标识? ip?cookie-id?别想得太复杂,购票类业务都 需要登录 用uid就能标识用户
在站点层, 对同一个uid的请求进行计数和限速 ,例如:一个uid,5秒只准透过1个请求,这样又能拦住99%的for循环请求。

一个uid,5s只透过一个请求,其余的请求怎么办? 缓存,页面缓存 ,5秒内到达站点层的其他请求,均返回上次返回的页面。 画外音:车次查询和余票查询都能够这么做,既能保证用户体验(至少没有返回404页面),又能保证系统的健壮性(利用页面缓存,把请求拦截在站点层了)。   OK,通过 计数、限速、页面缓存 拦住了99%的普通程序员,但仍有些高端程序员,例如黑客,控制了10w个肉鸡,手里有10w个uid,同时发请求,这下怎么办?   三、服务层的请求拦截 并发的请求已经到了服务层,如何进拦截? 服务层非常清楚 业务的库存 ,非常清楚 数据库的抗压能力 ,可以根据这两者进行削峰限速。
例如,业务服务很清楚的知道,一列火车只有2000张车票,此时透传10w个请求去数据库,是没有意义的。 画外音:假如数据库每秒只能抗500个写请求,就只透传500个。
用什么削峰? 请求 队列
对于写请求,做请求队列,每次只透传有限的写请求去数据层(下订单,支付这样的写业务)。
只有2000张火车票,即使10w个请求过来,也只透传2000个去访问数据库:
  • 如果前一批请求均成功,再放下一批

  • 如果前一批请求库存已经不足,则后续请求全部返回“已售罄”

  对于读请求,怎么优化? cache抗,不管是memcached还是redis,单机抗个每秒10w应该都是没什么问题的。 画外音:缓存做水平扩展,很容易线性扩容。
如此削峰限流,只有非常少的写请求,和非常少的读缓存mis的请求会透到数据层去,又有99%的请求被拦住了。   四、数据库层 经过前三层的优化:
  • 浏览器拦截了80%请求

  • 站点层拦截了99%请求,并做了页面缓存

  • 服务层根据业务库存,以及数据库抗压能力,做了写请求队列与数据缓存

你会发现,每次透到数据库层的请求都是可控的。
db基本就没什么压力了,闲庭信步。 画外音:这类业务数据量不大,无需分库,数据库做一个高可用就行。
此时,透2000个到数据库,全部成功,请求有效率100%。 画外音:优化前,10w个请求0个成功,有效性0%。

按照上面的优化方案,其实压力最大的反而是站点层,假设真实有效的请求数是每秒100w,这部分的压力怎么处理?

解决方向有两个: (1) 站点层水平扩展 ,通过加机器扩容,一台抗5000,200台搞定; (2) 服务降级 ,抛弃请求,例如抛弃50%; 原则是要保护系统,不能让所有用户都失败。   站点层限速,是个每个uid的请求计数放到redis里么? 吞吐量很大情况下,高并发访问redis,网络带宽会不会成为瓶颈? 同一个uid计数与限速,如果担心访问redis带宽成为瓶颈,可以这么优化: (1)计数直接放在内存,这样就省去了网络请求; (2)在nginx层做7层均衡,让一个uid的请求落到同一个机器上; 画外音:这个计数对数据一致性、准确性要求不高,即使服务重启计数丢了,大不了重新开始计。
除了系统上的优化, 产品与业务还能够做一些折衷 ,降低架构难度。

业务折衷一 一般来说,下单和支付放在同一个流程里,能够提高转化率。对于秒杀场景,产品上, 下单流程和支付流程异步 ,放在两个环节里,能够降低数据库写压力。以12306为例,下单成功后,系统占住库存,45分钟之内支付即可。


业务折衷二 一般来说,所有用户规则相同,体验会更好。对于秒杀场景,产品上, 不同地域分时售票 ,虽然不是所有用户规则相同,但能够极大降低系统压力。北京9:00开始售票,上海9:30开始售票,广州XX开始售票,能够分担系统压力。


业务折衷三 秒杀场景,由于短时间内并发较大,系统返回较慢,用户心情十分焦急,可能会频繁点击按钮,对系统造成压力。产品上可以优化为, 一旦点击,不管系统是否返回,按钮立刻置灰 ,不给用户机会频繁点击。


业务折衷四 一般来说,显示具体的库存数量,能够加强用户体验。对于秒杀场景,产品上, 只显示有/无车票,而不是显示具体票数目 ,能够降低缓存淘汰率。

画外音:显示库存会淘汰N次,显示有无只会淘汰1次。更多的,用户关注是否有票,而不是票有几张。


无论如何,产品技术运营一起,目标是一致的,把事情做好,不存在谁是甲方,谁是乙方的关系。  

总结

对于秒杀系统,除了产品和业务上的折衷,架构设计上主要有两大优化方向: (1) 尽量将请求拦截在系统上游 (2) 读多写少用缓存


任何脱离业务的架构设计是耍流氓

本文转自“架构师之路”公众号,58沈剑提供。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
2月前
|
消息中间件 存储 缓存
十万订单每秒热点数据架构优化实践深度解析
【11月更文挑战第20天】随着互联网技术的飞速发展,电子商务平台在高峰时段需要处理海量订单,这对系统的性能、稳定性和扩展性提出了极高的要求。尤其是在“双十一”、“618”等大型促销活动中,每秒需要处理数万甚至数十万笔订单,这对系统的热点数据处理能力构成了严峻挑战。本文将深入探讨如何优化架构以应对每秒十万订单级别的热点数据处理,从历史背景、功能点、业务场景、底层原理以及使用Java模拟示例等多个维度进行剖析。
57 8
|
21天前
|
弹性计算 运维 监控
阿里云云服务诊断工具:合作伙伴架构师的深度洞察与优化建议
作为阿里云的合作伙伴架构师,我深入体验了其云服务诊断工具,该工具通过实时监控与历史趋势分析,自动化检查并提供详细的诊断报告,极大提升了运维效率和系统稳定性,特别在处理ECS实例资源不可用等问题时表现突出。此外,它支持预防性维护,帮助识别潜在问题,减少业务中断。尽管如此,仍建议增强诊断效能、扩大云产品覆盖范围、提供自定义诊断选项、加强教育与培训资源、集成第三方工具,以进一步提升用户体验。
665 243
|
14天前
|
机器学习/深度学习 算法 数据可视化
基于深度混合架构的智能量化交易系统研究: 融合SSDA与LSTM自编码器的特征提取与决策优化方法
本文探讨了在量化交易中结合时序特征和静态特征的混合建模方法。通过整合堆叠稀疏降噪自编码器(SSDA)和基于LSTM的自编码器(LSTM-AE),构建了一个能够全面捕捉市场动态特性的交易系统。SSDA通过降噪技术提取股票数据的鲁棒表示,LSTM-AE则专注于捕捉市场的时序依赖关系。系统采用A2C算法进行强化学习,通过多维度的奖励计算机制,实现了在可接受的风险水平下最大化收益的目标。实验结果显示,该系统在不同波动特征的股票上表现出差异化的适应能力,特别是在存在明确市场趋势的情况下,决策准确性较高。
50 5
基于深度混合架构的智能量化交易系统研究: 融合SSDA与LSTM自编码器的特征提取与决策优化方法
|
25天前
|
存储 机器学习/深度学习 人工智能
【AI系统】计算图优化架构
本文介绍了推理引擎转换中的图优化模块,涵盖算子融合、布局转换、算子替换及内存优化等技术,旨在提升模型推理效率。计算图优化技术通过减少计算冗余、提高计算效率和减少内存占用,显著改善模型在资源受限设备上的运行表现。文中详细探讨了离线优化模块面临的挑战及解决方案,包括结构冗余、精度冗余、算法冗余和读写冗余的处理方法。此外,文章还介绍了ONNX Runtime的图优化机制及其在实际应用中的实现,展示了如何通过图优化提高模型推理性能的具体示例。
54 4
【AI系统】计算图优化架构
|
15天前
|
机器学习/深度学习 前端开发 算法
婚恋交友系统平台 相亲交友平台系统 婚恋交友系统APP 婚恋系统源码 婚恋交友平台开发流程 婚恋交友系统架构设计 婚恋交友系统前端/后端开发 婚恋交友系统匹配推荐算法优化
婚恋交友系统平台通过线上互动帮助单身男女找到合适伴侣,提供用户注册、个人资料填写、匹配推荐、实时聊天、社区互动等功能。开发流程包括需求分析、技术选型、系统架构设计、功能实现、测试优化和上线运维。匹配推荐算法优化是核心,通过用户行为数据分析和机器学习提高匹配准确性。
49 3
|
2月前
|
监控 Serverless 云计算
探索Serverless架构:开发实践与优化策略
本文深入探讨了Serverless架构的核心概念、开发实践及优化策略。Serverless让开发者无需管理服务器即可运行代码,具有成本效益、高可扩展性和提升开发效率等优势。文章还详细介绍了函数设计、安全性、监控及性能和成本优化的最佳实践。
|
2月前
|
弹性计算 运维 开发者
后端架构优化:微服务与容器化的协同进化
在现代软件开发中,后端架构的优化是提高系统性能和可维护性的关键。本文探讨了微服务架构与容器化技术如何相辅相成,共同推动后端系统的高效运行。通过分析两者的优势和挑战,我们提出了一系列最佳实践策略,旨在帮助开发者构建更加灵活、可扩展的后端服务。
|
2月前
|
消息中间件 运维 Cloud Native
云原生架构下的微服务优化策略####
本文深入探讨了云原生环境下微服务架构的优化路径,针对服务拆分、通信效率、资源管理及自动化运维等核心环节提出了具体的优化策略。通过案例分析与最佳实践分享,旨在为开发者提供一套系统性的解决方案,以应对日益复杂的业务需求和快速变化的技术挑战,助力企业在云端实现更高效、更稳定的服务部署与运营。 ####
|
2月前
|
存储 负载均衡 监控
如何利用Go语言的高效性、并发支持、简洁性和跨平台性等优势,通过合理设计架构、实现负载均衡、构建容错机制、建立监控体系、优化数据存储及实施服务治理等步骤,打造稳定可靠的服务架构。
在数字化时代,构建高可靠性服务架构至关重要。本文探讨了如何利用Go语言的高效性、并发支持、简洁性和跨平台性等优势,通过合理设计架构、实现负载均衡、构建容错机制、建立监控体系、优化数据存储及实施服务治理等步骤,打造稳定可靠的服务架构。
44 1
|
2月前
|
Kubernetes API Docker
构建高效后端服务:微服务架构的深度实践与优化####
本文深入探讨了微服务架构在现代后端开发中的应用,通过剖析其核心概念、设计原则及实施策略,结合具体案例分析,展示了如何有效提升系统的可扩展性、可靠性和维护性。文章还详细阐述了微服务拆分的方法论、服务间通信的最佳实践、以及容器化与编排工具(如Docker和Kubernetes)的应用技巧,为读者提供了一份全面的微服务架构落地指南。 ####

热门文章

最新文章