铁道部新客票系统的设计(一)

铁道部新客票系统的设计(二)

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

这几天正好看到一条新闻 铁道部:新客票系统2015年建成  ,正好最近想整理和总结一下这几年的工作中的收获,正好可以借这个机会,尝试设计一下铁路客票系统,把自己所学全部用到这个系统中去,顺便也希望各位猿们拍砖,一起探讨一下设计,技术吗,讨论讨论总是有点收获的,总比一个人在那里看书好。

非功能性要求

废话不说,这里先脱离系统的整体架构,后续在不断完善整体架构,这里首先讨论的是数据库层面的设计,因为对于整个架构系统来说,数据库的设计是最为关键重要的,数据库的设计好与坏,决定了整个系统的性能,可用性,扩展性。在考虑数据库的设计之前,我们可以先抛开非业务功能的需求,先看看非功能性需求,主要包括

1 数据库的类型选择

目前市场上数据库主要有:关系型数据库(Oracle,DB2,Mysql),NOSQL类型数据库(MogonDB),对象数据库(不是很了解),面向文档的数据库(apache couchBD),面向统计的数据库(HBASE)

根据客票系统的类型,应该是属于OLTP类型的系统,但是考虑到商业上分析需求,也属于OLAP型系统,由于本次讨论OLTP系统的设计,优先选择Oracle。为啥,用的公司多,市场上相关的技术工程师多,DBA管理员多,安全性和性能都不错。就是有点贵,不过考虑到是铁道部,完全忽略。对于部分客票系统非关键性业务也不重要的,这一部分数据可以考虑使用Mysql。至于NOSQL,没有用过,这个主要是面向web2.0的,对于事务要求高的系统,不太适合。

2 多数据中心

在金融行业,都必须部署多个数据中心,避免在一个数据库机房故障之后,全部数据都不可用。比如假如某地地震,数据库所在机房宕机了,如果这个时候检票或者买票,就sb了,所以需要尽快恢复。这样必须马上启动另外一个数据库机房配置。

除去灾备情况,考虑到铁路售票系统数据库的巨大访问量,2011年的铁道部的旅客发送量---2011年全国铁路运输目标:旅客发送量19亿人次,根据这个,初略估计一下一年估计要20亿张票,这个只是2011年的量,按照未来的几年的增长,按照目标值100亿人次估计,相当于一天有2700W独立UV,1亿PV。考虑到春节这个变态的高峰期,瞬间的并发量比平时会高上千倍。如果只在一个数据库只有一台,数据库就会存在单点,一旦数据库挂掉了,需要尽快的恢复。这个时候不太可能启用灾备数据库,因为灾备是异地备份,备份数据库同步数据比较慢(网络延迟),所以必须必须在同一个城市在部署一套数据库。这样在单点数据库故障的时候,可以马上切到备份数据库。

下面两幅图主要介绍异地灾备以及同城异机房备份的实现原理。

  • 同城备份

   数据一次写一份,日志写两份。由于日志文件实时同步,A服务器写完B服务器的日志文件,B服务器马上就写自己的数据文件。这样不会丢失数据。当A服务器故障,应用马上就可以切换到B服务器。不会存在单点故障。但是考虑特殊情况,北京地震,A,B机房同时故障,整个数据都丢失了。所以必须由异地灾备的数据中心。不过还有其他的方式,这里就不做叙述了。总之是要做好去除单点。

  • 异地备份

   这个架构和同城备份有一点区别,就是A服务器只会写A机房的日志文件,然后A异步同步日志到B机房的日志文件。这里面会有几分钟的网络延迟。这里不实时写B机房的日志文件,主要是性能。如果实时写B机房的数据,一次更新操作,就会至少有一次网络延迟(上海到北京的网络传输时间)。会影响数据库的性能。而同城市通过光纤连接,传输速率快,可以忽略网络延迟。如果A机房故障(灾难性的故障,比如地震,机房被恐怖分析袭击),就会丢失一部分数据,丢失的数据就是网络延迟同步的数据。对于购票业务来说,数据丢失几分钟的,是可以接受的,大不了我铁道部亏一点,这几分钟丢失的数据我全部免票。也可以做一次好的营销。但是对于金融行业来说,数据是不能丢失的,这里的异地备份就不符合金融业的要求。用性能换取可用性。就像atm取钱一样,一次交易涉及几分钟。你的交易数据银行至少会备份2份,一份同城的,一份异地的。

3 硬件配置

这一块不是很熟悉,交给dba专业的人去做吧。小机 + 存储(SAS)。不过对于铁道部有钱,上大机即可。不过我们还是按照互联网方式去分析设计系统,使用普通的存储以及服务器。

功能性分析

1 业务流程分析

先简单的了解一下购票系统的业务流程:旅客到互联网(也可能是其他渠道)登录,根据出发日期,起始站,终点站查询车票,确定车次和座位,预定车票,然后进行支付,支付成功之后,发短信,之后客户到线下去取票。一个简单的流程就结束了。

从上面的流程可以看出,整个业务流程中有几个以下几个实体以及实体的重要属性信息

1 旅客信息:假设都是实名的,至少有三个重要信息 姓名,身份证,手机号

2 车次信息:车次,起始站,终点站,类型,发车时间,到达时间

3 车次停靠信息:车次,停靠站,达到时间,停靠时间

4 余票信息:车次,起始站,终点站,发车日期,剩余座票,剩余卧铺。。。

5 车票信息:车次,起始站,终点站,发车日期,购票日期,旅客姓名,身份证,手机号,状态,购票渠道,支付日期

6 支付信息:金额,支付日期,支付银行,支付金额,支付方式

7 短信信息:车票信息,验证码,短信内容

整个购票过程包括以上几个重要的实体,其他的几个字段可以先不管。我们可以假设一下每一个实体的数据规模

实体 数据量 日增量
旅客信息 上限-中国人口数 16亿                   这个真不好估计
车次信息                             比较少,假设10万 日增应该也不会超过10
车次停靠信息 车次信息 ×200 == 200W 日增应该也不会超过100
车票信息 巨大,目前年增20亿,未来年曾100亿 自己换算一下,不过不会很平均,春节几天会暴增
支付信息 和车票信息同数量级 和车票信息一样
短信信息 少于车票信息,毕竟只有网络订票才会有短信,线下购票不会有 未知,假设100W
余票信息 一年交易量 365×车次信息 == 5000W 日增数据量 和 车次信息数量一致 假设10W

从数据量来看 车票信息 > 支付信息 > 短信信息 > 余票信息 > 旅客信息 > 车次停靠信息 > 车次信息

从如此数据量来看,必须进行分库分表。所以分库分表就在设计库的时候就显的非常重要。

2 简单分库策略

旅客信息相关的信息单独分在一个库,这些数据相对来说是读多写少,并且可以大量进行缓存,是基础相数据。

车次相关的信息,比如车次,车次停靠可以单独放在一个标里面,这个标是保存原数据信息,数据量不大,数据完全可以缓存。可以考虑和余票库放在一次。

剩下就是四大的实体信息,余票信息,车票信息,支付信息,短信通知信息,首先短信通知信息相对来说比较通用的,可能未来很多业务都会涉及到短信通知,所以短信相关的信息放在一个库

在剩下就是考虑业务上比较耦合的三个实体:余票,车票,支付。

余票查询频繁,没出一张票,就会更新余票数

车票数据量巨大,有查询和更新需求

支付信息:单笔查询和更新需求

考虑到车票和支付信息在数据量级上远远高于余票信息,余票信息单独一个库,而车票信息和支付信息业务上差异比较大,也单独分出来。

根据以上的分析,可以分出来5个逻辑库:旅客库,车票库,短信库,车次库(车次信息,余票信息),支付库。

继续往下分析,在5个逻辑库里面,由于旅客库数据量有上线,只需要分配一个实体库即可。 车次库增长有限,也暂时分配一个实体库里面。而车库票,支付库,短信库数据量比较大,分配一个实体库显然不够。下面单独分析这三个逻辑库的分库策略

3 车票库分库策略

对于车票信息的分库策略,需要考虑到以下几个因素

1. 功能需求

   查询需求:按照购票日期 + 旅客信息 + 状态 或者 旅客 +  发车日期 + 状态

   统计需求:按发车日期统计购票总数量和金额 或者其他几个维度

   交易需求:创建车票信息,更新车票状态,创建关联支付信息

   对账需求:(假设不考虑退票需求)按照支付日期统计支付流水总金额 以及 统计 支付成功的车票信息总金额

2. 负载均衡

     按照数据库处理实时要求进行分析,响应要求高的请求和耗时类请求分开,优先保证能够卖出票,支付车票。同时不能所有的请求都指向一个库。

3  高可用性

避免单点,否则购票功能就不可用。所以数据库至少有备份机制。

4 数据均匀

避免大多数据都在同一个库,否则遇到大数据查询数据库负载会很高,进而影响系统整体的可用性。因为大多数请求都会排队,导致系统资源耗尽。

  5 可扩展性

   当数据增长过快时候,能够很灵活的添加数据库而整个应用不需要做太大的修改

根据以上几个因素考虑,每一张车票生成一个全局的唯一性id,根据id最后一位数字/N平均把数据分配到N个数据库中,这样每张车票库最多可以分成10个库,可扩展性不强。也可以考虑一致性hash算法进行分库,但是这个比较复杂。还有一种方式就是随机分库,好处是可以无限扩展数据库,但是会给查询带来很大的影响。考虑到查询需求,太多的库可能导致查询复杂,甚至在有限时间内无法查询出来。这里采用最后数字/N的方式进行分库,N为数据库的个数。在这个基础上,在增加一个库,就是历史库,暂时只需要一个即可,把完结的历史数据迁移到这个库,一个季度之前的数据不需要在进行操作,一般只是查询需求,就迁移到这个库里面,减少交易库的压力。

这里分10个线上库,一个历史库。一共11个库。能够支持年100亿的交易规模。不过对于对账的需求,可以考虑另外的方式来实现。这里以后在说。

下面一幅图展示了分库的模型:

通过以上的分库策略,如果某一个库宕机了,会影响1/10的购票用户。

4 余票库分库策略

余票库虽然数据量没有车票库数大,但是查询和更新需求远比车票库频繁。而且是整个业务的关键路径。在考虑这个库的只需要保持一个月的数据即可,一个月前的数据可以迁移走,不需要所有的数据。而在春运期间,这个库的瞬间访问量会飙升,相当于淘宝的秒杀,要求实时性比较高,所以不太可能读写分离。综合考虑,可以分为两个库, 线上库和历史库。历史库用来做分析。这个后续是设计的重点。

5 支付库分库策略

支付信息和车票信息这两个库有点类似,只是用户查询相对来说比较少。这个支付库分库策略和车票库的策略可以一样。

6 短信库分库策略

由于短信通知是全站业务,这个完全可以独立与购票业务。消息量大,但非关键业务,非系统关键路径,对实时行要求不高,所以简单分成两个库即可。

在分库之后,数据一致性要求就会比较高,涉及到分布式事务 ,后续会重点讨论分布式事务的设计。

先写到这里吧,下一篇 会分析表结构以及分表策略和索引。

下一篇:铁道部新客票系统设计(二)

铁道部新客票系统设计(一)相关推荐

  1. 铁道部新客票系统设计(二)

    铁道部新客票系统的设计(一) 铁道部新客票系统的设计(二) 铁道部新客票系统的设计(三) 在上一篇文章中 铁道部信客票系统设计(一) 里面,探讨了关于数据库层面的功能性需求以及非功能性的需求,在非功能 ...

  2. 铁道部新客票系统设计(三)

    铁道部新客票系统的设计(一) 铁道部新客票系统的设计(二) 铁道部新客票系统的设计(三) 最近只是一时兴起,觉得无聊,正好要到买票的时候,写了这个一系列文章,首先是对自己这些年来的工作经验的总结,其次 ...

  3. 铁道部新规:列车空闲卧铺票可打折至50%

    本报讯(记者夏命群)昨天,记者从铁路部门了解到,根据铁道部最新规定,从昨天开始至6月30日,铁路部门将对列车运行中的空闲卧铺进行打折,优惠幅度在20%-50%间. 铁路自春运后进入了淡季.为了拉动旅客 ...

  4. 12306铁道部客票系统设计交流

    难得在博客园上能看到案例设计讨论,而且是关于12306售票系统的.于是我也来发表下的我一些感想,欢迎来吐槽! 12306系统升级了,但还是被吐槽了.这次国庆我没买火车票,按照去年春节的购票经历,我谈谈 ...

  5. 博客园电子期刊2012年9月刊发布啦

    期刊访问网址:http://emag.cnblogs.com/2012/CNBlogsEmag201209.html.以下为本期期刊内容: 博客园电子期刊 No57.2012年9月刊 推荐新闻 科技也 ...

  6. 关于分布式系统的数据一致性问题(一)

    最近写了一个关于 铁道部购票系统的若干文章 铁道部新客票系统的设计(一) 铁道部新客票系统的设计(二) 铁道部新客票系统的设计(三) 正好遇到一个博友,咨询了一个问题,这个问题正好可以作为分布式系统的 ...

  7. SSM+在线纳新系统 毕业设计-附源码241540

    基于SSM在线纳新系统 摘 要 21世纪时信息化的时代,几乎任何一个行业都离不开计算机,将计算机运用于在线纳新也是十分常见的.过去使用手工的管理方式对在线纳新进行管理,造成了管理繁琐.难以维护等问题, ...

  8. 敢为天下先,邮储银行“新核心”构建与落地之路

    今年4月,邮储银行新一代分布式核心系统投产的消息引发了业内广泛关注,这是国有六大行首个落地的分布式金融新核心.虽然分布式架构已经在互联网IT技术领域广泛应用并积累了大量实践经验,但在银行业,目前分布式 ...

  9. 统一南航电子客票换开规则和icscrs输入标准

    统一南航电子客票换开规则和ICS/CRS输入标准   为旅客办理舱位.航班日期.有效期.航程变更(不论票价是否改变).电子客票签转等客票后续处理业务时,如需以换开客票的方式操作,南航直属售票处.呼叫中 ...

最新文章

  1. TensorFlow实现超参数调整
  2. c语言五个整数排序,刚学c语言,老师让用if编一个五个数字从大到小的排序,有那个大神能帮我,谢谢啦...
  3. 解决:TypeError: ‘(slice(None, None, None), 1)‘ is an invalid key
  4. Socket.IO介绍:支持WebSocket、用于WEB端的即时通讯的框架
  5. P3577-[POI2014]TUR-Tourism【状压dp】
  6. python3-开发进阶-RESTful 软件架构风格
  7. 茱莉亚分形_茱莉亚的NaN Constant
  8. 登录drupal管理员_天气公司依靠Drupal来管理内容
  9. IndexOf() LastIndexOf() Contains() StartsWith() EndsWith()方法比较
  10. 计算机软件企业所属行业性质,最新企业所属行业类别、分类及行业代码查询表.doc...
  11. python 66:re正则表达式5(全- tcy)
  12. afterburner功耗限制调不了_为啥我的MSIAfterburner很多项都拖不了
  13. 电视台的收视率是怎么计算的
  14. [GIS教程] 7 空间数据查询与空间度量
  15. 最大公约数与最小公倍数( 初学Java 类与对象 )
  16. mybatis plus 看这篇就够了,一发入魂
  17. EF Attatch()方法附加对象
  18. LNK2038: “_ITERATOR_DEBUG_LEVEL”的不匹配项
  19. java中的事务管理
  20. 时域分析——无量纲特征值含义一网打尽

热门文章

  1. 对PTP 1588新的认识
  2. python函数中的嵌套函数
  3. Packet Tracer 思科模拟器入门教程 之二 交换机的基本配置与管理
  4. 【实验五 一维数组】7-7 去掉重复的数据
  5. 基于Android的记账本的设计与实现
  6. 谷歌大动作:最高优先级项目曝光,下一代AI搜索,剑指ChatGPT!
  7. 前端FormData详解
  8. OA 系统与 ERP 的关系,两者是如何对接集成的?
  9. Postman报错:Error:‌ NETERR:‌ getaddrinfo ENOTFOUND localhost
  10. 全向移动平台运动参数分析