注:本文首发于CSDN,转载请标明出处。
【编者按】在年前的「技术揭秘12306改造」专题中,负责12306改造的技术架构师刘云程从技术的角度、用科学论证的方式说明 12306是如何实现高流量高并发的关键技术,以及深入探讨了12306两地三中心混合云架构,今天,他继续为大家带来第三篇:传统框架云化迁移到内存数据平台。
以下为正文》》
摘要
12306混合云成功案例给予最大的启发就是打造一个从下到上都可做弹性扩展的“云应用”系统,企业客户可将关键业务的“子系统”部署在资源丰富的云计算数据中心,“云化”后的子系统可“按需”获取所需要的服务器虚机资源和动态调整网络带宽,利用这些资源解决在高流量和高负载情况下,系统无法快速弹性扩展导致的性能瓶颈。
此篇文章列举不同类型的系统改造迁移到云平台方案,从改造思路探讨,系统框架设计和项目实施的整个迁移过程,供大家参考和交流。在此以Pivotal Gemfire云平台为例子, 因为它已有大规模部署成功案例。 客户IT环境是五花八门, 对系统改造的思路和目的也不尽相同,Gemfire是不错的选择,但它不是唯一的选项。
前言
在过去20年,系统架构师最常用的系统框架是三层架构设计, 即Web层, 应用业务逻辑层和数据库层;Web层和应用逻辑层可随着业务变化做快速弹性扩展,但绝大部分关系型数据库层无法实现此功能。 在云计算,大数据和移动互联网时代,由于业务成长快速,服务多样化, 数据量急剧增加,用户对系统响应时间有更严格的要求; 在高负载情况下,无法横向扩展的数据库层往往成为系统性能的绊脚石。
在此篇文章,讨论重点是从软件中间件平台(PaaS)和应用系统(SaaS)层面出发,使用“分布式内存数据网格( In Memory Data Grid)”技术,将传统架构改造迁移到云平台。系统改造有多种不同的方式,主要是要看改造的目的和所受的限制来决定; 为了具体化说明, 我们以下列三个案例提供给读者参考和交流。
- 12306项目:整个售票环节的一系列核心子系统都经过高度“云化”。 目的是可以将云化后的子系统“按需”灵活部署在不同的数据中心(公有云或私有云),提供优质服务。 云化的手段是将子系统业务逻辑和数据都放在Gemfire集群上执行, 利用Map Reduce的技术,建立可弹性扩展平台,提供“高性能CPU计算能力”。
- 某市社保项目:采取短平快的局部“子系统云化”,针对有高并发需求会导致瓶颈的子系统进行改造。改造的手段是将子系统业务逻辑和数据放在Gemfire节点上执行, 建立可弹性扩展平台,利用Gemfire分布式并行查询技术来解决“高并发查询”的要求。
- 金融单位POC测试项目: 问题在于系统的查询业务量多,关联表格多,在高并发情况下,查询反应时间长。 POC目的是要验证在不更改子系统业务逻辑限制下,以最小的代价,对“数据访问层 (DAO)”进行修改,建立可扩展的“内存数据缓存层”,解决“高并发查询“的方案;另外,还有数据库与Gemfire集群之间“失效转移 fail over”的设计。 以此为基础,以后再将业务逻辑逐渐放到Gemfire平台,进行改造升级。
一、12306 混合云的启示
在前两篇文章提到,2012年春运后12306承办单位-铁科院引入”分布式内存数据网格” 技术,将余票计算/查询子系统改造迁移到Gemfire云平台,局部解决12306的主要瓶颈;改造后的子系统在2013年春运时上线,其效果是显著的,虽然整个系统运行还是有”卡,顿”等不足之处,但铁科院对此技术深具信心坚持改革,才有后续一连串的子系统改造出炉。在2015年春运,建立两地三中心混合云的服务模式,将大部分余票查询流量引导到阿里云提供查询服务;此举的目的是要借助云计算数据中心的资源,“临时性”解决在春运期间由于互联网购票和刷票软件所引发的难预测,高流量,和高并发请求,降低系统不稳定的风险。
12306混合云成功案例最大的启发是给企业客户和政府部门带来新的思路,就是将关键业务的“子系统”改造迁移到云平台架构,根据实际情况,将“云化”后的子系统部署在资源丰富的云计算数据中心(私有云或公有云)。 例如, 12306核心系统在经过全面改造和优化后, 每个云化后的子系统都具有特定的独立性,因为相关数据都放在Gemfire内存数据网格节点;这意味着这些子系统类似“云”一样, 可以随着业务需求变大或变小,一分为多,任性的漂移到多个不同数据中心来协同合作,避免在IT设备方面的重复投资, 并提高资源的使用率。
云化后的子系统部署在多数据中心,需要特别注意下列两点建议 :
- 如果将子系统部署在公有云提供服务时,数据隐私的保护和安全性应为首要考虑。
- 如果规划将子系统部署在多数据中心时,在系统框架上必需考虑上下游子系统之间的数据传输或同步/异步的设计。
以12306为例,两地多中心混合云的架构示意图如下;在春运售票高峰期间可以将余票查询功能部署在多个公有云数据中心提供快速服务(例如阿里云和电信天翼云)。
两地多中心混合云架构
二、系统改造迁移的思路和需求
随着企业成长,对于一个复杂的大系统来说, 其业务功能不断增加,服务方式多样化,数据存储量越来越大,但系统性能越来越慢,而用户对响应时间的要求越来越严格;尤其是在过去5年里,每年都有新技术的演进 (大数据和分布式内存数据平台)和新业务的衍生(物联网应用,社交应用平台和移动应用)。
当传统架构系统已逐渐无法满足日趋成长的业务需求时,有两种方案可供选择, 一是从硬件着手,scale up的选项, 就是更换性能更强大的服务器;二是scale out的选项,从软件平台着手, 进行应用系统改造,采取弹性可扩展的框架设计。
更换硬件服务器是最简单的做法, 但以后更换成本会越来越高,系统性能提升是越来越有限。 软件应用系统的改造,是一劳永逸从根本做起,改造成本是与系统的复杂度有关,是需要全面改造? 还是选择性的局部改造 ?这需要根据实际使用情况来决定。
针对系统的scale out设计,如果要推翻以前的架构,重建系统,那是个大工程,除非有下列三钟情况:
- 系统已经是千疮百孔, 无法再打补丁也无人后续维护
- 原有的框架设计已优化到极致,无论如何优化,都已经无法满足日益增加的业务需求。 例如,12306就是典型例子。
- 业务流程和组织管理方式有巨大的变动, 需要重建系统
否则,最省钱和最有效的方法就是针对系统瓶颈做“局部改造”来提高性能,保护过去的投资。例如,社保项目就是典型例子
在此篇文章,讨论的重点是如何将系统改造迁移到云应用平台, 由于每个系统都有其特殊性和复杂性的开发背景,其设计的系统框架,所采用的软件平台和开发技术也都随着时间演进而不一样。 因此改造的方式需要依据实际的环境来进行。
1. 12306 系统改造思路和需求 – 按阶段逐步云化核心子系统
- 原来系统是使用Stored Procedure开发,系统已经优化到极致,很难再进一步提升性能。
- 如果采用scale up的硬件升级,投资过于庞大; 随着铁路基础建设不断扩大,业务量也会随着增加,无法保证硬件升级后的系统性能会满足未来业务成长的需求。另外, 就是春运高峰期过后该如何处置过剩的Unix小型机也必须列为考虑。
- 承办单位- 铁科院经过仔细评估后,认为高流量和高并发问题必需采用云计算可弹性扩展的平台和技术来解决。
- 以分布式内存数据网格” - Gemfire技术为切入点,以余票计算/查询子系统为试点项目。 采取稳妥的改造策略, 逐年逐步改造和优化其子系统,解决一系列环节上的瓶颈,保证在改造期间整个12306系统的稳定运行。
- 在改造初期,新旧两套系统必须同时并行运行。 利用CDN(Content Delivery Network)的流量管理功能, 逐渐将流量加压到Gemfire集群,测试集群在高负载下是否能平稳过渡高峰售票期。
- 采用“多重Gemfire集群”相互备份的设计,同时并行运行,为未来“多数据中心”的部署当试点和铺路。
2. 社保系统改造思路和需求 – 短平快的局部子系统云化
- 社保制度逐年改革,新编制组织架构不断扩大,新业务不断增加,省市社保人数从数百万级别到某些人口大省超过亿的级别;这些社保缴费资料需要保存达数十年以上, 永随一生, 每年都有数百T甚至P量级的数据存储单位。社保单位必须考虑如何存储这些资料? 如何在大数据量情况下提供快速查询服务? 如何建设一个IT平台能随着未来业务成长而不断的弹性扩容,此为主要的改造思路。
- 社保系统是对外的公共服务平台于2008年上线,此平台是以互联网为载体,开通企业单位和个人网上申报业务的服务。 在面对日益增加的网络业务办理需求,平台硬件系统(多部高端Unix小型机)所承载压力逐渐加大。 系统硬件已逐渐出现瓶颈。在2012年1月集中申报期间, 系统的CPU(包含应用服务器和数据库服务器)高达90%以上, 导致系统不稳定,无法正常访问,影响重大。
- 经过社保相关单位仔细评估,确立系统改造的策略应由两方面着手, 一是建立虚拟化的云环境, 二是针对子系统瓶颈进行局部改造, 改造后的子系统平台需要支持“弹性扩展”,满足未来日益增加的网上业务。
- 采用VMware技术搭建虚拟化云平台来提升基础架构的扩展能力,采用Pivotal Gemfire 可弹性扩展的高速缓存功能, 支持高并发“热点数据”查询服务,降低原有数据库的I/O瓶颈,提高整个系统性能和稳定性。
3. 金融单位POC测试改造思路和需求 –建立可扩展的 “分布式内存缓存数据层”
金融单位系统庞大复杂,所有的子系统从设计到开发都需要严格遵循统一开发流程,
核心子系统业务逻辑不轻易更改。对系统而言,查询业务量多,数据量大,关联表格多,在高并发情况下,查询反应时间长。
POC测试目的:
- 在不改系统业务逻辑情况下, 对“数据访问层 DAO – Data Access Object”进行改造, 建立可扩展的 “分布式内存缓存数据层”;目的是提高业务查询性能,快速反应查询结果,降低原有数据库的I/O瓶颈,提高整个系统性能。
- 考虑系统稳定性和安全性, 还需要验证“分布式内存缓存数据层”与关系型数据库之间“失效转移 fail over”的设计。
三、12306系统改造迁移到Gemfire平台
在最初的框架设计已考虑系统性能问题,所以使用Stored Procedure开发来提升系统执行速度。此设计思路是参考德国和英国互联网售票经验 – 即总售票量20%的比率是透过互联网售票,也就是说当初12306系统规划是要满足每天售票量100万张的需求来设计。
在2012年春运12306对外开放时,涌入将近2千万人次登录,远远超过当初的预设目标,但又受限于系统架构无法弹性扩展,导致整个12306系统里里外外都不稳定, 无法正常访问。在采用Pivotal-Gemfire云化后的12306系统有了“质与量“的大跃进,在2015年春运售票高峰日已达560万张,占了整体售票量的60%;避免过去日夜排队购票的痛苦, 也节省大量社会成本。
由于12306业务逻辑复杂,系统庞大, 在此只以余票计算/查询为案例。有关整个系统的业务逻辑设计不在此讨论。下列的描述如果有误, 也请各位先进指正。
2012年 改造前的余票计算/查询子系统架构描述
1. 路局“实时”提供售票记录
火车票的席位销售是由每个路局规划和调控(铁路总公司共有18个路局), 而12306与每个路局是共享同一个“票库”。 换句话说,“线上”的12306是与“线下”的火车站点售票窗口,电话售票,和各地的售票点抢票。每个路局将每张票的销售记录都“实时“传送到12306在铁总数据中心“主数据库服务器”做汇总。
2. 数据库复制到余票集群:
在铁总的数据中心 - 余票计算服务器集群是由“主数据库服务器”和72部Unix小型机组成;主数据库服务器汇总各个路局传输过来的数据后,利用数据库复制的机制,实时将数据“复制“到72部Unix小型机。
3. 并行处理余票计算: 其中8部小型机做售票预处理,再将预处理结果送到64部小型机,64部小型机“同时并行”处理余票计算。
4. 应用缓存服务器: 64部小型机将余票计算后的结果汇总产生余票表,将余票表放置在前端的应用缓存服务器集群;此举是要解决在高并发的情况下,缓存服务器提供更快速的余票查询服务。
5. CDN(Content Delivery Network)服务器:12306最外围部署CDN网络,其目的是使用户可就近取得所需信息,将用户的请求重新导向离用户最近的服务节点解决 Internet网络拥挤的状况,还有调整负载均衡的功能,提高用户访问的响应速度。
6. 余票信息更新机制:余票信息更新是以“车次“为基准,每隔10分钟更新一次。当用户提交“区间站点”的余票查询时,先从CDN服务器查询资料,假如CDN的资料已超过10分钟,会从应用缓存服务器索取最新的数据。同理,当应用缓存服务器的资料超过时效,会触发余票计算流程,重新计算余票产生余票表, 提交给应用缓存服务器。每隔10分钟更新的参数是可调整的。
12306改造原则和目标
(1)设定性能指标:
以余票计算子系统为例,Gemfire集群的余票计算性能指标需要达到10,000 TPS以上, 并可以随着业务成长做弹性扩展。配合应用缓存服务器集群和最前端的CDN负载均衡服务器集群,预估12306可以支持每秒达百万次的余票查询。此部分的系统性能是与服务器CPU类型, 内存大小,Gemfire节点数和x86服务器数量都有关联。
(2)余票计算处理能力可随着虚机的增加而线性增加
余票查询是要反映最新的余票情况,作为购票的依据。 在上篇文章已谈到余票计算的复杂度,需要很强大的CPU处理能力为后盾来计算每个区间站点的余票量;将计算结果放置到缓存数据服务器和CDN服务器。余票计算是利用Gemfire Data Grid和Map Reduce的技术提供巨大CPU处理能力。
(3)在不改变原有的体系框架上增加Gemfire集群, 新旧两套系统并行运算
为确保12306生产环境的稳定性和平稳过渡,新旧两套系统必须同时运行,由最前端的CDN服务器控制访问流量,逐渐将需要余票计算的请求加压到Gemfire集群,测试Gemfire的承载能力,检验可扩展的功能。
(4)系统高可用性(High Availability)
Gemfire的数据节点都有其它节点的备份数据, 也可以将内存数据持久化到硬盘或是同步/异步写到数据库。
(5)x86服务器
考虑未来多数据中心和混合云的部署,必须使用x86服务器为生产机。
根据12306改造设计原则在不改变原有的体系框架上增加Gemfire集群, 在过渡期间,新旧两套系统并行运算,在过渡期后,以Gemfire集群为主。 所以此步的改造是针对上述”改造前的余票计算/查询子系统架构”的第2项和第3项进行分析和改造。
12306改造步骤:
(1)系统架构改造和数据上载
为确保12306生产系统的稳定运行和平稳过渡,在不改变原有的体系框架上增加Gemfire集群, 新旧两套系统并行运算。那就必须考虑如何将数据从数据库实时同步到Gemfire集群做余票计算。
A.数据库复制服务器 :增加一部数据库服务器,将铁总数据中心“主数据库服务器”汇总的数据实时复制到此部数据库服务器。
B.实时同步机制和SQL解析服务器 : 此步骤是从数据库取出Log数据并解析SOL语句,因为原来代码是用Stored Procedure开发的。
C.Rabbit MQ服务器 :同步机制服务器将解析过的SQL语句透过Rabbit MQ传输给Gemfire集群做余票计算。
D.Gemfire集群将余票计算结果汇总后,提交给前端的应用缓存服务器提供余票快速查询。
(2)系统数据结构分析
数据结构分析和设计是在改造过程中最关键的一步,影响到后续性能的提升; 利用“数据网格Share Nothing”的特性, 将数据切割, 把 “数据关联性强”的数据放在同一个Gemfire 数据节点,再配合业务逻辑的设计,降低节点之间数据交换的延迟,提高系统处理能力。
(3)Benchmark (基准点)测试
- 进行Benchmark测试, 评估每部Gemfire服务器的TPS和余票计算反应时间
- -验证Gemfire集群性能可随着x86虚机的增加而线性增加
- 测试“实时同步”机制, 量测数据同步到Gemfire集群的稳定性,延迟和吞吐量
(4)系统稳定性, 安全性和HA设计
在Gemfire的数据节点都有其它节点的备份数据来达到HA的目的,也可以将内存数据持久化到硬盘或是数据库。
使用Gemfire改造的实施流程:
1. 需求分析阶段:
- 需求调研,确定改造方案、
- 分析数据表结构、样本数据、数据量及应用访问特性信息
2. 架构设计:
- 设计Region结构,确定分区方式,和 设计二级索引
- 数据切割(partition)放在Gemfire的节点, 每个节点数据量大小是根据物理机内存来决定。例如, 在阿里云的节点一般是30G左右,在铁总数据中心的节点是60G-120G左右。 从项目经验来说,Gemfire数据节点以不超过128G可得到最佳效果。
- 利用Data Grid和Map Reduce的分布式技术提供强大的CPU处理能力。
- 使用到的Gemfire功能参考下列描述
3. 编码和单元测试:
- 12306是采用Stored Procedure开发,必须将Stored Procedure解析, 采用Java开发和编码,并将业务逻辑代码和数据都放在Gemfire节点, 此举可以达到最高的系统性能
- 单元测试
4. 集成测试/准确度测试/性能调优:
- 在集群环境下进行准确度测试
- 在集群环境下进行性能及压力测试
- 依据测试结果进行性能调优
- 性能调优可能需要调整细部架构的重新设计
5. HA和热部署测试
6. 线上运维:
- 创建Release版本并纳入管理
- 配置部署生产环境并进行持续监控
主要的Gemfire功能特性:
在12306改造过程中,使用到下列Gemfire的功能特性:
- Rich Objects: 以objects的形式体现和编码,自己定义数据结构
- Elastic Growth w/o pausing : 弹性扩展和热部署
- Partitioned Active Data : 根据数据属性,例如:客户,订单,车次,站名,做合理的数据切割,放在不同的数据节点。
- Redundancy for instant FT:HA的设置
- Colocated Active Data: share nothing的概念,将关联性强的数据放在同一个Gemfire 数据节点, 例如,车次,站名
- Replicated Master Data: 数据量不大的常用数据,例如:站名字典和席位类别等,在每个Gemfire节点都有一份拷贝,此举是要减少数据的交换。
- Server-side Event Listeners: 当数据在Server端产生变化时,会触发相应的操作
- Client-side Durable Subscriptions:当Server端满足客户端订阅的某些条件时,会推送信息
- Parallel Map-Reduce Function Execution: 车次余票在每个Gemfire 节点并行运算,再汇总运算结果
- Parallel OQL Queries
- Continuous Queries
- LRU Overflow to disk in native format for fast retrieval
- Parallel, Shared Nothing Persistence to disk w/ online backup
- Asynchronous Write Behind, Write Through or Read Through
四、社保项目子系统改造迁移到Gemfire云平台
社保申报子系统改造原则和目标
从访问量和并发量规模来说,社保所遇到的问题远远逊于12306所碰到的挑战。子系统改造是基于VMware虚拟化云平台基础上提升申报系统的查询性能。
(1)设定性能指标:
性能指标需要达到原有子系统性能50倍以上
(2)针对下列两个子系统瓶颈进行局部改造
- 缴费工资申报
- 城镇职工增加
(3)改造后的子系统性能可随着Gemfire节点虚机的增加而线性增加
(4)系统高可用性(HA)
参考12306描述。
子系统瓶颈的局部改造步骤:
社保系统是很复杂庞大的系统,由上百个模块构成。此系统采取三层架构设计, 使用Java开发。主要问题在于高并发申报过程中, 频繁的数据库写入和大量查询导致硬件平台高负载,子系统不稳定, 无法正常访问。
- 子系统的改造是针对数据库瓶颈提出改良方案
- 采取数据库“读/写分离“的方式,将数据“写入”关系型数据库;将“读”的操作由Gemfire集群来提供,因为查询的访问量数十倍于数据的写入量。
- 客户端资料写入时,同时将数据写入Gemfire节点和关系型数据库
- 将“欲改造“的子系统业务逻辑代码改写后移到Gemfire节点执行
- Gemfire集群提供刚录入“热点数据“的快速查询
- 不同子系统数据库之间的数据批量同步,将其它子系统“完整”的热点数据上载到Gemfire集群提供快速查询
相关的改造步骤和实施流程请参考上述的12306章节,改造后的架构如下图所示。
五、某金融单位POC项目 - 建立可扩展的 “分布式内存缓存数据层”
金融单位系统是由上百个子系统构成, 所有的子系统从设计到开发都要遵循标准统一开发流程,子系统采取三层架构设计,应用逻辑层与数据访问层设计层次分明。由于业务查询量大,牵涉到十几张关联表的查询,系统反应时间长。数据库读写频繁,CPU时常满负载,导致系统性能瓶颈。
POC子系统改造目标
改造方式是在不改变子系统业务逻辑情况下,对数据访问层进行修改DAO接口,引入“分布式缓存数据层”架构。
(1)设定性能指标:
性能指标需要达到原有子系统性能20倍以上
(2)针对两个子系统进行DAO接口改造
(3)验证改造后的子系统查询性能可随着Gemfire虚机的增加而线性增加
(4)系统高可用性(HA)
除了Gemfire集群的HA以外,还要考虑系统稳定性和安全性, 采用“失效转移 fail over”设计,万一Gemfire集群异常时,改由数据库提供查询服务
数据访问层(DAO)改造步骤:
根据客户场景的要求,子系统的改造是针对数据库提出改良方案,对数据访问层进行修改DAO接口,嵌入“缓存数据代理层” (Delegator)架构。
缓存数据代理层有如下功能设计:
- 缓存数据代理层向上封装数据访问接口,向下同时支持DB和Gemfire缓存数据层
- 与业务逻辑相关的API可以随着业务需求,按需弹性增加API接口的支持
- 根据Gemfire的特性,对SQL语句进行修改,设计成并行查询功能
- 考虑数据一致性的要求,客户端数据直接写入关系型数据库,再将数据同步到Gemfire集群提供快速查询。
- 万一Gemfire集群有异常,客户端可直接访问数据库,实现缓存数据层和DB之间的无缝切换
- 另外,其他数据库或Hadoop集群存储全量业务数据,可将“热点数据”上载到缓存数据层
- 通过Gemfire异步队列也可以将Gemfire的“热点数据”持久化到DB或Hadoop集群
- 当查询在Gemfire缓存数据层未命中时,通过Cache loader从DB或Hadoop集群加载数据到缓存数据层, 提供查询服务。
相关的改造步骤和实施流程请参考上述的12306章节,改造后的架构示意图如下:
六、结论和启示
由上面几个案例说明,不同的用户有不同的诉求,不同的系统开发环境和不同的限制条件所采用的改造方式也不一样。总结如下:
(1)12306项目: 流量高,并发性强,服务器负载高,反应时间要求严格;为了避免某一个环节的瓶颈,需要理顺整个流程, 将一系列的子系统做“云化”的改造。根据实际需求,将云化后的子系统按需部署在公有云提供服务。 改造的手段是用“分布式数据网格”的技术,结合业务逻辑特性和数据结构,将业务逻辑和关联性强的数据放在同个Gemfire数据节点,利用Map Reduce的技术提供强大的CPU计算能力来解决问题。
(2) 社保项目: 社保试点项目的改造重点是针对会发生瓶颈的子系统进行改造,将子系统业务逻辑和关联性强的数据放在同个Gemfire数据节点,利用Gemfire分布式并行查询技术来解决高并发查询的要求,并为政府行政部门管理透明化,内容更丰富的“Open Data”服务平台铺路。
对于人口大省,例如广东,河南,江苏和四川人口接近上亿的省份,随着社保体制的改革,更要考虑“大数据”的存储和查询,因为这些社保资料达P量级,需要存储数十年以上。 大数据和快数据的设计可以借鉴 12306 订单分级查询的机制,将“热点数据”放在Gemfire缓存集群提供快速查询,将历史数据存放在Hadoop集群。当查询在Gemfire缓存数据层未命中时,通过Cache loader从DB或Hadoop集群加载数据到缓存数据层,提供查询服务。
(3) 金融单位POC项目: 此POC的改造与上述两个项目不一样,在12306和社保项目改造都是需要将业务逻辑改写在Gemfire集群; 此金融单位POC的测试目的是在不改写业务逻辑的情况下,对原来系统的数据访问层(DAO)进行改造, 提供可扩展的分布式缓存数据层提供快速服务,并提供失效转移的设计。