万物之始,大道至简,衍化至繁。世间一切事物在刚刚开始的时候,都是非常简单的,是为大道,随着事物不断地发展,其衍变出来各种复杂的局面。然而,追本溯源,仍然会发现复杂局面下真正在左右事物的还是那些最基本的东西——大道。如果能牢牢把握住这些被认作是“大道”的东西,再复杂的局面也自然会变得简单。

近些年来,在数据库的领域里,可谓是群雄逐鹿,志在中原。他们各自有各自的特色,相互间也甚是喜欢用自己的长处去比较对手的短处,以彰显其产品的优势,眼花缭乱的测试结果和市场评价,其局面之复杂就像将要开启一个新的时代。不论是作为研发者还是用户,这样的竞争无疑都是一件好事,但也要求我们需懂得把握其中的大道。

为什么会有如此多样的数据库在市场上竞争呢?当然是市场需求在推动的,而需求的本身则源自于各行业的业务系统应用。如果说未来会开启一个新数据库时代,那很好。然而,现在无疑还是RDBMS的时代,其中的佼佼者还是Oracle数据库无疑。

本书将秉承大道至简的主导思想,立足于Oracle的数据库相关技术,给读者展示一套高并发业务系统的数据库架构设计方法论。

 

1.1 初见高并发

高并发这个概念并不新鲜,可以说有数据库的地方都有可能面临高并发的问题。在数据库里,高并发问题主要集中在两个方面:读的高并发、写的高并发,两者看起来都不是很复杂的,然而实际情况往往是读和写会交织在一起,并同时呈现出高并发的问题。

这个时候,相信很多读者都会提出一个观点:做读写分离嘛。是的,这是一个不错的主意,但只是一个治标不治本的主意。业务系统的耦合度很高,是不可能实现业务层级的读写分离的。在架构设计的过程中,不能驻足于技术层面,还是需要渗透到业务层面去的。不论是业务驱动技术,还是技术驱动业务,两者都是不能分离开考虑的,比较好的做法,应该是在两者之间形成一种平衡,当然这是需要架构师的分析能力和沟通能力来加于驱动的。

 

1.1.1 从一次谈话说起

应用架构师:“哥们!还记得上半年让你们帮忙做的一次数据库容量测试吗?”

数据库架构师:“当然!我们可是费了很大的工夫才完成的。”

应用架构师:“当时不是说我们在现有的硬件条件下,数据库的容量足够承受当时4倍业务压力吗?可是下半年我们的业务量才增长了0.5倍,怎么就不行了呢?”

数据库架构师:“从系统资源利用率的报告来看,CPU、内存、IO、网络上都没有太大的压力。但是,在业务高峰时段,CPU出现短暂冲高的现象。”

应用架构师:“没错!在应用端可以看到出现用户阻塞,中间件上的连接持续增加,没有得到及时释放。”

数据库架构师:“嗯,那是数据库未能及时响应造成的。CPU冲高,通过监控,我们发现很多并发的会话在争用一些资源,比如:数据块、索引块、Latch和Mutex。表现出很多等待事件的冲高。”

应用架构师:“我想我们遇到高并发争用的麻烦了。”

数据库架构师:“是的。当初这套系统的设计,预期到现在这么大的业务压力吗?”

应用架构师:“谁也不会有这种先见之明吧?当初只是一种业务的尝试而已,谁能想到市场的反应会那么好!从数据库层面来看,有什么好办法吗?毕竟现在的问题出在数据库上。”

数据库架构师:“办法总归是有的,针对性地一一解决掉。但是,这总归是治标不治本的办法。就像治水,现在压力我们堵住了,如果压力再大一些呢?我需要你的帮助。”

应用架构师:“你是说业务架构的变更吗?小变化没有问题,但是要像互联网公司那样大改,肯定是不行的,我们接受不了这么大的变化。”

数据库架构师:“是的,变革对我们来说,成本太大,小帆船掉头容易,航母掉头可能就要出事情了。”

应用架构师:“我们最近在开发消息队列,一定程度上能缓解用户的高并发压力。但这是以牺牲用户体验作为代价的,终归不是太好的办法。”

数据库架构师:“我想我们可以学习大禹治水,堵不上,就疏通。先将一部分业务压力分离出去,在子数据库和主数据库之间即时同步必要的数据,同时适当冗余数据到子数据库,减少数据库之间的交互。”

应用架构师:“是个好办法,我们现在不就是这么在做的吗?问题不还是在那里吗?”

数据库架构师:“我想是的。因为业务热点过于集中,在数据库上这部分业务数据耦合度又非常高,没有办法做到有效地拆分。”

应用架构师:“这不奇怪,我们的业务逻辑的复杂程度不是互联网应用可以比拟的,没办法像他们那样去充分地解耦。但是,我们是否可以学习他们使用廉价MySQL数据库代替Oracle数据库,这样业务分离的成本就低了很多。”

数据库架构师:“你确定这样的成本会低吗?Oracle数据库的开发人员真的会开发MySQL吗?我们的业务逻辑是很难在MySQL数据库上实现的,现在Oracle数据库帮助我们完成了大部分的数据耦合,如果使用MySQL,这些都将要在应用端完成,开发成本将会增加。另外,Oracle有强大的优化器机制,开发者写得不算太好的SQL,它也能包容,MySQL则不然了,SQL写得不好,马上给你颜色看,因为它的优化机制不能跟Oracle相提并论。与Oracle相比,MySQL只能作为一个数据容量来看待。”

应用架构师:“你说的这些我也明白,但是我们的数据库是应该架构扩展了吧?”

数据库架构师:“当然。虽然我们不能做到充分的数据解耦,但是一点一点的解还是可以的吧。我们现在的问题是解决高并发问题,而高并发集中的那部分业务就是我们的目标。”

应用架构师:“那部分业务很难弄哦。读写比例为5:1,写操作占比还是蛮高的,而且都交织在一起的。最大的问题是要保证较快的响应速度,否则高并发压力就会积压。”

数据库架构师:“内存数据库!将其作为Oracle数据库的前置缓存数据库,来加快响应速度,如果保证了快速响应,高并发压力也就解决了。眼下Oracle和SAP都在内存数据库上大作文章呢。”

应用架构师:“他们都是在搞OLAP的内存数据库吧,我们的可是OLTP。”

数据库架构师:“Oracle的TimesTen就是为了解决OLTP的并发问题而研发的哦。关键是看我们的应用是否适应得了。”

应用架构师:“嗯,是多样化的数据库架构了。”

数据库架构师:“是的,就像一套数据库生态体系,没有必要特别待见谁,也没有必要特别排斥谁,关键是看应用的需要。不过,我们也需要反思一个问题,就是当初Oracle的设计阶段没有预见性,应该从Oracle内部设计先把握好,加强其处理并发的能力。是谓:‘先修内政而后纵横。’”

 

1.1.2 问题就在那里

看过冗长的对话,我们来总结一下吧,问题到底出在哪里?

q  Oracle数据库架构设计之初,粗放设计,没有充分把握细节;

q  业务数据耦合度过高,无法充分解耦,革命性的变化成本太高,不能接受;

q  业务逻辑比较厚重,灵活性不高;

q  可以接受架构创新。

以上问题,相信很多架构师和数据库管理员们都会面临。更多时候,我们都是无力去推动业务的,让业务适应技术,一直都是技术人员美好的愿望,却鲜有实现。现实一点地来看,我们只能一定程度上去引导业务,也不能完全让技术去适应业务,两者需要达到一种平衡。

立足于大多数的传统行业,来看一看应用的现状吧。业务逻辑都是经年累月沉淀下来的,要想革命性的变化确实很难,除非行业革命。谁能想象一下,让银行去拆分核心逻辑呢?业务看似刁难的要求,也蕴藏着行业的特点,架构师是需要充分认识到的。

如图1-1所示,理想情况下的应用系统架构中的子系统应该是相对比较独立的,子系统之间关联较少,而且相互关联的子系统数量相对较少。实际情况往往是大相径庭的,子系统之间存在很高的耦合性。子系统内读写错综复杂,基本上不可能实现读写分离。面对这样的现实,出于成本和风险的考虑,很难做到子系统的解耦,理想情况也只能是理想了。

 book_ch01_01

图1-1  架构现状

业务子系统与数据库的对应关系,如图1-2所示。在一套完整的数据库生态体系中,子系统和数据库也不是能独立开的。理想情况是若干子系统分布在一个数据库中,数据库基本上是自包含的。现实仍然是残酷的,往往是子系统和数据库出现多对多的关系。

 book_ch01_02

图1-2  子系统与数据库对应关系

 

那么数据库架构设计就需要反映这样的业务架构,如图1-3所示。对于某一系列的业务应用来说,肯定不可能通过单个数据库来实现的。需要的是一个数据库群,其包含核心库、业务应用库,以及各种功能的库,根据重要性做层级划分。数据库之间实现即时的数据同步,实现一套完整的数据库生态体系。

 book_ch01_03

图1-3  数据库生态体系架构

做到这些是不是就解决问题了呢?当然没有,如果解决了,也不会有以上那段对话。但是,这种架构的演化方向确是正确的,将错综复杂的业务分为治之,如果某些业务上出现了很高的并发压力,不会影响到其他业务的应用,可以将影响面控制在最小范围内。

虽然本次在架构建模阶段没有充分考虑到Oracle数据库的细节问题,但是也可以作为一次经验教训,为下次的建模工作提供指导。比较可喜的是,我们也不必坐以待毙,架构的创新始终都是受欢迎的,因为这意味着数据库的并发处理能力的提升。

从技术层面来看待以上的问题,我们可以去做好两件事情:

q  Oracle数据库架构设计工作细化。

q  以Oracle数据库为中心,开展架构纵横扩展。

 

1.1.3 你不是一个人在战斗

对于现在的企业级应用系统来说,数据库一般不会成为一套系统的瓶颈所在。数据库出现高并发问题往往都是热点业务集中争用造成的结果。为什么这么说呢?因为现在的数据库应用中,不论是Oracle数据库,还是MySQL数据库,抑或其他新型数据库,它们都不是一个人在战斗。

如图1-4所示,在一套比较完整的应用系统架构体系中,一般可以分为四个大层级:

应用层:直接服务于最终用户的,完成用户行为的交互。

网络层:后台处理的第一个层级,实现网络路由,并通过网络负载均衡器实现第一次负载均衡,使高并发压力第一次得到分流。

中间件层:就是通常说的B/S架构的中间服务器层,其接收网络层来的用户连接,并实现第二次负载均衡,所不一样的是网络层是通过硬件实现负载均衡,而中间件层是通过软件实现的。同时,其按照一定的逻辑配置连接数据源。

q  数据路由:隶属于中间件层,是数据库层的一个前栈,实现分布式数据存储的路由。一般来说,数据库使用分布式存储的话,这个组件都是不可少的。

数据库层:这是我们最关心的,也是最底层的结构,可分为核心数据库层和前置数据库层。

  • 核心数据库层:传统意义上的数据库群所在的区域,我们按照不同的功能应用,区分不同的数据库存储,包括:核心库、子系统库、灾备库(可细分为远程灾备和本地灾备)。如果业务扩展,可以通过ADG库和T-1交易库实现部分业务的分离,这两个概念我们会在第二部分纵横篇详细介绍。
  • 前置数据库层:这个层级是可以部署在核心数据库层的前端,也可以平行部署,其另一种叫法是数据库中间层。可以部署一些内存数据库,分离高并发业务到这个区域,也可以部署一些开源的数据库,分离边缘化的应用于其中。

 book_ch01_04

图1-4  系统架构概要图

 

可以看到,一个完整的体系架构远比我们想象得要复杂,云的概念也是基于这个架构逐渐衍生出来的。就拿数据库层来说吧,我们平滑地实现数据存储的横向和纵向的扩展,并对上一层级是透明的,那么我们就实现了数据库的池化,也就是说对外服务的数据库可以视为一个,基本上实现了数据库云架构。

从以上架构来看,高并发的压力经过了网络层和中间件层的过滤,到达最底层的数据库层,基本上都不会有压力了,应用层、网络层、中间件层都可以视为数据库的保护层。当我们进行应用系统压力测试的时候,绝大多数情况下,数据库都是没有太大压力的,最容易出现问题的往往是中间件层,换而言之,在数据库被压垮之前中间件层已经被压垮了。这也提醒我们只做系统应用压力测试是不够的,我们还需要做数据库的压力测试,找到数据库层的瓶颈所在。

是不是可以就此掉以轻心呢?当然不能,数据库出现高并发压力在实际应用中还是比较常见的。难道我们前面说的不对?不是的,可以看到不论是网络层,还是中间件层,都是在分流压力,压力并没有凭空消失,这些用户会话要访问的数据分布是无法控制的,如果分布过于集中,那么数据库会在某一个点上出现高并发争用,也就是热点争用,如上述谈话的背景一样。

面对高并发压力,我们现在已经很清楚自己要做什么了吧?就是一定程度上实现数据访问的分流工作,也就是通常所说的纵横扩展。另一方面来看,任何的扩展都是有一个核心点的,就是我们的Oracle数据库,扩展工作一定程度是对其核心地位的弱化,但是核心仍然是核心,在扩展之前,必须合理地做好Oracle核心库的设计。

Trackback

no comment untill now

Add your comment now

切换到手机版