3月12日下午在阿里巴巴西溪园区,举行了MongoDB杭州用户交流会。微软MSDN特邀讲师徐雷分享《基于MongoDB的*云平台高并发高可用HA架构实践 》,从自身实践出发,讲述了*云平台分层、技术栈选型、物理架构、API架构及DB数据库架构的设计思路和方法。
以下内容根据现场分享和演讲PPT整理而成。
学习MongoDB的重要性
目前,几乎所有国内外的互联网大公司都在用MongoDB,学习企业需要的技术很重要。
MongoDB优点
相比较关系型数据库而言,MongDB有两个明显的优点:灵活的数据模型和便于横向扩展。
灵活的数据模型:作为一位网站开发者,最痛苦的就是需求变更,MongDB可以接受字段的不断修改,非常灵活。
便于横向扩展: 如果有海量数据存储,这时可以做Sharding,非常容易,这个是MongDB本身已经支持的。传统的关系型数据库在这一块比较难实现,因为它会由很多固有的设计缺陷导致。但传统关系型数据库的分片思想和MongDB分片思想其实很像,从算法的角度来说,没有太大区别,比如基于范围进行分片,这两个是通用的。
高并发与高可用架构关键点
程序员一般追求高并发,对于高并发这个关键词容易产生兴奋点。作为架构师设计一个架构,如果要支持某个级别的并发,一定要注意:不是用Redis就是高并发,不是用MongDB就是高并发。高并发高可用架构关键点包含:多线程、分布式通信RPC、集群、负载均衡、网络与硬件、监控与诊断等。比如Java有多线程、高并发的问题,如果涉及到分布式通信RPC 、分布式架构的话,一定会有一些RPC的技术,会有线程通信、进程间的通信出现,这些在不同框架中都有对应的实现。架构师在设计架构时,需要深入研究。
集群:是不是一定要用集群?不一定。一般小规模公司才用3-5台服务器,大规模公司用128G、256G、甚至2T的服务器内存,连数据和索引都进服务器。MongDB在数据量非常大的时候,比如你有16G内存,发现它很慢,有一个很重要的问题,稍微研究下底层的算法,会发现MongDB在使用索引结构进行数据查询的时候,它需要对索引进行遍历,如果能整体进内存最好,如果不能整体进内存,它就部分加载,这样的话就更慢,因为涉及到一个磁盘内存问题。
负载均衡:假设用了集群,比如有10台web服务器,需要做负载均衡,可以用业内比较成熟的实现方案,比如阿里云、微软云、亚马逊云,直接配置就可以用。如果要构建私有云,或者数据中心的话,需要想一些负载均衡的方案。比如业内比较流行的,软负载均衡,反向代理负载均衡。
网络和硬件:这也是高并发的前提。比如10w并发,平均一个消息多大,估算一下网络流量,不要说不管带宽是5M,还是10M,就要10w并发,这需要看硬件的服务器配置,所有的高并发一定是个完整的体系,不是说在某个点上,写段代码就高并发了。所以现在看到的高并发系统,一定是经过无数次的迭代。
监控与维护:这是运维最头疼的。因为运维每天晚上需要远程登录看机器正常不正常,影响正常休息,所以现在也提出了自动化运维概念。
*云平台背景
*也需要进行转变,他们希望把整个*平台信息化,构建统一高效的*云平台。比如税务的信息化、公务人员考核的效率化等。
基于前面说到的,设计的架构一定要微观上+宏观上高并发,不能说了搭了几层就是高并发架构,首先要看写的代码,如果在后台就产生了大量问题,大量bug,怎么能够高并发,从前端到后台是一条链,任何一个节点出问题,都会影响整个系统架构。
*云平台分层架构图
从上图显示,这个架构系统不是只有关系型数据库,或者NoSQL数据库。因为这个场景是比较特殊的。对于*官员考核的指标比较多,每个指标量化单位不一样,考核数据模型是会变化的,会导致数据的不确定性。这个时候比较适合用NoSQL,如果用传统关系型数据库的话,开发就需要天天改数据层的表。
参考上图,我们做的技术并不仅仅是一种技术,需要考虑传统PC端,也要考虑移动端的问题。这里作为服务治理层,或者服务层,这里服务治理层不仅是服务层,因为希望对服务做一个统一的规划和安排。另外希望后期加一些自动化运维和监控的知识,包括现在比较新的微服务的概念,这是设计的思路。
协议的话,也没有固定只用http这一个,也没有只用soap协议。可能大家会说因为你对 SOA 架构比较熟,但其实今天所有的系统架构,这个叫SOA的概念已经存在。不是说用哪个框架,就一定能解决问题,不推荐这种方式。如果涉及到移动端,可能会用到MQTT协议,如果是页面应用的话,可能会用到最新的web socket。
业务逻辑层上,分层不是越多越好,而是根据需要分层,分完层之后是否方便后期扩展。比如业务逻辑层,Java和.NET里面都有分层的思想,这个部分把业务逻辑独立出来,不影响其它层。需要注意一下,这里用到Redis,前面讲过高并发的系统应用,Redis我们推荐。如果公司有能力开发一套缓存系统可以开发,比如阿里巴巴的RocketMQ消息队列,如果开发不了,就用开源成熟的产品。Redis目前是最流行的开源的免费缓存,它属于NoSQL的范畴,这两个结合和MongDB不冲突。MongDB能够解决10000个并发,一般公司够用。如果遇到峰值的时候,可以用兔子消息队列,让其帮助从中加一层,来缓解数据库压力。缓存技术除了加速以外,还可以充当请求缓存池,用于处理一些不太着急的请求。
再说一个问题,这里不论是Java和.NET,连接数据库的技术都是差不多的,都有连接池,都有多线程,而且垃圾回收的机制也差不多。同样如果想对传统型关系数据库或者NoSQL数据库做研究的话,可以看下NoSQL并发有很重要的问题,传统关系型数据库是不强调事务的,但是传统的NoSQL数据库,从诞生之初开始,高并发是它很重要的一个特点。目前NoSQL也开始支持事务,但是部分事务,不完整。关于MongDB有很多坑,因为它有几个存储引擎,这个有点像MySQL,MySQL也有几个开源的存储引擎,每个存储引擎都不一样,要用这个数据库的话,需要注意使用版本、存储引擎,需要在官方文档上确认一下。
*云平台技术栈选型
Java底层和.NET底层原理是相通的,数据结构的算法基本上一样。但为什么有些是Java做的,有些是.NET做的,这里面我们会用到。反向代理考虑到尽量是免费的,节省成本。涉及到一些日志框架,建议用最成熟的框架,这里没有平台或者语言系统的偏见。用Docker方便运维。
*云平台SOA架构设计
现在有手机定位,自动驾驶,*也在考虑这些问题。比如*希望看到各省县长的履历,进行优先提拔;比如要防控房地产的问题,房价波动厉害,需要了解房地产的交易资金,房地产大数据等,任何一个指标*都希望能看到。SOA叫做面向服务的架构,是基于服务来集成现成的系统,这个架构没有过时。
*云平台新SOA架构:ESB+微服务
这些架构如果开始做的话,两个系统直接服务集成,后面更复杂的问题来了,像阿里巴巴自己做了一个服务框架叫Dubbo,它里面有服务治理的事项,也有微服务的特点。作为一名技术人员,一定要注意它的试用场景,如果没有这些框架,能不能做个类似的功能?
这里面涉及到一个问题,如果后期系统特别多,最好有一个中间件平台的概念出来。这样在服务治理的过程中,可以更好的规划系统架构,而不是所有系统之间随便连接。随便连接的后果是,后期所有系统接口都是乱的,系统越多,乱的越厉害。比如早期是webservice,有可能后期改成TTP,或者改成HTTP等等一些新型的协议。
另外,这还涉及到高并发高可用的问题。网站选一个高并发的框架,在网站上要求1w个并发,一台服务器支持1w/秒的并发,接下来你想要10w的,一定要想办法进行横向扩展,当然如果企业特别有钱,可以把服务器换成1T的内存。还有一个高可用指标,比如每秒是1w个并发,更新一下直接挂掉,这是不行的。
省级单位*云平台物理架构
物理架构和逻辑架构不同,逻辑架构可以分10层、100层都可以,但不是分层越多越好。分层越多,解耦越厉害,越影响性能。很多人不管设计什么架构,先分个三层,不管需不需要,直接把接口用webservice包容。这里一定要根据需要做判断。
MongDB做集群,做高可用。首先,保证物理安全,服务器不要坏掉;然后,MongDB可以支持数据直接加密,金融数据不安全的话,数据永久加密。MongDB3.4版本之后加了金融的数据类型。
MongDB可以做可复制性集群,这里可以一对多,但是有个问题,它可以实现自动化过程转移,如果说数据访问层开发的比较好的话,使用了较新的驱动,无论是Java还是C sharp ,它可以自动化来切换。在这个集群中,它自动会找一台新的节点出现,来替代主节点。这是相对于传统数据库MongDB做的好的地方。作为运维只要把web关系层配好,就不用担心哪台服务器在服务,直接可以自动化切换,图片服务器和缓存服务器,也不是所有的数据都进缓存,有部分数据为了缓解压力,把用户资料的数据可以放到缓存里,这样可以从缓存里拉所有数据。
负载均衡的话,用硬件软件都可以,负载均衡如果只用一台服务器,风险较高。CDN从单数据中心扩展到多数据中心也可以,一般公司还用不到多个数据中心。
*云平台服务治理API架构设计
所有系统上线之后,不是简单的开发和发布,后期系统需要跟其它平台进行对接,会有一个服务组件的中间件平台,可以用开源的,也可以用商用的,比如Oracle、SAP、微软、阿里巴巴的中间件平台。中间集成可能会有不同的协议,这里面会涉及到很多问题,Redis后面可能会换成消息队列,比如一个5年考核指标,一个月内的数据量比较大,这个时候数据库肯定要持久化,有些内容放到MongDB,有些会放到传统的关系型数据库里面,需要提前做一些预测。再注意一个问题:这里的数据web层和访问层,全部都是集群。Redis也是支持集群。
系统上线之后,要看哪些系统出现异常了,什么样的异常是需要马上解决的,这里面涉及到服务监控的问题,需要配合专门的运维工程师制定一些规则。
另外,缓存在UI层就有了,API这层也可以有缓存,不是所有的东西放到Redis里面才叫缓存,Redis属于分布式缓存,有些数据可以放到数据持久层,比如关系型数据库,MongDB也有,服务器只要配置够高,数据直接进数据持久层缓存或者数据访问层缓存也可以。如果单独加一层缓存也可以。像中间件平台也有独立的缓存,API层也有。从架构角度来说,要想下缓存放在哪层比较合适,相应的硬件配置要跟的上。当然,越接近客户端的缓存,效率越高,因为它的物理位置更接近客户端请求。如果放在最下面,说白了中间要经过很多层才能到数据这一块。
省级单位*云平台DB数据库架构
*系统,首先物理上保持隔离,再保证安全。要注意的是,峰值出现的时候,需要加一层缓存或者消息队列。
*系统的数据量规模是有限的。小规模系统可以用可复制集群,保证数据库节点的自动化灾备转化就可以了,这样的好处是:首先,读写分离把压力分担了;另外,如果出问题,可以自动化灾备、自动化切换,避免手动修复,或者宕机带来的一些问题。
缓存数据服务器最好用两台。比如支付宝,新浪微博做的比较成功,大量数据放在缓存里。缓存也有读写分离。一些互联网公司的测试数据显示,Redis的并发能达到每秒11w,所以它很适合做数据持久层的这一套缓存机制,无论是传统关系型数据库,还是MongDB,用普通的SSHD,每秒只有1w写入量的话,可以把数据先写入Redis,这个并发高,基本上10w的并发,能够满足绝大多数互联网公司的需求,如果还不行,可以写入的数据量少一点,再做读写分离。
*云平台架构设计考量
推荐阅读
《MongoDB实战》
《jQuery 实战》