西西河

主题:【原创】身为码农,为12306说两句公道话 -- 代码狗

共:💬137 🌺892 🌵3 新:
分页树展主题 · 全看
/ 10
下页 末页
  • 家园 【原创】身为码农,为12306说两句公道话

    我曾在淘宝写过一段时间代码,2012年在一家百强民企做电商副总,当时在极为艰苦的条件下带队开发了一个B2C网站,走支付宝和银联支付通道,年营业额千万级(当然实在太少了,我只是说这个网站投入了实际的运营)。

    也就在那个时候,我对12306嗤之以鼻,觉得他们做得太烂了,认为自己能带队花几百万半年时间做个好的出来。于是我狂妄地想做一个开源的订票系统给他们。我花了一个星期时间思考建立数据模型,思考到库存这一步的时候,我才发现,12306的库存复杂性比淘宝、京东高很多倍,运算量也大很多倍。传统的分布式数据库、缓存、负载均衡技术并不能恰好满足12306的需求。

    在平时,12306也就是个正常的电商网站。但一到黄金周,12306就是一个全站所有商品都秒杀,所有SKU都是动态库存的变态。

    即使不考虑线下既有的电话、代售点等渠道,要实现一个12306,最少最少也是千万级别的硬件投入(这是当时的估算,没有精算,可能与实际相差较大,总之,我说得不一定对,12306的业务也许没我说的那么复杂,但也绝不是某些人喷的那么简单),软件和人力另算。那些叫嚣只要40台服务器、只要2个架构师4个程序员、大谈分库分表和前端CDN的人们,只是纸上谈兵罢了。所谓初生牛犊不怕虎,做了三年CMS和BBS,就以这个经验来喷12306,未免太天真了。

    媒体人喷12306,是他们不懂技术,没有能力和耐心来分析背后的难度。技术人员喷,则是因为大部分的技术人员在短时间思考时,容易陷入过于乐观的误区,经典的例子就是估算工作量,程序员们往往容易估算出一个超短的工期,把写程序的工作乐观地想象成了打字员照稿敲键盘的工作。

    知乎那篇文章,我觉得不是洗地。排名第一和第二的答案都说得很客观。淘宝技术是比12306强大很多倍,淘宝现在的系统也是花了10倍于12306的钱、时间和人才做起来的。根本原因还是铁路运力不能满足春运需求,淘宝也解决不了这个问题。

    12306这一年来进步非常大。从前段动画验证码、分时段抢票,到后端去小型机、虚拟化、内存数据库的运用。可以说,12306是中国政府机关做的最强大的网站(电商系统),能在短短一两年内做出这样的改变,几乎是个奇迹,就连一些市场化的民企都望尘莫及,甚至一些上市公司都比不上它!(比如51job和ctrip)。

    事非经过不知难,在网上批判12306的人,大部分还是形成了【国企 = 垄断 + 腐败 + 低效 】的思维定势。小部分是真的轻视了它的难度。

    至于12306一期工程3个亿(含硬件)贵不贵我不评价,我只提供一个数字供参考,百度一年的研发费用(不含硬件)是10亿,这个数字来自百度财报。网上能查到。3亿看起来好大一个数字,真用到超大型的电商系统、搜索引擎系统里面,其实也不算什么天文数字了。

    再解释一下,为什么秒杀压力大,以及为什么12306的动态库存很复杂。

    先说秒杀。

    2013年12月25日前后,天猫搞了一个圣诞季积分兑换活动,持续几天。25号上午10点12分,放出了15000个天猫魔盒(淘宝集市有人卖,大概190-230块),从成交记录上看,是19秒内全部抢完。

    实际上,我也参加秒杀了,那天的题目特别简单(请输入xxx汉字的拼音首字母),我应该是5秒内答题完成并提交订单,结果告诉我排队的人太多,挤不进去,并提示14秒以后重试。人太多就是因为题目太简单了,门槛越低,5秒内挤进去的人也越多嘛,如果题目换成【2克浓度为3%的U235在大亚湾核电站能发多少度电】,5分钟之内也不会有1万5千人跟我竞争。

    我想,14秒以后哪还有我的事情呀,于是重新答题秒杀,结果出现了服务器错误的页面。反复刷新几次,就告诉秒杀结束了。

    在群里问了一下同事,有不到10个人回答我,都说没秒到(也可能秒到的人闷声发大财,不回复我)。

    淘宝是什么技术水平呢,淘宝有至少4000技术人员,至少4万台服务器(这都是两年前的公开数据了,按规定可以谈论),2013年11月11日成交额351亿,2012年全年成交额超过1万亿。

    淘宝拥有各种自主研发团队:服务器、交换机(网上可以搜索到淘宝公开的绿色服务器开放标准);操作系统(Linux Kernel taobao版,yunos手机操作系统是阿里云的,暂时不计入)、Web服务器(Tengine)、Java语言虚拟机(JVM taobao版)、数据库(MySQL内核 taobao版,google和facebook也有自己的版本,HBase淘宝版、还有自己全部从头开发的OceanBase)、负载均衡器(LVS,LVS始创人就在淘宝,担任研究员)、Java运行容器(Jboss,其创始人之一,王文彬,也在淘宝,担任副总裁)。

    淘宝还有数不清的开源项目和中间件,如高性能Java通信中间件HSF、分布式数据库中间件TDDL、异步消息系统notify等等等等。

    以淘宝这样的技术水平,也不能做到秒杀时让每个用户都没有拥挤感,为什么呢?

    一是要尊重物理原理,一台服务器一秒钟能承受的计算量是有极限的,任你怎么优化,采用多高效的算法和编程语言,都突破不了某个极限,比方说汽车发动机驱动的F1赛车至今也不能突破400公里的时速(超音速推进号那个1千多公里的时速不能算,那是飞机引擎驱动的)。再往深了说,就不容易懂了。感兴趣的可以从著名的C10K问题开始看起。

    二是要考虑经济效益,十一黄金周的时候,北京主城区到八达岭长城的路堵得严严实实,但不能因为黄金周的高峰,就把这段路修成长安街那样10车道的高速公路。否则的话,花费天文数字(真的是天文数字,12306那3个亿大概只够修1-3公里)。修了一段路,黄金周是可以飙到80公里/小时了,可平时呢,拿来给两边的居民晒谷子?

    淘宝目前的硬件和带宽数量,已经超出日常运营的需求了,就是留了相当大的余量给大促销(众所周知的是双十一,双十二,其实基本每个季度都有大促销,每个月都有促销,甚至天天都在促销——聚划算)。amazon当年就是为了应对黑色星期五的大促销购置了大量的服务器,平时订单量没那么大了,amazon就把富余的服务器拿来搞云计算了。顺便说一下,阿里云是当今中国第一世界数一数二的云计算服务商,和amazon走的路也有点像。

    再说动态库存。

    淘宝秒杀天猫魔盒的时候,只有一个商品(行话叫做SKU),它的库存是15000个。有一个人秒杀到了,库存就减1,19秒卖完的,一秒要成功产生789个订单(下订单的请求可能是8万个,只是可能啊,非实际数字,也可能是1万个,用于说明一下壮观程度)。想象一下,你在广场上卖火车票,一秒钟有8万人举着钱对你喊:卖给我!

    上过大学的人都知道,比秒小的时间单位还有毫秒、皮秒、飞秒。但交易系统登记一个交易可不像电子绕着原子核跑一圈那么简单,它要做这些事:检查是否恶意访问、取到系统时间、取到顾客默认收货地址、核对顾客秒杀资格(当时的规定是天猫T2.T3达人)、生成订单号、把顾客ID系统时间订单号收货地址写入订单系统、扣除顾客天猫积分、商品库存减一、给顾客打标记(每人只能秒一个,下次不能秒了)等等,这每一件事都要花费毫秒级别的时间,这些操作加起来的时间可能是接近1秒级别的,但由于淘宝的服务器比较强悍,而且采用了分布式和集群技术,结果比1秒理想一点。但即使有1万台服务器,也不能把这个时间稀释成万分之一秒,因为,商品只有一种,它有15000个库存,对应的数据库记录只有一行,所有的交易请求都要到这里来处理。

    能不能把这15000个拆分成5000个商品并分配到5000台服务器上呢?那样不就可以5000台服务器同时处理了吗?答案是不能,首先,5000个商品,意味着有5000个商品详情页,5000个购买按钮,这对前期的营销、引流是个灾难。基本上就没法做引流入口了,显然这违背了商业管理原则,人为增加了信息混乱程度。其次,天猫魔盒秒杀也不是啥大事,即使按官方标价399元来计算,也就6百万的交易。如果6百万的交易要花费那么大的配套成本,那就太不划算了。再次,淘宝有十几亿商品,这十几亿商品的展示交易和管理,本来就是分布到上万台服务器上去了。没有必要再把每个商品按库存拆成多个商品了。

    这789人抢到了,还不一定会付款(99积分换天猫魔盒还好一点,不需要去网银,成本也极低,大部分是会付款的,3999秒杀iPhone 5S就不一定,有人可能网银有问题,有人可能改变主意不想要了),所以就又带来订单取消重新恢复库存的问题。还有想要的消费者们,会认为还有机会,继续在前台刷一会儿,最终这个秒杀会被热情的消费者们猛刷30秒到1分钟。

    (超卖这一部分科普笔法写得有错误,鉴于12306目前全在内存数据库中读写,没有产生超卖问题,先把这个段落删去。感谢@吹西门的雪 指正)

    好了,讲了这半天淘宝,可以说12306了吧?

    我以北京西到深圳北的G71次高铁为例(这里只考虑南下的方向,不考虑深圳北到北京西的,那是另外一个车次,叫G72),它有17个站(北京西是01号站,深圳北是17号站),3种座位(商务、一等、二等)。表面看起来,这不就是3个商品吗?G71商务座、G71一等座、G71二等座。大部分轻易喷12306的技术人员(包括某些中等规模公司的专家、CTO)就是在这里栽第一个跟头的。

    实际上,G71有136 * 3 = 408种商品(408个SKU),怎么算来的?请看:

    如果卖北京西始发的,有16种卖法(因为后面有16个站),北京西到:保定、石家庄、郑州、武汉、长沙、广州、虎门、深圳。。。。都是一个独立的商品,

    同理,石家庄上车的,有15种下车的可能,以此类推,单以上下车的站来计算,有136种票:16+15+14....+2+1=136。每种票都有3种座位,一共是408个商品。

    好了,再看出票时怎么减库存,由于商务、一等、二等三种座位数是独立的,库存操作也是一样的,下文我就不再提座位的差别的,只讨论出发与到达站。另外,下文说的是理论世界的模型,不是说12306的数据库就是这么设计的。

    旅客A买了一张北京西(01号站)到保定东(02号站)的,那【北京西到保定东】这个商品的库存就要减一,同时,北京西到石家庄、郑州、武汉、长沙、广州、虎门、深圳等15个站台的商品库存也要减一,也就是说,出一张北京到保定东的票,实际上要减16个商品的库存!

    这还不是最复杂的,如果旅客B买了一张北京西(01号站)到深圳北(17号站)的票,除了【北京西到深圳北】这个商品的库存要减一,北京西到保定东、石家庄、郑州、武汉、长沙、广州、虎门等15个站台的商品库存也要减1,保定东到石家庄、郑州、武汉、长沙、广州、虎门、深圳北等15个站台的商品库存要减1。。。总计要减库存的商品数是16+15+14+。。。。+1=120个。

    当然,也不是每一张票都的库存都完全这样实时计算,可以根据往年的运营情况,在黄金周这样的高峰时段,预先对票做一些分配,比如北京到武汉的长途多一点,保定到石家庄的短途少一点。我没有证据证实铁道部这样做了,但我相信,在还没有12306网站的时候,铁道部就有这种人工预分配的策略了。

    想象一下,8万人举着钱对你高喊:卖给我。你好不容易在钱堆里找到一只手,拿了他的钱,转身找120个同事,告诉他们减库存,而这120个同事也和你一样被8万人围着;也和你一样,每卖出一个商品要找几十个人减库存。。。这就是12306动态库存的变态之处。比你平时买东西的任何网站的库存机制都复杂几十上百倍。

    再说一下抢票插件,机器永远比人快,当你好不容易从8万人里突出重围,来到了柜台前,你发现,我操,来了10万根绑着钱的竹竿,而且当有退票出来的时候,你要闯过3层人肉才能接近柜台,竹竿在8个人身后一伸,钱就到了柜台前。你低头看了一眼手机,票就没了,竹竿却永远在那里伸着,永不低头,永不眨眼。如果没有这10万根竹竿,虽然你很可能还是抢不到票,但不至于沮丧成这样:我TM为什么总是手最慢的一个?!!

    防机器人抢票,也不是加个图片验证码那么简单。我写过文章系统性分析过,图片验证码有6种机器暴力破解的办法,抢票插件用的是我说的第三种,OCR识别。Google采用的Wave波形字母已经能比较好地防住机器OCR了,ems.com.cn上的验证码就是反面教材,机器OCR成功率接近100%,12306的比ems的图片验证码强一点。不过,验证码设置得复杂一点吧,人们要喷:这只是便宜大学生和办公室白领,农民工连26个字母都认不齐,怎么搞?搞动画验证码吧,也有人喷,视力不好的人怎么办?最后验证码搞得太简单了,皆大欢喜了,其实最高兴的是开发抢票插件的公司。

    就算采用了机器完全不可能识别的验证码,也防不住社会工程学的破解办法。招募一堆网吧打游戏的青少年朋友,每成功输入50个验证码给1块钱,或者等值的虚拟货币、游戏装备,我保证想赚这个钱的人数不胜数。这点钱对转卖车票的利润而言,是可以接受的成本。有没有什么技术可以防住社会工程学的破解办法呢?能防住网吧青少年的验证码只有【2克浓度为3%的U235在大亚湾核电站能发多少度电】。

    以上讨论只是把12306当成和淘宝一样没有历史包袱从零起步的交易系统,实际上,它不是,它后面的票池,还有电话售票、火车站售票、代售点售票等多个传统渠道要服务。除了客运服务,12306还有全国最大(很可能也是全球最大)的大宗物资货运系统。

    架空政策(包括定价政策、警方打击黄牛政策、身份验证政策)谈技术,是不可能解决春运抢票困局的,要想让春运的时候每个人在12306抢票都毫无拥挤感(但不一定能抢到票,铁路运力摆在那),那就是逼着12306买一大堆服务器对付春运,春运过去后,成为跟amazon一样牛逼的云计算服务商。和逼北京修一条10车道的高速公路去八达岭长城一个道理。

    目前的12306技术上是还有问题,比如,抢票高峰,输入个身份证号和图片验证码都卡得要死(本人亲测),服务器端繁忙,你浏览器端卡什么呀。

    但人家在进步。相信2014年春运的时候,技术已经不再是一票难求的主要问题。在铁路运力不可能神速增加(孙中山先生计划的20万公里铁路,土共修了快70年,才修到10万公里)的情况下,要做到春运更公平地买票,需要停靠政策调整。

    下文针对的是春节国庆这种非常暑期。其它时期,大部分线路保持现状就行了,问题不大,极少部分票源紧张的线路可以按春运处理:

    1. 拍卖法,价高者得之

    当硬座票拍出飞机票价格的时候,相信票就不难买了(可惜就是贵了),也没有那么多黄牛了。要说淘宝有什么能帮12306一下子搞定技术问题的,淘宝的拍卖系统可以帮忙,浙江省高院在淘宝拍卖一年多,成交26亿。

    可惜这个方法不可能实行。现在的高铁票价都被媒体和意见领袖喷成啥样了,何况是拍卖。再说,火车票毕竟是生存之刚需,票价20年来不涨本来就有照顾补贴的成分在里面,全拍卖可能也是不妥当。

    2. 抽签法,运气好者得之

    开车前2个月开放报名,开车前7天抽签,中途可取消。预存票款,抽不中退款。上传身份证和正脸自拍照,机器核对。

    这样的话,拦截黄牛的成功率就高很多了,黄牛可以预存票款,可以找到大量真实身份证号,你黄牛再让每个给你身份证号的人把身份证照片和脸部自拍也给你试试?即使有人真想找黄牛,给身份证照片还是会犹豫一下吧。而且中间手工操作多了很多,黄牛成本提高,还不一定搞得到票。反正都是碰运气,我想真正的消费者还是会选择自己先去碰运气吧。

    这个方法实施难度也大,无论怎么设计抽签规则,必然有人大叫“有黑幕,不要相信政府”。

    开车前7天出抽签结果,改变行程的人应该在7天前就能决定改还是不改了。没抽到的也还有时间想别的办法。当然不一定是7天,15天,10天也可以,具体几天要有数据模型来算。

    3. 拍卖 + 抽签

    软卧、高铁商务座等高价位的,拍卖,反正买这个的是经济能力相对较强的。那就拼谁经济能力更强吧。

    硬座、站票抽签。

    4. 凭身份证进站,车票跟发票一样,是报销凭证,不是进站凭证;退票后钱进入12306账户,不可提现,只可该乘客下次乘车用;黄金周期间,个人账号最多订购10张票

    这个办法可以打击黄牛囤票再转卖

    运行一段时间后,按账户余额弄个排行榜就知道谁是黄牛了

    可惜这个需要车站设备改造配合。

    -----更新-----

    收到有同行质疑136个库存的合理性,他提出的方案是:

    北京西(01号站)到深圳北(17号站)一共设置16个商品(SKU):

    SKU01:01号站 到 02号站

    SKU02:02号站 到 03号站

    ...

    SKU16:16号站 到 17号站

    如果出一张01号站到17号站的票,就把SKU01/SKU02....SKU16这16个SKU的库存都减一。

    这种做法是可以运行的。我原来参与设计的一个ERP系统就是这样的做的。

    16个商品方案的优点是商品数会比较少,缺点在于查询性能较低,要查询16次才能知道【北京西到深圳北】还有没有余票。而136个商品的设计,穷举了所有出发和到达站点的组合,出票前只需要查询1次库存就知道还有没有余票。

    大部分面向公众的网站,其业务特点都是读多写少。电商系统的库存查询次数更是远远多于库存修改次数的。在秒杀系统中,可能会出现99%的请求查库存1%请求改库存的情况。 像12306春运抢票这种场景,在秒杀工具(抢票软件)的推波助澜下,查询1万次库存才成功出一张票也不是没有可能。

    还有人说,KFC的食品可以单卖,也可以套餐,为什么没像我一样搞出这么多SKU,那是因为,KFC门店的人肉查询频率非常低,没有必要为了优化查询性能把库存结构设计成那样。

    关键词(Tags): #12306#秒杀#编程元宝推荐:铁手, 通宝推:mooncarxy,二手玫瑰,空空如也,河区分,NetCobra,贼不走空,longpath,柴门夜归,清风席卷,strain2,履虎尾,trilfe,被明月兮佩宝璐,xiaoyin,诸法空相,witten1,平淡是真,今晚打老虎,二至,踢细胞,啊凡,庄汀,曾自洲,子系走神,老沛,眭村散人,汉服骑射,御前带两把刀,阴霾信仰,kk,住在乡下,az09,为什么不可以,太伤脑君,西伊,想学自由泳,小白兔albert,咪铛,方恨少,niuph,常识主义者,逍遥蜀客,冯家窝堡四贝勒,Leono1,hycpla,常挨揍,上好佳,nvda,唐家山,土拨鼠yuanap,夏级核潜艇,楚庄王,西电鲁丁,xyz熊,打铁的,上古神兵,jboyin,花大熊,金银木,发了胖的罗密欧,端履门,忘情,四道口,舒拔,四处乱晃,北纬42度,mailsina,富柜,PCB,三力思,桥上,rentg,米爹,洗心,芝娃娃,阿四,胡一刀,梓童,休眠火山,振振公子,未知如之何,月下,老醋花生,五峰,新手爱学习,敲门,jent,紫色月亮,野芹,MOMOZONE,然后203,
    • 家园 为12306说句公道话的后续

      这篇文章本来还有后续,我打了个草稿的,准备回答一些问题,后来因为种种原因没有及时写成文章,现在这股新鲜劲已经过去了,把草稿发出来,有兴趣的河友可以看看。

      以下是草稿,写于2014年1月20日。

      1. 我的身份问题

      只是表明我是做过技术的,是否淘宝离职员工不是关键。这些道理也并不深奥,大部分研发经验丰富的业内人士一看就懂。我的科普目的基本达到了,为了减少麻烦,我不会做任何努力证明我的身份。

      2. UI问题

      OTN不丑(就是购票界面),12306首页确实丑

      3. 串号问题

      不一定是自行编写的业务层代码出错。淘宝曾经出过串号问题,是JBoss bug。12306也用的JBoss,且其版本仍存在串号bug的可能。

      4. 证书问题

      这个确实不妥

      5. 到底是不是动态库存

      有余票表格可以证明,同时存在动态SKU和人工静态分配。且这个表格是从12306上查询出来的。

      6. 和民航的差异

      6.1 运力和价格决定了铁路比民航主流,黄牛和正常用户更青睐铁路

      6.2 民航大多只有一个经停站,行程规划和库存管理复杂度不如铁路

      6.3 民航性价比上来了,一样会挂(如AirAsia亚航开航时放出的特价票,基本是逢特价必挂)

      6.4 同一个线路,买机票要跑很多代理网站、航空公司官网才知道哪里是最低价,是不是真没票了(这也是qunar.com发展起来的原因之一)。相比之下,买火车票的要简单很多

      7. 分销问题

      和机票一样。

      预分配的票可以分销,动态库存的部分分销了,也只是分担了前面的压力,库存还是要回到总部。分销商和铁总的通信带宽、技术衔接是个问题

      如果预先分票,首先如果预测不准,会造成对票的浪费,其次也是最重要的,黄牛更难解决。

      8. 一个车次一台服务器

      8.1 技术上讲,1台服务器是单点,down机了这个车次就不能卖了。要保证高可用,起码3台,而铁总有接近5万个车次(数据来源存疑)

      8.2 需求上讲,消费者的买票原始需求是城市到城市,不是固定某一个车次。要达到这样的效果,12306的应用还是要把满足这个需求的所有车次库存都查一遍

      9. 黄牛到底是怎么工作的

      9.1 电视报道的黄牛一分钟一千张票,数字存疑,有黄牛接受采访表示【我也想活在新闻联播里】

      9.2 目前的购票流程(不预存票款,无实名检验),黄牛不需要什么后门,仅凭机器自动填写表单和提交表单的速度差,和机器24小时不眠不休,即可拥有对真人的优势。12306在对付黄牛上还有很多可以做的事情,但不能简单地说这里有后门。

      9.3 从经济角度,12306和黄牛勾结,收益太小,风险太大。网络售票反而是大大减少了各级售票点和黄牛交易的可能

      9.4 技术层面彻底杜绝黄牛很难很难。庞大的肉鸡网络提供足够的IP,人工验证码识别平台,识别一个验证码才2分钱

      10. 验证码

      10.1 加载慢

      复杂的验证码生成比较消耗时间,例如Google采用的那种,生成时消耗的时间,是ems那种的100倍。可以预先生成上百万验证码图片,放在服务器上,消费者请求时,直接把图片发给消费者,而不是实时计算。

      10.2 动画验证码

      动画验证码刚出来的时候确实能使抢票插件的OCR失效,这是因为抢票公司之前的OCR算法是针对静态图片的。并不是说动画验证码更难识别。

      GIF和PNG动画本质上是多帧图片连续播放,抢票插件把每上帧都当成一个静态图片来识别,就可以了。

      Flash实现的动画验证码才能对付OCR,但也有可能被人通过swf逆向工程的方式破解

      11. 哪些是可以很好地由多台机器分担的

      除了库存更新,其它工作(如上面生成验证码和校验验证码的工作)是非常好由多台机器分担的。

      库存要应对高频率高并发的查询、更新,又要保证高度的一致性,是12306(含其背后的票务系统)最大的技术瓶颈

      12. 消费历史订单放内存

      45分钟内的订单可以放内存,以达到最快的查询速度。

      45分钟以外的订单,可以放硬盘上的传统数据库。

      冷热数据分离。可以更经济地利用内存。

      13. 12306比淘宝难度更大,是媒体误读

      上一篇文章说的是12306库存比淘宝京东这类电商复杂几十上百倍。但并不是说12306整体技术难度比淘宝复杂。除了库存,还有很多其它衡量的维度,比如淘宝的营销模型比12306复杂几百上千倍。

      上一篇文章也说了,淘宝花的时间、人、钱都比12306多10倍,如果淘宝整体复杂度还不如12306,那是不合逻辑的。

      12306和淘宝的峰值压力在一个数量级

      淘宝和12306都是很牛,就像乔丹和博尔特都是伟大的运动员。

      14. 跨天的车次和车次复用

      如G824和G821

      15.为什么是136个SKU,而不是16个

      如果出一张01号站到17号站的票,就把SKU01/SKU02....SKU16这16个SKU的库存都减一。

      这种做法是可以运行的。我原来参与设计的一个ERP系统就是这样的做的。

      16个商品方案的优点是商品数会比较少,缺点在于查询性能较低,要查询16次才能知道【北京西到深圳北】还有没有余票。而136个商品的设计,穷举了所有出发和到达站点的组合,出票前只需要查询1次库存就知道还有没有余票。

      大部分面向公众的网站,其业务特点都是读多写少。电商系统的库存查询次数更是远远多于库存修改次数的。在秒杀系统中,可能会出现99%的请求查库存1%请求改库存的情况。

      像12306春运抢票这种场景,在秒杀工具(抢票软件)的推波助澜下,查询1万次库存才成功出一张票也不是没有可能。

      还有人说,KFC的食品可以单卖,也可以套餐,为什么没像我一样搞出这么多SKU,那是因为,KFC门店的人肉查询频率非常低,没有必要为了优化查询性能把库存结构设计成那样。KFC网上订餐比门店的查询压力大一点,但只要不是像12306那样全站商品都秒杀,也是不需要为了优化查询性能把库存结构设计成那样的。

      16. 为什么不是一个座位号(如4号车厢18D座位)对应一个商品

      查询余票时要count,性能差。

      因此可以先生成订单,接受支付,支付成功再分配座位号。用异步操作把系统解耦。并发量最大的订单事务上不要把太多非必要的操作(如分配座位、给购票人发邮件短信)牵扯进来。

      17. 不能简单地把12306视为原来窗口售票时代票务系统的一个web界面

      12306上线,票务系统的每秒读写请求涨了上千倍。因此12306上线时,铁总肯定也花了大量的资源优化原来的票务系统。后台票务系统没有大的改造不足以支撑12306上线

      参考资料:

      高铁的商务座数量:

      1. 京广高铁G80次,380型车,28个:http://news.qq.com/a/20121227/000701.htm#p=5

      2. 西安北到深圳北的G824所用的CRH380AL车26个:http://henan.sina.com.cn/news/z/2012-09-24/0712-24627.html

      3. 京沪高铁的G129次24个:http://luxury.ce.cn/html/2012/csdc_0628/75379.html

      4. 沪杭高铁G7305次28个:http://news.cntv.cn/china/20120520/106624.shtml

      (注:以上参考新闻可以看出,这些线路的商务座数量都不超过30个,但如果去12306查询余票,同一线路内,不同路段的商务座余票量加起来很容易超过30,所以后台必定有动态库存机制)

      快捷余票查询:http://yupiao.info/

      通宝推:我来也,
    • 家园 经验重要

      很多经验少的人会估算少工作量,经验是一个很重要的东东

      • 家园 没经验的人往往容易高估写代码的良品率

        软件其实是很复杂的一个工业门类,没经验的人往往容易高估写代码的良品率

    • 家园 讨论一下16种SKU

      讨论一下。16种SKU应该是可以的。要照顾到查询的性能,可以把读写数据库分开。每次出票后更新读的数据库(可用消息队列,而且读数据库可以是NoSQL),读数据库里有所有组合和票数。毕竟写数据库造作是瓶颈。

    • 家园 写得真好!

      让俺这种技术二把刀看得很过瘾!

    • 家园 楼主善用春秋笔法

      三大问题哈

      1.用淘宝来比喻。

      但是是12306没有淘宝那么复杂的业务。成功的把问题引到了一个更复杂的系统上,然后让读者通过类比认为12306也是同样的业务。成功的洗地党。

      2.业务上设计的复杂性代替系统的复杂性

      楼主你设计的业务我看懂了。。但是显而易见,更新处理需要事务,有事务就要有锁,有锁就是一切慢的源头。查询不需要,所以不可能有那样的穷举设计滴。。要提高查询效率只要查起点站到终点站之间的区间段里面最小的票即可。

      3. 楼主和大多数人都把问题引到数据库读写上去。但是如果买过票的攻城师,应该会发现没有那么复杂。

      (如果真那么复杂,大多数攻城师不会来这么说哈)

      因为当中还有个付款问题,付款有45分钟,付完款才去更新数据库。

      考虑到人动作快慢问题,峰值不会有那么高。

      但是其中有个奇妙的锁定问题。这个锁定是毛的意思啊,我完全不太明白。而且我看问题都在那个锁定上。

      好吧,上面没听懂的同学我们再反向思考一下:如果瓶颈在数据库上,那么12306刷票的那一会,线下的电话售票,网点售票应该同样无法卖票才对。看明白的请继续思考下面问题:为毛线下卖票没问题线上就会有问题呢?两者最后不去读的一个数据库??

      另外还有些技术细节有些明显问题,让我觉得你可能技术没有那么厉害。。

      不过是总结一下,成功的洗地党。

      关键词(Tags): #洗地
      • 家园 连锁定都不懂,你还是别出来丢人了吧

        比如说有m张票,n个人同时买票,每买一张票数就要减一。这n个买票的人都是独立的,减一这个操作怎么进行呢?当然是把记录锁起来一个个减。一个人买了票之后,票数变为m-1,第二个买票的人就从m-1张票的基础上再减一。不锁的话就乱掉了,不知该从那个基础上减,也没法判断余票(因为不知道同时买票的n是多少)。

        需要锁的不止是票数,还有其他东西,这样又会产生“死锁”“活锁”问题,需要一些很耗时间的技术来解决。

        以上这些概念,哪怕学过给文科生开的数据库基础的人都了解。您是怎么做到连这都不懂还敢说人家洗地的?就因为它是体制内的项目所以活该被喷?

        线下不受影响当然是因为预留车票啊,网上、电话、网点各有配额

    • 家园 名帖留名
    • 家园 新华网说“12306是150多个码农”负责

      我作为外行觉得150个人有点少。

      还做了个好多图表,挺漂亮的。

      外链出处

      感觉整体上与其还算平和,就事论事吧,没有明显上纲上线。里面还是透露了一些有意思的信息。比如,虽然预先估计到网上售票只占总交易的20%,但竟然没有估计到访问量会远远大于实际交易量。还说今年到现在为止还没有出现过系统崩溃。

    • 家园 看到不少“明显”的方案,有个据说是费曼的比喻很形象

      现在有个保险箱,它的密码我们猜了很多年都没猜出来。你给我们写了封信,说:“为什么不试试112233这种组合呢?最简单的往往就是对的!”——我的问题是:是什么让你觉得我们没有试过?

    • 家园 12306技术负责人也在关注楼主的帖子。见 人民日报

      http://paper.people.com.cn/rmrb/html/2014-01/20/nw.D110000renmrb_20140120_1-13.htm

      12306 春运能否不瘫痪(民生三问)

      对话人:铁路12306技术负责人 朱建生 本报记者 陆娅楠

      《 人民日报 》( 2014年01月20日 13 版)

       朱建生:我觉得网友“代码狗”在西西河论坛中发表的一个帖子里有一段话非常专业:从物理原理讲,服务器每秒钟能承受的计算量是有极限的。从经济角度考虑,一个网站不太可能以最高峰值的承受力为标准来建设。

    • 家园 同一线路的商品数可能没有那么多

      帮同学订北京到枣庄的票,走的是京沪高铁,到枣庄的票几乎一分钟内就没了,但是同一线路到上海的票在三个小时后还有几百张!没办法只能花了多一倍的价钱没了到上海的票,至少能保证回家。所以充分怀疑是每个站的票都是预留好的。

分页树展主题 · 全看
/ 10
下页 末页


有趣有益,互惠互利;开阔视野,博采众长。
虚拟的网络,真实的人。天南地北客,相逢皆朋友

Copyright © cchere 西西河