背景
12306最大的特点就是峰值流量。12306平常一天的PV(page views)值大约是在 2500万到 3000万左右, 在2015年春运高峰日的PV值是297亿,流量增加1000倍,这样海量的请求,假如不能在短时间内动态调整网络带宽或增加服务器数量,就会造成网络阻塞或是服务器性能无法满足要求,甚至使整个系统不稳定。更何况这些流量中的购票甚至不是在这天均匀分布的,而是集中在放票后的几秒到几分钟内。12306采用集中放票方案。2019年把四个时间点放票改成了全天工作时间每半小时放票。12306的抢票插件曾经拖垮了github(当然这也不证明github水平差,只是毫无准备)。
12306的另外一个特点就是查询流量远远多余购票流量。12306在抉择中抛弃了实时展示余票的方案,而是采取定时刷新的办法(十分钟间隔)。
12306还有一个特点,每天23点至次日6点期间。12306系统会进行数据整理和维护,来保证系统明天能够从完美的状态开始运行。
12306和普通抢购系统的另一大差别是商品之间的关系过于复杂。卖出一张票,要同时更新整个线路的票务信息。但是这句话我一直表示高度怀疑。经常会发生半程票没有只卖全程票的情况。我觉得很有可能在春运期间,12306简化了出票的逻辑,默认只卖全程票。
架构变迁
12306互联网售票系统在2011年下半年开始上线使用(Unix小型机架构),但在2012年春运期间引发无数的争议。在2012年春运后,12306项目承接单位与多家IT公司联系,经过多次论证和POC 测试, 最终引入分布式内存运算数据管理云平台 - Pivotal Gemfire做试点,用以提高12306系统性能,解决“高流量和高并发“的难题。
GemFire(其实就是增强和商业版本的)Redis
Ø 多种网络拓扑
Ø 高并发的内存数据结构,避免锁争夺
Ø 可选的ACID
Ø 序列化(native serialization)和智能缓冲(smart buffering)保证消息快速分发
Ø 同步或异步写磁盘
Ø 冗余内存拷贝
通过云计算平台虚拟化技术,将若干X86服务器的内存集中起来,组成最高可达数十TB的内存资源池,将全部数据加载到内存中,进行内存计算。计算过程本身不需要读写磁盘,只是定期将数据同步或异步方式写到磁盘。GemFire在分布式集群中保存了多份数据,任何一台机器故障,其它机器上还有备份数据,因此通常不用担心数据丢失,而且有磁盘数据作为备份。GemFire支持把内存数据持久化到各种传统的关系数据库、Hadoop库和其它文件系统中。
简单比喻下Scale out和Scale up,帮助我们理解:
Scale Out,比如:我们向原有的web、邮件系统添加一个新机器。
Scale UP,比如:我们向原有的机器添加CPU、内存。
2015年,12306把查询流量迁移到了阿里云上。