高并发系统深度优化

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 高并发系统深度优化

1 背景

每年的春节是中国人的传统节日,大多数中国人都会在这一天选择回家团聚。为了方便用户进行购票,2012 年春节,铁道部推出 12306 网站,进行网络实名购票。然而,历年春节假期,巨大的访问请求都让中国铁路客户服务中心网站(www.12306.cn)陷入“万劫不复”。根据新浪的调查,在 2013 年春节,有近 90%的网友表示 12306 网站缓慢、页面崩溃,严重影响正常购票。


世界级的人口迁徙带来了一个世界级的难题: 要如何通过网络,把火车票及时卖给有需要的人?


12306 网站所面临的问题分析:


铁道部在线车票发售网站 12306 基本不存在大量图片、视频这些占带宽资源的东西,所面临的主要问题就是数据库的高并发量——用中国的人口基数来算,这是一个极为恐怖的并发量,在车票发售的高峰时间点,向 12306 发起的并发请求数量大得就像一场国家规模的 DDOS 攻击。

中国铁路客户服务中心网站(www.12306.cn)是世界规模最大的实时交易系统之一,媲美 Amazon.com,节假日尤其是春节的访问高峰,网站压力巨大。据统计,在 2012 年初的春运高峰期间,每天有 2000 万人访问该网站,日点击量最高达到 14 亿。


所以 12306 所面临的难题本质上也是属于 高并发访问问题,类似与一些电商网站所搞的"秒杀"活动一样。通过对 12306 的深度优化,2015 年 12306网站顺利过关,没有“瘫痪”,是值得庆祝的。而我们本次主要就是来探究一下如何对 12306 网站做深度优化来抵御高并发访问。


2 高并发访问

那么 12306 做了什么样的优化,才解决了高并发访问呢?

12306 技术部主任单杏花在接受一次记者采访的时候有说到:我们研发了 分布式的内存计算的余票计算技术,让余票计算变得非常高效。与此同时单杏花及其团队还研发了 异步交易排队系统,这种系统采用 售取分离、读写分离的核心系统架构等多种技术,为 12306 售票系统提供技术支撑。


其实通过她的描述,我们可以得出一些处理高并发访问方式:

1、采用内存计算(使用缓存系统)

2、异步处理请求(进行流量消峰)

3、数据库进行读写分离操作

常见的分布式缓存系统:MongoDB , Redis,MemCache


2.1 流量消峰的方案

1、要对流量进行削峰,最容易想到的解决方案就是 用消息队列来缓冲瞬时流量,把同步的直接调用转换成异步的间接推送,中间通过一个队列在

一端承接瞬时的流量洪峰,在另一端平滑地将消息推送出去。在这里,消息队列就像“水库”一样,拦蓄上游的洪水,削减进入下游河道的洪峰

流量,从而达到减免洪水灾害的目的。


98a57b5cf0a94427a8c37b48ae99989d.png

2.2 进行人为验证答题

你是否还记得,最早期的秒杀只是纯粹地刷新页面和点击购买按钮,它是后来才增加了答题功能的。那么,为什么要增加答题功能呢?这主要是为了增加购买的复杂度,从而达到两个目的。


第一个目的是防止部分买家使用秒杀器在参加秒杀时作弊。2011 年秒杀非常火的时候,秒杀器也比较猖獗,因而没有达到全民参与和营销的目的,所以系统增加了答题来限制秒杀器。增加答题后,下单的时间基本控制在 2s 后,秒杀器的下单比例也大大下降。答题页面如下图所示。

c95bc5859718497a8f3b0f0ca18e9064.png

第二个目的其实就是延缓请求,起到对请求流量进行削峰的作用,从而让系统能够更好地支持瞬时的流量高峰。这个重要的功能就是把峰值的下单请求拉长,从以前的 1s 之内延长到 2s~10s。

这样一来,请求峰值基于时间分片了。这个时间的分片对服务端处理并发非常重要,会大大减轻压力。而且,由于请求具有先后顺序,靠后的请求到来时自然也就没有库存了,因此根本到不了最后的下单步骤,所以真正的并发写就非常有限了。


2.3 分时间段进行产品上架处理

其实处理高并发访问还有两种常见手段: 静态化、集群


静态化: 分布式缓存是为了解决数据库服务器和 Web 服务器之间的瓶颈,如果一个网站流量很大这个瓶颈将会非常明显,每次数据库查询耗费的时间将不容乐观。对于更新速度不是很快的站点,可以采用静态化来避免过多的数据查询,可使用 Freemaker 或 Velocity 来实现页面静态化。


集群: 使用多台服务器去处理并发请求


3 系统架构介绍

基于以上几点高并发的处理方案,我们本次所设计的 12306 后端系统架构如下所示。


3.1 数据同步架构

383138344a0d42c0aa2fb327ab7e30f8.png

系统管理员通过后台管理系统基于一些基础数据(座位数据,列车车次数据,乘车计划数据)生成指定日期的乘车计划数据。然后我们通过 logstash


将生成的数据同步到 ES 和 Redis 中。

Logstash 常见的数据获取方式 拉,推。上述架构给大家展示的是拉的模式,但是这种方式我们当前这个系统环境中不太适合,原因是因为我们使用了 MyCat 进行分库分表的处理,而 Logstash 在进行拉取数据的时候如果数据量较大我们就需要进行分页拉取,那么此时 Logstash 就会生成类


似这样的一条 sql 语句:select count(*) as count from …来查询满足条件总条数,但是这个 count 别名使用了反引号,而这个 反引号在 MyCat 中无法使用,因此就会产生异常。

因此本次我们在进行数据同步的时候使用的是 Logstash 的推模式进行数据同步,如下所示:

479245469828411da57e370490f2aaa2.png


3.2 数据搜索架构

数据同步完毕以后,用户就可以搜索相关的乘车计划数据了。具体的搜索架构如下所示:


88615cf4a49b4712b388da137929d41c.png

3.3 用户下单架构

通常订票系统要处理 生成订单、减扣库存、用户支付这三个基本的阶段,我们系统要做的事情是要保证火车票订单不超卖、不少卖,每张售卖的车票都必须支付才有效,还要保证系统承受极高的并发。

这三个阶段的先后顺序改怎么分配才更加合理呢?


3.3.1 方案一:先扣库存在支付

cf77dbf26df24eaf85b5bfe76b9d5db5.png

当用户并发请求到达服务端时,首先创建订单,然后扣除库存,等待用户支付。这种顺序是我们一般人首先会想到的解决方案,这种情况下也能保证订单不会超卖,因为创建订单之后就会减库存,这是一个原子操作。

存在的问题:

1、就是在极限并发情况下,任何一个内存操作的细节都至关影响性能,尤其像创建订单这种逻辑,一般都需要存储到磁盘数据库的,对数据库的压力是可想而知的;

2、存在如果用户存在恶意下单的情况,只下单不支付这样库存就会变少,会少卖很多订单。


3.3.2 方案二:支付完减库存

d7a16521214649d08f177a97d23ea8a3.png

如果等待用户支付了订单在减库存,第一感觉就是不会少卖。但是这是并发架构的大忌,因为在极限并发情况下,用户可能会创建很多订单,当库存减为零的时候很多用户发现抢到的订单支付不了了,这也就是所谓的" 超卖", 并且这种方案也不能避免并发操作数据库磁盘 IO。


3.3.3 方案三:引入消息队列

从上边两种方案的考虑,我们可以得出结论:数据库只要创建订单,就要频繁操作数据库 IO。那么有没有一种不需要直接操作数据库 IO 的方案呢,这就是预扣库存。先扣除了库存,保证不超卖,然后异步生成用户订单,这样响应给用户的速度就会快很多;那么怎么保证不少卖呢?用户拿到了订单,不支付怎么办?我们都知道现在订单都有有效期,比如说用户五分钟内不支付,订单就失效了,订单一旦失效,就会加入新的库存,这也是现在很多网上零售企业保证商品不少卖采用的方案。订单的生成是异步的,一般都会放到 MQ(消费队列)中处理,订单量比较少的情况下,生成订单非常快,用户几乎不用排队。如下图所示:

0185a93f34144f1cb0552eb63c24c86a.png

这种方案也就是单杏花主任所提出的异步交易排队系统。当然 12306 网站的还有一个改造的关键技术 建立可伸缩扩展的云应用平台 台。根据互联网上的新闻,中国铁道科学研究院电子计算技术研究所副所长,12306 网站技术负责人朱建生说,为了应对 2015 年春运售票高峰,该网站采取 5 项措施:

一、利用外部云计算资源分担系统查询业务,可根据高峰期业务量的增长按需及时扩充。

二、对系统的互联网接入带宽进行扩容,并可根据流量情况快速调整,保证高峰时段旅客顺畅访问网站。

三、防范恶意抢票,通过技术手段屏蔽抢票软件产生的恶意流量,保证网站健康运行,维护互联网售票秩序。

四、制定了多套应急预案,以应对突发情况。


4 下单流程

de0b6a523581486699298146b195cb17.png

MQ异步生成订单数据到mysql,redis是主要控制库存的方式,如果订单失效就会退回到redis库存

相关实践学习
基于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
目录
相关文章
|
4月前
|
存储 监控 固态存储
在高并发环境下,如何优化 WAL 的写入性能?
在高并发环境下,如何优化 WAL 的写入性能?
|
2月前
|
存储 监控 固态存储
在高并发环境下,如何优化 WAL 的写入性能?
在高并发环境下,如何优化 WAL 的写入性能?
|
5月前
|
消息中间件 算法 数据库
架构设计篇问题之商城系统高并发写的问题如何解决
架构设计篇问题之商城系统高并发写的问题如何解决
|
2月前
|
Java Go 云计算
Go语言在云计算和高并发系统中的卓越表现
【10月更文挑战第10天】Go语言在云计算和高并发系统中的卓越表现
|
2月前
|
缓存 监控 负载均衡
nginx相关配置及高并发优化
Nginx的高并发优化是一个综合性的过程,需要根据具体的业务场景和硬件资源量身定制。以上配置只是基础,实际应用中还需根据服务器监控数据进行持续调整和优化。例如,利用工具如ab(Apache Benchmarks)进行压力测试,监控CPU、内存、网络和磁盘I/O等资源使用情况,确保配置的有效性和服务的稳定性。
156 0
|
4月前
|
存储 缓存 安全
.NET 在金融行业的应用:高并发交易系统的构建与优化之路
【8月更文挑战第28天】在金融行业,交易系统需具备高并发处理、低延迟及高稳定性和安全性。利用.NET构建此类系统时,可采用异步编程提升并发能力,优化数据库访问以降低延迟,使用缓存减少数据库访问频率,借助分布式事务确保数据一致性,并加强安全性措施。通过综合优化,满足金融行业的严苛要求。
59 1
|
4月前
|
监控 算法 Java
企业应用面临高并发等挑战,优化Java后台系统性能至关重要
随着互联网技术的发展,企业应用面临高并发等挑战,优化Java后台系统性能至关重要。本文提供三大技巧:1)优化JVM,如选用合适版本(如OpenJDK 11)、调整参数(如使用G1垃圾收集器)及监控性能;2)优化代码与算法,减少对象创建、合理使用集合及采用高效算法(如快速排序);3)数据库优化,包括索引、查询及分页策略改进,全面提升系统效能。
55 0
|
5月前
|
消息中间件 缓存 监控
如何设计一个秒杀系统,(高并发高可用分布式集群)
【7月更文挑战第4天】设计一个高并发、高可用的分布式秒杀系统是一个非常具有挑战性的任务,需要从架构、数据库、缓存、并发控制、降级限流等多个维度进行考虑。
154 1
|
6月前
|
存储 NoSQL Java
探索Java分布式锁:在高并发环境下的同步访问实现与优化
【6月更文挑战第30天】Java分布式锁在高并发下确保数据一致性,通过Redis的SETNX、ZooKeeper的临时节点、数据库操作等方式实现。优化策略包括锁超时重试、续期、公平性及性能提升,关键在于平衡同步与效率,适应大规模分布式系统的需求。
199 1
|
5月前
|
设计模式 存储 缓存
Java面试题:结合建造者模式与内存优化,设计一个可扩展的高性能对象创建框架?利用多线程工具类与并发框架,实现一个高并发的分布式任务调度系统?设计一个高性能的实时事件通知系统
Java面试题:结合建造者模式与内存优化,设计一个可扩展的高性能对象创建框架?利用多线程工具类与并发框架,实现一个高并发的分布式任务调度系统?设计一个高性能的实时事件通知系统
64 0