主题:【原创】好吧,给一个铁道部订票系统的正确答案 -- 布老虎
全部旅客的理解那是奢望。不说一百个吧,一千个旅客里有一个不理解要控诉,铁道就得抓瞎。
今天看到此文,恰好我做过类似的东西,有点小心得。
先挖个坑。
布老虎在上面提到eventual consistency,我觉得这东西实在不错,看了看wikipedia上的介绍。单就我对wikipedia上BASE条目及其引用文献的理解,这一概念很难用在火车票系统上,至少也不会像布老虎说的这么简单。
首先按照eventual consistency的支撑,CAP theorem的说法,火车票订票系统要保证的是Consistency和Availability,如果要保证这二者,或者哪怕只要严格的Consistency,这样就退回到传统数据库的要求。事实上,所谓证明CAP theorem的这篇文章里面就说:it is impossible to reliably provide atomic,
consistent data when there are partitions in the network。这里的partition,对应我们的问题就是相互独立的后台数据库节点。也就是说,如果后台数据库之间没有同步(如同MapReduce那样)还能保证Consistency和Availability的系统,就和永动机一样,理论上就可以证明是不可能的。这样就退回到Oracle这样的数据库了。
其实BASE系统是不能讲严格的consistency的。布老虎的实现和这篇文章里面的伪代码差不多。为了提高速度,只能保证weak consistency,把几个操作放到message queue里面执行,包括修改不同车次可买的火车票数量和扣用户的钱。这样的系统上线,几乎肯定引发严重的问题。首先是当前查询到的火车票数量是不准确的,任何信息牌上显示的剩余座位信息都是不可靠的。二是当前用户的余额不会立即被扣除,一个恶意用户短时间内可以发起大量购买请求。三是“买到”的票是没有保证的,必须等确认之后才有效,这一点就像是飞机票的超售。飞机票的超售在国内已经引发很多问题了,这个比飞机票的超售还要严重:一是对火车客户而言这是一个全新的概念,以前没有接触过,二是无法确定座位,而火车用户对座位可能看得比飞机上的座次还重。想想春运期间被耍了一把以后还要滞留的客户,不知道会引发多少问题。
搬小板凳等着看
下,有满意的用户体验? 这不只是技术科技层次的问题。
没具体需求和业无约束底下泛泛谈开源/闭源,java/.net反而会失去技术方向的把握。而且.net真的那么不堪吗,我可是用.net做过排得上号的一个系统呢。而且还是早期的.net 2.0。
本帖一共被 1 帖 引用 (帖内工具实现)
因为电子售票系统当年选择的数据库是SybaseASE, 而且已经积累了这么多年了,被粘住脱不了身了。
当年车票由小纸板车票换成目前使用纸质车票, 那可是费了牛劲,阻力很大。地方路局和铁道部之间的利益纠葛,那就是天子和诸侯的关系, 单单靠权力自上向下压是行不通的。
举个小例子, 目前使用的粉红色车票其中有一块钱的软件费(貌似是这个名字,记不清楚了), 这一块钱是分给各个地方路局用在做软件硬件升级用的。你如果更换系统更换的早的话, 就能更早拿到这笔钱。这么多年鬼知道这笔钱是不是升级了硬件软件。
改革改革,就是利益再次分配。分不好得罪人,就像商鞅被五马分尸啦。哪个领导敢拍板, 把那个后台数据库换了?
据说华尔街那边有不少公司都在用。
如果用了多年,要脱身确实不容易。
再加上他们的技术能力,再考虑到利益纠葛,只能哈哈了。。。。
搞的我都不好意思了,本来想坑掉都不行了。
========================================
简单说下我以前参与的那个系统:一个商品秒杀系统,每次来访问的用户人数都比较多,带宽与服务器的压力都很巨大。这个系统虽然设计实现的比较堍,但却管用。
当然我们的系统与铁道部订票的系统没法比,因为我们为了抗访问压力,将前面的业务逻辑尽量简化。
总结起来,对这类系统就是这么几点:
1. 不能追求完全的精确。任何一个抢购系统都会有些全局的资源,比如车票、座位、商品。要控制抢购的数量,不能超卖,这是起码的要求,但这个要求不能僵硬的执行。要做到实时数字的完全准确,就会对性能造成极大的影响,甚至会造成整个系统瘫痪。
2. 第一层抗访问压力的逻辑要简单再简单。用户来了,访问一个哈希表(我们用的Redis),看看这个用户有没有已经买过,if买过了就返回跳走,else没买过,就看下商品资源是否有货的标志,if没有货就返回卖光了的标志给客户,else恭喜成功记一条syslog出去。ok了,前面一层只有这点逻辑。
3. 尽量异步化。上面说了,前面记条日志就返回了,每个请求没有什么阻塞的时间。后台有个程序会把这些日志汇总到一个中心服务器里,那个中心的服务器会记录总数,并把信息写入到Redis的主库里。这样,整个抢购过程中,只有一个连接在写Reids,剩下的都是简单的读取。
总之,举重若轻,越是看上去困难复杂的问题,越要用简单的方法解决。当然,像美国医保网站那样复杂的系统搞5亿行代码,也是必须的。
在这个行业也混了十多年,主要做的是欧美市场的东西。身边比较有共识的是,产品是否成功,技术最多占20%的比重。最重要的懂行的类似产品经理的脚色。
我们经常收购某些热销的特定行业软件。进去看代码、框架基本就是一个烂字。但客户认。原因就是这样的软件本来就是由行业里懂得各种弯弯绕的人弄出来的,天然就满足他们的需要。
现在怎么样不知道,10年前是全国大集中的,UNISYS的主机,伴随着业务量的飞涨,几年就要升一次级,一次至少几个亿。
采用特定的行业软件,常常意味着工作流程的改变,用户也不傻,一般都是觉得流程合适,才下注的。