12306 如何做到尖峰日 PV 值 297 亿下每秒出票 1032 张

转载声明:
作者:刘云程 (YC),技术总监,任职于资拓宏宇(上海)公司,主要负责提供客户应用系统升级, 迁移到高性能和高扩展性的“云应用平台”。 刘云程毕业于台湾清华大学,在美国拿计算机博士,于 1994 年由 IBM 外派到北京。他在 IT 行业有近 30 年工作经验,曾任职于 IBM 中国研究中心负责电子商务和移 动互联网方面的研究。
原文链接:https://www.csdn.net/article/2015-02-10/2823900

前言:

12306 互联网售票系统在 2011 年下半年开始上线使用,但在 2012 年春运期间引发无数的争议。在 2012 年春运后,12306 项目承接单位与多家 IT 公司联系,经过多次论证和 POC 测试, 最终引入分布式内存运算数据管理云平台 - Pivotal Gemfire 做试点,用以提高 12306 系统性能,解决“高流量和高并发“的难题。

高流量高并发是指某特定时间段的海量请求,根据过去的经验法则,高并发是指访问流量是平常流量的 3-5 倍;但由于互联网和移动设备 apps 的普遍化,电商网站的促销模式“11.11“,或是厂商的“饥饿营销“,都会衍生“秒杀“现象。所以过去的经验法则用到 12306 春运售票系统,往往是远远低于实际的的流量。例如,12306 平常一天的 PV(page views)值大约是在 2500 万到 3000 万左右, 在 2015 年春运高峰日的 PV 值是 297 亿,流量增加 1000 倍,这样海量的请求,假如不能在短时间内动态调整网络带宽或增加服务器数量,就会造成网络阻塞或是服务器性能无法满足要求,甚至使整个系统不稳定。

12306 成长之路

短短的 3 年,从 2012 年春运到 2015 年春运,12306 网站从 10 亿的 PV(page views)值增加到 297 亿 PV 值,PV 值成长 30 倍;网络带宽从 1.5G 调整到 12G,带宽成长 8 倍;而 12306 的售票量从 110 万增加到 564 万 ,成长 5 倍。出票处理能力从 每秒 200 张提升到 每秒 1032 张,也是 5 倍的成长。

PV 值的增加是与放票的次数和可出售的票量有关系,例如,2015 年 PV 值是 2014 年的 2.3 倍, 原因是放票次数多了 5 次“秒杀”,另外增加 12% 的售票量。由此可见,互联网流量 PV 值的增加速度远远高于售票量增加的速度。

f515acddad884e0c8a3d1e34f7d86326.png

高流量除了代表网络容易造成阻塞以外,系统服务器也会面临更高的 CPU 负载,在此情况下又该如何应对呢?是选择基于原来系统框架上购买更昂贵的硬件做“scale up“升级呢 ?还是选择购买低成本的 x86 服务器,进行”可扩展云平台架构“ scale out 的改造设计呢?12306 互联网购票系统的改造给我们一个很好的案例参考,也让政府单位和企业进一步了解了具体是如何实现的。

12306 改造的关键技术– 建立可伸缩扩展的云应用平台

2015 年 12306 网站顺利过关,没有“瘫痪”,是值得庆祝的。根据互联网上的新闻,中国铁道科学研究院电子计算技术研究所副所长,12306 网站技术负责人朱建生说,为了应对 2015 年春运售票高峰,该网站采取 5 项措施:一是利用外部云计算资源分担系统查询业务,可根据高峰期业务量的增长按需及时扩充。二是通过双中心运行的架构,系统内部处理容量扩充一倍,可靠性得到有效保证。三是对系统的互联网接入带宽进行扩容,并可根据流量情况快速调整,保证高峰时段旅客顺畅访问网站。四是防范恶意抢票,通过技术手段屏蔽抢票软件产生的恶意流量,保证网站健康运行,维护互联网售票秩序。五是制定了多套应急预案,以应对突发情况。

“利用云计算资源“,“按需及时扩充“和”快速调整“,这几个字眼是 12306 改造的精神,其核心就是要建立一个从下到上全面“可伸缩扩展的云平台”。底层的硬件架构要支持可伸缩扩展,上层的应用系统架构也需要支持可伸缩扩展。

  1. 在过去数年,云计算的基础架构虚拟化已经非常成熟,也日益普遍部署;当网络阻塞时,可以动态增加带宽,当服务器 CPU 到达高位时,可以快速从资源池获取虚拟机资源来分摊负荷。 “软件定义的数据中心“ 可以轻易完成这些伸缩性扩展的配置。

  2. 当客户将底层的架构都虚拟化后,网络设备,Web 服务器,应用服务器都可以做“伸缩性”的扩展;但遇到一个难点就是“12306 的应用系统框架”无法支持可伸缩扩展。原因是关系型数据库 Sybase 无法支持“应用系统”的伸缩扩展。

  3. 客户在过去数年已经投入大笔经费在 IT 方面的建设,但“系统框架设计”还是沿用 10 几年前的三层设计,而且每年都在原来的基础上做不断的升级。当业务不断成长时,数据量也跟着成长,功能越来越多, 但系统性能越来越差。客户该如何选择呢 ?是 scale up? 还是 scale out ?

为什么选择 Pivotal Gemfire 构建 12306 的云应用平台?

要解决 12306 春运时高流量高并发的问题,如果单靠硬件升级解决的话,可能需要扩充数十倍的硬件服务器。但在春运以后,又该如何解决服务器过剩的问题呢?

要真正解决“高流量,高并发“的难题是需要从软件和应用系统层面出发,唯有实现“可扩展的应用云平台架构”,灵活和快速热部署的机制,才是真正解决高并发访问的根本。

在经过多次论证和 POC 测试后, 12306 最后选择 Pivotal Gemfire 作为系统改造的平台,其主要原因如下:

  1. 关联数据节点设计:可以根据客户的业务逻辑特性和数据关联性,将关联性强的数据放置于同一个服务器节点,提高系统性能,避免分布式系统服务器的频繁数据交换。

  2. 将数据移到内存:由于数据是放在内存里面,屏蔽传统数据库频繁访问, CPU 与数据库的交互作用,影响服务器性能。内存的数据交换速度远高于磁盘速度上千倍, 极大提高系统性能。

  3. 扩展和伸缩性:以 Gemfire 构建的应用云平台,是以 x86 PC 服务器为主的硬件基础。在保证系统的性能下,此平台可以随着客户业务的成长来任意调配 x86 服务器的数量,避免以后昂贵的硬件升级带来的困扰。经 POC 测试结果显示,整个系统性能可随着服务器的数量的增加实现几乎线性的成长。

  4. 数据可靠性:在同个集群里面可以有多个数据节点备份,数据可以自动同步,或是将内存数据持久化到硬盘或是数据库

  5. 跨地域的数据分布或同步 :可以透过“广域网”将指定的 Gemfire 集群的内存数据“实时同步”到异地的数据中心。这是属于“应用层”的数据同步异于传统的“数据库”同步。

  6. Pivotal Gemfire 使用 x86 PC 服务器,其性价比远远高于 Unix 小型机。

在后续章节,以 12306 为案例做进一步分析,使用 Pivotal Gemfire 会给 12306 带来什么好处。

回顾 12306 成长的烦恼

(1)网络阻塞是个门槛

网络是进入 12306 征程的起点,网络带宽快慢往往决定“秒杀“的结果,这在很多电商网站促销时时常发生, 因此 12306 也无法避免。下面数字是由互联网收集得到的,可能有偏差。但我们尽可能根据这些数目字来解析数年来网络原因发生的问题。

  • 2012 年:12306 第一次在春运使用, 网络带宽 1.5G,可以支持最大的 PV 值是 11,250;根据报导,此系统有 10,000 人的登陆限制, 假如每人每秒点击一次的话,理论上是可以勉强支持正常的点击量。

但在购票尖峰日,有上千万的网民第一次上网购票,在无法登陆的情况下, 用户不断刷取首页,或是已登陆者无法得到系统的及时反应,不断点击页面,产生大量的请求,造成网络和系统的高负载,导致崩溃。

  • 2013 年 :宽带增加一倍到达 3G 频宽,有 20 万用户登陆的限制,采取 10 次放票,分散流量,防止买票过度集中;但不幸的是“刷票软件”横行,每秒可以刷票数十次到数百次,高峰期有 25 万的 PV 值, 远远超过带宽的最大理论值 22,500 PV。

  • 2014 年 : 宽带增加到达 5G,16 次放票,有屏蔽刷票软件抢票的设计,有效阻挡 90% 的点击,但实名制有漏洞,每秒还是有 15 万次的浏览需求,远超过 37,500 PV 的的理论带宽承载量。

  • 2015 年 : 12306 有 21 次放票,增加带宽到 12G,手机订票(流量小)分担 25% 的 12306 售票,解决实名制的问题,可以阻挡 95% 刷票软件的点击量,每秒最大有 117,800 次的浏览请求,此数目字已经很接近理论带宽承载量 117,400 PV 值。

根据上述解析, 2012 年 – 2014 年春运的网络带宽给 12306 带来很多问题。根据网民的反应,在 2015 年 12306 带宽在 12G 的情况下,虽然稍微有点卡, 但是大致的反应还是不错的。此轮点与我们的推论是大致符合。

5c5061f479ad4b4a8d490aba2eb82eea.png

  1. PV 值和放票次数是根据互联网的报导。

  2. 2013 年与 2014 年的 PV 值有 10 倍的差异, 2014 年多了 6 次放票时段,票的出售量增加 90%。但在 2013 年,极有可能是大部分的票量集中在少数时段就放完,减少多次的“秒杀“发生。

  3. 2012 和 2013 年, 12306 没有屏蔽抢票软件的设置。在 2014 年以后,实现了基本的屏蔽功能。 假设此在 2014 年可以阻挡 90% 抢票软件的点击, 在 2015 年可以阻挡 95% 的点击。

  4. 在 2015 年, 假设互联网的平均 PV 值的数据量是 15K byte, 手机上网的 PV 值是 1K byte,占有 25% 的流量。

  5. 带宽最大理论 PV 值 / 秒 : 1G 的带宽是 1,000,000,000 bit/second,1 byte = 8 bits.

2015 年平均 PV 值 =11.5K byte (含手机上网), 2012-2014 年的 PV 值 = 15K bytes。

另外,假设考虑网络 IP 协议交换有 10% 的损耗。

  1. 浏览请求最大 PV 值 / 秒:假设在每个放票时段,抢票的高峰期是 5 分钟(含查询, 下单,付款等操作),在高峰期 5 分钟的下载流量是整个时段下载总量 50%;

再假设有效的浏览下载量是 5% 上传的请求点击量,换句话说,有 95% 的点击量被屏蔽,可能是阻挡刷票软件,或是网络阻塞丢包,或是系统忙碌没有反应等等。

**(2)服务器集群性能无法伸缩性扩展 **

参考互联网上的资料,12306 服务器集群是传统的三层架构设计,如果不考虑最前端的 F5 负载均衡服务器,它是由 数百部 Web 服务器集群和应用服务器集群构成前端,64 部数据库小型机集群(用于专门实现并行计算每班车次的余票量),和订单处理服务器集群构成后端。从专业的角度来看,此种框架设计是中规中矩的,国内 99% 的框架设计师都是如此设计。

如前述所提,由于 Sybase 数据库的原因,此种设计无法做伸缩性的扩展。因此,12306 要进一步提高性能就面临很大的抉择。在此,先了解服务器集群性能与实际需求之间有多少差距。

回顾 2012 年到 2015 年,12306 系统在这 3 年内有很大的变化。

  1. 2012 年春运 :根据互联网上的信息,2012 年 12306 设计的售票指标是在 100 万张票的销售,这完全低估了互联网网民的实际需求,在尖峰日,有上千万人登陆。网络带宽,Web 服务器集群,应用服务器集群,余票查询 / 计算集群, 到订单处理集群, 这些设备性能完全无法应付高流量高并发的请求。由于极大的低估互联网的需求,造成 12306 整个系统不稳定。

在 12306 系统,余票查询 / 计算子系统是最复杂的, 最耗损服务器 CPU 资源。在整个客票系统里,有数十条行车路线,有 3000 多个车次(G,D,K,Z,C,..),5000 多个火车站,不同的席次(硬座,硬卧, 软座, 软卧, etc),座位等级 (商务, 一等, 二等),和车票等级(一般,军人, 学生,残障,小孩)等因素,将这些参数换算成数学模型,那可是有数千亿条的排列组合。

2012 年的余票计算系统实际处理能力据估计不会超过 300-400 TPS,而有效的余票查询请求远远高于 3000 QPS (query per second)。另外,系统每隔 10 分钟更新车次的余票,这些余票信息是没有参考价值,因为在 10 分钟里已经售出数十万张票。如果要满足余票计算的需求达到至少 3000 TPS, 那么 12306 需要再增加 6 倍的服务器,即将近 400 部小型机(原有系统有 64 部服务器)。

  1. 2013 年春运:在 2012 年 6 月进行第一步余票查询 / 计算改造,使用 Pivotal Gemfire 改造后的结果是每秒至少支持 10,000 TPS 以上,此数目字已经足够应付高并发的需求,因此在 2013 年春运余票查询顺利过关。 由于集群计算能力大增,余票更新缩短到每隔 2 分钟提供最及时的信息。

在余票查询瓶颈移除后,订单处理服务器的瓶颈就出现在订单排队,网民必须等待数十秒到数十分钟才会得到订单的确认。订单的请求累积高达数千甚至数万个以上,估计当时订单处理服务器的处理能力不超过 200-300 TPS。

  1. 2014 年:在 2013 年后,进行“订单分库二级查询”处理,将订单生成与订单查询分开处理。因为订单查询的数量远远超过订单生成的数量。因此, 12306 将查询订单的热点数据放在 Gemfire 集群, 将历史订单数据放在 Hadoop 集群。如此设计,不但提高订单查询的功能数十倍,而且订单生成的性能至少也提高 5 倍以上(使用原有服务器)。

  2. 2015 年:进一步使用 Gemfire 优化整个 12306 系统,总共建立 5 个 Gemfire 集群。另外建立三个数据中心(高铁公司, 铁科院,和阿里云),在阿里云上部署数百个虚拟机(有 Web 服务器,应用服务器,和余票查询服务器集群)分流余票查询 75% 的流量,因为余票查询流量占据 12306 整体流量的 90%。

b364ca8528ee495e82ca54fe823e7850.png

在 12306 系统,余票计算的结果是放在“数据缓存应用服务器”,在 2012 年每隔 10 分钟更新每班车次的余票结果。如果新请求与上次更新的时间间隔低于 10 分钟,数据缓存系统就直接返回上次计算的结果。而在 10 分钟左右再重新计算新的请求。在 10 分钟的间隔,服务器集群需要计算 3000 多个车次的余票结果。自 2013 年以后,12306 系统每隔 2 分钟更新车次余票结果。

使用 Gemfire 改造后 12306 的现状和启示

2015 年的春运购票期间 12306 系统的表现是很令人瞩目的,它的效果和影响总结如下:

  1. 提供“高并发,低延迟”的解决方案,一劳永逸,不用烦恼后续硬件升级的问题

  2. 通过 GemFire 多集群技术,实现多重的高可用性,确保高峰压力下和系统异常的情况下保证业务的持续性。

  3. 构建一个可扩展的云应用平台架构,灵活和快速热部署的机制,为未来混合云的部署打基础。

  4. 余票查询集群性能提升 :

  • 使用数十部 x86 服务器 (或是上百部虚拟机)可以达到 10,000 TPS 以上,提升原来系统性能达 30 倍以上。原来的系统是使用 64 部 Unix 小型机。
  • 余票信息更新从原来 10 分钟缩短到 2 分钟,使信息更有参考价值。
  1. 12306“订单分库二级查询”子系统:
  • 将订单生成与订单查询分库处理,订单查询性能提高 50 倍, 订单生成性能提高 4-5 倍。
  • 将热点订单放在 Gemfire 集群,将历史订单数据放在 Hadoop 集群。这是快数据和大数据结合的完美案例。
  1. 混合云的应用:
  • 使用 Gemfire 改造后的分布式系统,极易分散部署到不同的数据中心
  • 例如,余票查询子系统可以独立于原来的大系统部署到公有云上,同时也可以再将此子系统一分为二,将另一部分服务器部署在私有云的数据中心。即按业务需求随时部署所需要的资源,来解决高并发的难题。