十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

铁道部信客票系统设计(三)

铁道部信客票系统设计(三) 最近只是一时兴起觉得无聊正好要到买票的时候写了这个一系列文章首先是对自己这些年来的工作经验的总结其次是把分布式事务性系统的设计思想进行分析和整理最后也就是和想集大家的智慧讨论系统的设计。我不是铁道部的工程师我只是一家互联网金融类公司的屌丝工程师级别不高能力也一般就是喜欢技术而已。在第二篇文章里面重点分析了余票库的整体设计我看到有的评论说了几点现在整理一下1 为什么要用悲观锁为什么要用锁由于之前是做金融系统对数据的一致性要求很高。铁道部的出票操作要保证数据一致性所以必须在获取余票的情况下锁定余票记录否则会导致并发问题多出票。如果是站票还无所谓如果是卧铺咋办一个席位两张票。这个操作和帐户扣款一样考虑下面的例子这里没有锁导致多出票这个只是两个线程假设有10个线程则多出10张票考虑有锁的情况2 系统能否承受悲观锁首先我们需要看到什么情况下锁以及锁持续时间以及请求的并发数来进行分析。大多数情况下铁道部购票系统承受的并发量都不会太大除了节假日主要是国庆节和春节。及时在国庆节和春节的情况下我们假设每秒钟1000个请求去买座Z27的20121001的座票那么锁记录持续的时间是多长了分两种情况a 有票业务逻辑完成释放锁假设一般坐票有1000张那么会有1000次锁业务操作假设业务持续锁时间0.1秒这个需要实际去进行压力测试一秒钟处理10条记录需要2分钟才能消化。而且这两分钟内oracle连接也被占用后续的请求排队系统缓慢然后假死。这里面我们可以设置一个值假设超过5秒还没有办法获取到锁自动释放连接数据库返回错误客户端可以选择重试查询票数或者报错给客户当然这个涉及到客户体验如果获取不到锁基本上可以告知客户票已经售完。考虑到如果余票库有10个那么就可以分摊一秒钟就可以100请求。这个具体还是不过以上只是假设需要有实际的数据以及压力测试要测试一下性能。b 无票直接释放锁基本上非常快不会占用资源。在下一个查询周期就不会在锁定记录因为直接在缓存出就排除了。所以个人认为使用悲观锁不会存在太大的问题只要库设计的合理锁超时时间设计的合理对请求进行有限的控制是可以支持的当然这个要求实际去检测。3 不需要锁只需要一台应用服务器启动线程处理购票也不需要应用集群那可以想象一下所有的购票请求都会同时请求到那一台处理购票的服务器上假设这个每秒钟处理1000请求这个据我所知已经算高了基本上高峰期几秒种的数据就把服务压挂了。并且这个是单点一旦这一台服务器挂了整个系统瘫痪。4 余票数据可以放在内存中吗放在内存也就是放在内存缓存里面这个问题有以下几个1 缓存故障当缓存出现故障的时候怎么办当然可以缓存集群切换到另外一台缓存服务器但是余票的数据如何同步两者不一致怎么办2 系统发布当系统发布的时候怎么解决缓存中的数据库问题当然可以先把请求处理完成然后在发布。或者发布之前把缓存的数据同步到数据库中这样也是可以的。但是设计上太复杂。3 极端情况硬件故障操作系统故障机房断电这些故障都会导致内存数据丢失余票数据都丢失了我就知道我所在的公司遇到的变态的情况如下机房无故断电网卡故障磁盘写入失败经常遇到的情况是jvm crash内存泄漏这些会导致放在内存的数据比较危险。还有领域驱动设计和数据库设计两者没有必要联系。领域驱动是解决复杂业务领域的时候用的一种设计思想自己在这方面开发比较多和数据库这一层设计没有关系对于性能来说当然可以把所有的数据都放在内存里面这样的处理效率最高但是内存的数据就易丢失的数据。设计一个系统架构最大的问题就是权衡利弊。对于火车票系统在出票的流程上相当于金融系统的转账余票相当于用户的余额要保证最高优先级的安全性和一致性。这个性能相比优先级要高。谈谈对架构的认识这里在说说谈谈自己对架构的认识吧架构不是说就只管系统的性能架构是全局观。涉及到安全性可用性性能数据一致性可扩展性等等。每个系统的应用特点不一样所以思考的重点不一样。金融类系统对可用性和安全性数据一致性要求非常高不能有任何的妥协宁可牺牲性能这就是为什么银行喜欢用IBM的产品。新浪这样的网站性能很重要但是如果丢失的用户少量数据无所谓所以数据可以放在内存里面甚至可以用nodejs这样的新技术来实现。铁道部这样的国家级系统可用性一定是在第一位的其次是数据一致性然后才是性能。就扯这么多每个人的观点不一样但是架构就是这么虚的东东。关系型数据库目前证明还是最可靠的你能想象金融类帐务系统用的是NoSql这样的对事务要求不高的数据库吗所以关系型适合在购票这样的核心应用。其他的库可以用NoSql来实现比如会员库没有问题。渠道购票分配上一篇文章提到了这个渠道订票的需求目前有两种方式进行数据库层面的设计第一种是各个渠道的数据切割开互补影响也就是说我网络订票不影响窗口售票我想这个需求还是比较合理的有限保证窗口票那么可以把数据库水平分割按照渠道来设计这种设计的最大好处就是各个渠道订票完全是分割开的互相都不影响但是这样最大的问题就是事先算好每个渠道的票的配合比如窗口100张网络20张代售200张电话30张。非常不灵活比如假设我窗口还有票但是窗口没有人买怎么办那只能其他渠道来卖。这样也比较浪费毕竟大多数情况下铁道部的购票还是系统还不是那么繁忙的。另外一种设计就是在渠道层做流量控制让流量控制这一层负责票数分配这种设计方式就是比较考验渠道层渠道层需要做流量控制这样分配的最大问题就是分配均匀所以很好的算法。但是数据库层统一了可扩展性比较强。容易进行扩容也不会造成硬件的浪费。两种设计方式体现的思想不一样各有利弊。不过从更倾向于第二种设计方式比较灵活。而且渠道流量这一层本身就必须的这一层可以设计的比较厚而且可以大量使用缓存或者NoSql。余票库的再分析1 余票库的分库策略昨天讨论余票库分库策略想起和一个铁路工程师聊起再想想自己电话订票的时候可以发现更好的分库方式。下面是从百度百科搜到的铁道部的组织架构铁路局是中国铁路管理体制的特色产物是中国铁路四级现在为三级体制的重要组成部分。中国目前有18个铁路局公司分别是哈尔滨、沈阳、北京、呼和浩特、郑州、济南、上海、南昌、广铁集团、柳州2007年已搬迁至南宁、成都、昆明、兰州、乌鲁木齐、青藏铁路公司、太原、西安、武汉。铁道部下面分为18个铁路局我估计每个铁路局负责的车次不一样那么分库就可以按照铁路局分库这样就可以分为18个数据库。但是考虑到余票库的实际数据量并不大只是高并发我们没有必要分成18个库。但是我估计由于利益分配这个18个铁路局应该每个铁路局都有自己的数据中心。但是我们这是纯技术层面的分析先不考虑利益和实际情况。我们可以按照铁局路分库但是前提是负责卖票的车次都不一样否则一个车次分到两个库里面系统会变的很复杂。假设范围分为四个东南西北比如哈尔并沈阳北京呼和浩特一个库。这样我们就有一个简单的模型了那么在梳理一下一次典型的购票数据流其中虚线圈起来的部分是要保持数据一致性。简单的说就是 余票减少一张车票库待支付记录就会多一条车票支付成功车票状态要变更支付数据完成短信要发送当然这个要看你对一致性要求有多高车票购票成功短信发送不一定要成功。但是车票支付成功支付数据总要有并且是成功的吧。这个要进行对账的否则就是一笔糊涂账。据说铁道部还会建立会员营销系统那么越来越多的功能就会更复杂比如支付成功积分增加一百积分以后可以进行车票的支付等等。不过这个不是核心如果能继续写在分析吧。至于在分布式环境下如何保持数据一致性这个我会专门写几篇文章来进行分析我觉得这个是比较有价值的。2 如何确定余票这个是第二篇博文中我没有写的我觉得这个是最复杂的现在继续分析。确定余票的因素日期车次假设动车普通车次不重复出发站到达站席位其他三个很容易从数据库中获取这里不说了主要是出发站到达站两个维度。如果通过其实出发站和到达站进行查询首先我们根据车站确认可以通的车次可以简化为对N个车次查询在根据出发站到达站进行分析假设 车次Z27坐票20121001中途经过5站ABCDE共有100张简化记录为(A-E) 100假设用户U1买了从A-E的车票一张那么还剩下99张, 就是 (A-E) 99假设用户U2买了从A-C那么 (A-E) 98 ,(A-C)98 (C-E) 99假设用户U3买了从C-D, 那么 (A-E) 97 ,(A-C) 98 , (C-E) 98 (C-D) 98 , (D-E) 99看来越来越复杂但是我们发现这个和二叉树有关看一下下面的图不断构造一个树的过程而且判断票和也查找节点有关找到之后此节点票数-1所有的父节点票数-1。我算法不好只能想到这个算法了不知道有没有更好的算法这个树不需要实时更新放在内存里面。这样就方便查询了。整个架构的基本模型把第一篇和第二票文章整理的内容在综合整理以下在应用在丰富以下可以搭建一个简单的分布式系统的应用原型透过这个原型我们在不断的完善系统目前铁道部可能的架构模型最后看到铁道部的组织架构感觉铁道部的系统架构可能大致是这样的随便乱太猜想的下面一个简单的模型实际情况远远比这个复杂。由于数据中心是分布的所以系统很慢。因为数据这一层路由都是远程调用啊。同时铁道部的应用应该也是分布部署的由于数据中心不集中花在系统间通信的成本太高。感觉这个可能是铁道部内部的政治格局导致的以前的银行都是这么搞的每个省都有自己的一套系统。后续写了这么多先休息一段时间吧后续有时间在继续分析这个系统今天也恰好看到一个新闻据介绍12306互联网购票系统是基于中国铁路客票发售和预订系统简称客票系统这一核心系统构建的。客票系统在10余年的运营过程中先后完成6次升级1.0版本实现了计算机售票取代人工硬板票2.0版本实现了区域级联网3.0版本实现了全国联网售票4.0版本实现了与清分清算系统的对接5.0版本实现了席位复用和共用5.2版本实现了实名制售票、电子客票和电子支付。由于2.0版本是区域级别售票3.0实现全国联网售票但是我估计所谓实现全国联网售票因为是在2.0的基础上通过适配和路由搭建的铁道部应该还没有统一的数据中心数据应该是各个铁路局控制的。4.0版本主要做清分系统这个就是内部的核算系统应该算是铁道部内部最为复杂的一个系统了比如我卖了1000张票应该得多少钱应付给代售点和合作商户做多少钱。5.0可能就是上面说的同一个位置由于区域段不同可以买两张以上的票只要铁路段不重复也就是我说的余票树模型。5.2就是实名制和增加了电子支付和电子客票这个应该稍微简单一点只是增加了一种支付工具和验票手段。所以版本号就没有怎么升级。看看新的客票系统的愿景;铁道部透露新一代客票系统实现了四方面创新。一是服务模式创新系统支撑包括票务服务、旅行服务等各种延伸服务在内的预订业务。二是营销理念创新对铁路列车开行、运力调整、票价优惠等提出合理化建议制定铁路客户常旅客计划建立旅客积分、奖励制度。三是管理手段创新满足淡旺季不同客流特点下的售票组织需要。四是技术架构创新研发高性能核心交易平台。从业务角度来看1 铁道部想建立客户模型目前铁道部还没有客户模型毕竟实名制刚开始区分优质客户以及黑名单。未来可能你座的越多可能走优先贵宾通道上车等等2 建立积分模型这个主要是用来营销和航空和银行一样估计就是换礼品什么的3 技术架构创新我觉得这个是最重要的现在的架构可能因为历史的原因比较弱。4 高性能核心交易平台这个是必须的类似淘宝那样的交易平台。从全球性来看ebay的交易平台比较牛逼不过淘宝最近的交易数据不知道超过ebay没有。这个交易平台未来会不会开放也是一个想想的空间。未来还可以想想的是一旦铁道部建立的会员模型更有可能往金融上面去靠拢建立自己的账户模型推出更多的支付方式比如预存款联名卡等等。铁道部相当于拥有最多实名制会员的公司想象空间很大。但是前提是系统要做得好别再被人骂。
返回列表