12306的“能”与“不能”:春运买票难何时有解?
每年的春节是中国人的传统节日,大多数中国人都会在这一天选择回家团聚。然而,历年春节假期,巨大的访问请求都让中国铁路客户服务中心网站(www.12306.cn)陷入“万劫不复”。根据新浪的调查,去年春节,有近90%的网友表示12306网站缓慢、页面崩溃,严重影响正常购票。
世界级的人口迁徙带来了一个世界级的难题:要如何通过网络,把火车票及时卖给有需要的人?
中国人回家 世界级难题
铁道部在线车票发售网站12306基本不存在大量图片、视频这些占带宽资源的东西,所面临的主要问题就是数据库的高并发量——用中国的人口基数来算,这是一个极为恐怖的并发量,在车票发售的高峰时间点,向12306发起的并发请求数量大得就像一场国家规模的DDOS攻击。
中国铁路客户服务中心网站(www.12306.cn)是世界规模最大的实时交易系统之一,媲美Amazon.com,节假日尤其是春节的访问高峰,网站压力巨大。据统计,在2012年初的春运高峰期间,每天有2000万人访问该网站,日点击量最高达到14亿。
而到了去年春节期间,12306的网站订票系统系统峰值负载达2.6万QPS(每秒钟2.6万次访问请求)或11万TPS(TPS指每秒服务器处理、传输的事物处理个数,一条消息输入、一条消息输出、一次数据库访问,均可以折算成TPS),与去年淘宝双11活动峰值负载基本相当。然而,12306面临比淘宝更严重的问题—— 数据关联度。
淘宝的“双11秒杀”活动数据关联度本质上并不大,因为订单之间本身并不存在多少关联,淘宝可以用离散度较大的分布式计算架构,把负载一点点分离出去。
铁路票务系统的负载与普通B2C网站有着本质的不同,整条线路上每个车站、座位之间是密切关联的
但12306不同, 售票系统每出一张票都要对全线路做数据更新(因为一条线路存在多个站点),车票数据之间存在互相关联,“牵一发而动全身”,系统的负载集中很多,直接搬运淘宝的分布式计算方案难以解决问题。
将问题放大到全球,答案也是一样的:谷歌拥有独步天下的分布式计算技术,但它同样是一个离散的架构,分布于全球各地的“谷歌服务器农场”的数据库每天仅需要同步2~3次数据,直接搬到12306来用,恐怕也是败走麦城。
放眼世界,还没有哪一家网站面临12306这样的窘境: 访问请求大,I/O负载重,时间段分布不均衡。12306要解决问题,必然无法照搬现有的成功经验。
为解决12306网站的主要瓶颈——余票查询系统,从2012年中开始,中国铁道科学院电子计算技术研究所找来IBM、阿里巴巴等大企业寻求解决方案,给出的条件是资金管够但是问题得解决,但几大企业最后都拒绝了。
几番折腾之后,铁道部发现市面上可以买到的成套解决方案都不足以应付春运购票负载,所以只好开始尝试自行改进现有数据库来解决问题。
问题解决了一半:车票查询速度提高75倍以上
2012年3月开始,铁路总公司(原铁道部)开始调研、改造12306。2012年6月选择了 Pivotal GemFire分布式内存计算平台(Distributed In-memory computing)改造12306,由铁科院项目小组负责人王明哲主任和资拓宏宇(IISI)信息科技有限公司在铁科院主管朱建生所长领导下提供技术实施。按照计划,一期工程最先改造的是12306的主要瓶颈——余票查询系统。
12306的老系统所使用的是HP Superdome小型机,使用UNIX操作系统,Sybase ASE数据库,在历届春运期间被发现性能严重不足,遂改用x86系统+linux平台。
2012年9月份,12306完成代码改造,系统上线。2012年国庆,又是网上订票高峰期间,很多人发现,登录12306变得容易了,虽然还是很难订票,但是查询余票很快。2012年10月份,二期用GemFire改造订单查询系统(客户查询自己的订单记录)上线。2013年春节,又是网上订票高峰期间,大家发现登陆12306查票简单多了——虽然还是很难订到票,但是查询余票很快,而且查询自己的订票和下订单也很快。
据介绍,12306目前最核心系统用了 十几个节点的多路Xeon E7服务器,每个节点配1TB内存,将数据库全部放到内存中运行。根据系统运行数据记录,技术改造之后,12306只用十几台x86服务器就实现了以前数十台小型机的余票计算和查询能力,单次查询的最长时间从之前的15秒左右下降到0.2秒以下,缩短了75倍以上。在改造之后,支持每秒上万次的并发查询,高峰期间达到2.6万个查询/秒吞吐量,整个系统效率显著提高。
订单查询系统改造,在改造之前的系统运行模式下,每秒只能支持300-400个查询/秒的吞吐量,高流量的并发查询只能通过分库来实现。改造之后,可以实现高达上万个查询/秒的吞吐量,而且查询速度可以保障在20毫秒左右。
并且,新的技术架构可以按需弹性动态扩展,并发量增加时,还可以通过动态增加X86服务器来应对,保持毫秒级的响应时间。
至此,虽然高峰期买票还是难,但你可以认为,12306的技术问题已经解决了一半。
技术一步跨越三代:GemFire是如何搞定麻烦的?
12306能够取得这样翻天覆地的效果,靠技术上的小修小补是不可能的,必须有全新的思路,能够给性能提升带来杠杆式的作用,GemFire分布式内存数据平台就是这样一种技术。
GemFire分布式内存数据平台的技术原理如上图所示: 通过云计算平台虚拟化技术,将若干x86服务器的内存集中起来,组成最高可达数十TB的内存资源池,将全部数据加载到内存中,进行内存计算。
这样改造后,整个数据库的访问过程本身不需要读写磁盘,只是定期将数据同步或异步方式写到磁盘,最大程度利用了DRAM内存速度快、吞吐大的优势。
GemFire在分布式集群中保存了多份数据,任何一台机器故障,其它机器上还有备份数据,因此通常不用担心数据丢失,而且有磁盘数据作为备份。GemFire支持把内存数据持久化到各种传统的关系数据库、Hadoop库和其它文件系统中。
大家知道,当前计算架构的瓶颈在存储,处理器的速度按照摩尔定律翻番增长,而磁盘存储的速度增长很缓慢,由此造成巨大高达10万倍的差距(如下图),数据库在内存中运行和在磁盘中运行,性能差距可达上万倍。 用通俗的话来说,GemFire分布式计算实际上是用内存打造了一个超大的“硬盘池”,来运行数据库,这样你就能很好理解为什么性能差距是如此之大了。
按照Pivotal官方的说法,计算与存储的关系,可以简单划分为四代:
第一代,基于磁盘的单一系统:计算过程中需要从磁盘读取数据。小型机、大型机是其中的佼佼者,将单一系统的性能做到极致。
第二代,基于磁盘的分布式集群系统:计算过程中需要从磁盘读取数据,但通过分布系统将数据分散到不同的服务器磁盘上,提高整个系统的处理能力。目前很多大型互联网和电子商务公司采用基于X86服务器的分布式集群系统,依靠海量的X86服务器部署解决高流量并发的问题。
第三代,基于内存的单一系统:将整个数据库放在内存中,计算过程不需要从磁盘读取数据。整个系统的性能取决于单一系统的性能。传统的内存数据库就是这样的系统,对于企业级的应用可以很好地解决访问速度的问题,但面对海量数据或是海量并发访问的扩展性问题就无能为力。
第四代,基于内存的分布式集群系统:GemFire就是这样的系统,并行计算是其关键技术之一,因而可以通过增加服务器部署规模,在内存计算的基础上,线性扩展性能。
12306之前采用Unix小型机架构,采用GemFire技术改造成Linux/X86服务器集群架构,就意味着一下跨越三代。从小型机到大内存X86服务器集群,不仅让性能提升了一个数量级,而且成本也要低得多。
中国铁道科学研究院电子计算技术研究所副所长朱建生表示,“通过技术改造解决了困扰我们多时的尖峰高流量并发问题,让全国人民不再因为技术原因而抱怨,我们终于舒了一口气。Pivotal GemFire分布式集群内存数据技术对整个技术改造发挥了关键的作用。”
“买票依旧难”,问题的另一半何时能解?
让我们回到最初的问题。2013年春节,依然有近90%的网友表示12306网站缓慢、页面崩溃,严重影响正常购票。这是为何?GemFire分布式计算技术没有起效吗?答案是否定的。
恰恰相反,网友依然不满12306的原因是GemFire还做得不够。事实上,GemFire改造的仅仅是12306的后台数据库系统,网站的前端和UI(被网友反映崩溃最多的罪魁祸首)依然臃肿陈旧,这些被诟病的问题并未得到及时解决。这就是我们写下“问题只解决了一半”的原因所在。
另外,网络购票,铁道部的订单系统也是瓶颈所在(反映到购票流程里就是“出票”这个过程)。 车票也是一种商品,购买行为是要发生支付关系的,这就牵涉到更加复杂的支付渠道和财务结算问题,远远超出了GemFire一个票务数据库的“管辖范围”之内。
我们在这里先提出一个假设:假定12306的数据库、前端、UI、出票流程全部都用现代化技术完成改造,这样就能拯救归心似箭的我们吗?很可惜答案依然是否定的。
这样的结果只有一个——用户原本需要花几小时断断续续刷网站的体验,变成“秒杀”——没错,假设系统能力变成无限大,足以实时响应春运时全部用户的全部鼠标点击,绝不崩溃,后果就是车票瞬间抢空。你看到的,将是一个到达放票时间后,迅速告诉你“没票”的网站。
“买票难”问题的本质是春运期间铁路运力的整体不足,作为一个客户服务网站,12306的性能无论怎样优化,用户买到票的概率都不会提升。所以,即使技术强大到12306永不崩溃,也无法保证让所有网友都按时坐上回家的火车。
要解决“买票难”,合理规划城镇化进程、科学统筹交通等基础设施建设、着重解决区域经济发展不平衡等,都是需要考虑的问题。而这些,就不属于本文讨论的范畴之内了。