我当年负责一个项目(中国电信BDC项目),购买的数据库硬件是P590小机组。通过压力测试后系统上线后,业务迅猛发展。小机的内存、CPU长期在98%上下徘徊。硬件虽然好,但是也扛不住业务的狂飙,应用服务器横向扩展相对比较容易,而数据库的升级相当的昂贵。
怎么办?当然首先是一堆的参数的调优和系统的调优。但是指标下降的不是特别理想;
怎么办?对系统进行合理拆分吧。
数据库拆分又分为垂直拆分和水平拆分,垂直拆分相对动静小一点。教育要从娃娃抓起,优化要从简单的抓起。
垂直切分,也可以称为纵向切分。我个人对垂直切分的理解是分两种,一种是把不同模块需要的表且分开,不同的模块放到不同的数据库中;另外一种是把一些特别大的表,把实际常用的字段,不常用的字段切分成两张表或者多张表。
也可以将数据库想象成由很多个一大块一大块的"数据块"(表)组成,垂直地将这些"数据块"切开,然后把它们分散到多台数据库主机上面。这样的切分方法就是垂直数据切分。
切分数据库模块
我们的应用系统,内部由很多个功能模块所组成的,而每一个功能模块所需要的数据对应到数据库中就是一个或多个表。而各个功能模块相互之间的交互点越统一、越少,系统的耦合度就越低,系统各个模块的维护性及扩展性也就越好。这样的系统,实现数据的垂直切分也就越容易。
在垂直切分之前,我们要把功能模块梳理清楚,耦合度越低,数据垂直切分的规则定义也就越容易。完全可以根据功能模块来进行数据的切分,不同功能模块的数据存放于不同的数据库主机中,可以很容易就避免跨数据库的事情存在,同时系统架构也非常清晰。
但是在实际中,如果这个系统当时是设计为一个系统,那么这些数据之间就必定有一些关联,否则怎么形成一个系统。但是在电信中,数据库之间的DBlink是不允许使用的,那么在特定的情况下,使用专门的接口或者让应用程序读取多个数据库然后处理数据,是一个必然的选择。
但是,数据本身规模的提升,比如主电话用户数达到了1.2亿,单张表的查询所需要的资源开销就已经非常大了,这个时候垂直切分起不了那么多作用,但是饭要一口一口吃,还是先把垂直切分的问题解决吧。
我们先分析一下,然后设计一个切分规则,进行一次垂直拆分。
初略一看,没有哪个模块可以脱离其他模块独立存在,模块与模块之间都存在着关系,莫非无法切分?
我们先把系统的主要功能模块进行分类,这样问题就清楚多了。
系统功能基本可以分为4个功能模块:电话用户表、地址库、对外服务库以及数据采集加工库(采编维),分别对应为如下这些表:
1.电话用户表:area,user,tel,…
2.地址库:address , …
3.对外服务库:out_search,out_user,out_tel,…
4.数据采集加工库(采编维):orders …
再稍微深入分析一下,可以发现,虽然各个模块所使用的表之间都有关联,但是关联关系还算清晰。
其中,数据采集加工库(采编维)和其他的模块没有必然的直接关系,那么可以考虑直接用一个新的数据库承接这块的服务。并且这一块的用户数相当大,和其他三个模块的使用情况比较接近,选定了一个目标,那就拆分吧。
我们的业务有一个特性,那就是和地区关系紧密,所有模块都需要使用area区域信息。
要共享区域信息有好几种办法:
DBLink最简单,而且能够共享一份数据,但是不符合公司的管理要求;
统一做接口,接口开发容易,调用也不难,但是对改造的系统,都有一定的改动,而且这个接口的性能要求不低,不是一个最优的选择;
最终选定的方法,就是在各个拆分的库之间,都放一张area表,因为中国的行政区划变化不频繁。与此同时,在这些area表之间做接口,如果数据有变动,会同步更新数据。
拆分之后,P590小机组是:电话用户表、地址库、对外服务库三大组;
有购买了P570小机部署:数据采集加工库(采编维)
切出来之后,数据采集加工库(采编维) 就成为了一个单独的项目,在以后的时间里,它发展壮大,成为一个大的平台,并且有了一个响亮的名字:统一采编维。
而我们,在垂直切分的路上,迈出了第一步。
垂直切分的优点:
数据库的拆分简单明了,拆分规则明确;
应用程序模块清晰明确,整合容易;
垂直切分的缺点:
配套的实际投入(软硬件)会增加;
部分表关联无法在数据库级别完成,要在程序中完成;
无法处理访问大且数据量超大的表的性能瓶颈;
事务处理相对复杂;
切分达到一定程度之后,扩展性会受到限制;
过度切分可能会带来系统过于复杂而难以维护。
切分数据库特大表
在早期的数据库设计中,因为各种各样的原因,会让系统中存在一些特大表。这些表,不仅数据的行数特别多;而且字段还特别多。
比如我们的老GPS数据加工表,这张表有220多个字段。数据量有6000多万。这种表,如果一不小心有人写的SQL是全表扫描,那么整个数据库实例都要被拖累。
就是一个普通的数据写入,创建索引也是一个很大的开销。
怎么办,其实垂直切分不是解决问题的根本途径,但是这个总归比较简单,在做一个重大的决定前,总要从简单的部分做起;就和跑步一样先做做热身活动,然后才能开始跑起来,这样才能跑的更好,更远。
这张表非常古老,一直忽视了他的存在,一直到有一天,有一位同事对这张表做了点操作,小机组差点挂掉。这个问题,必须要解决。
一步一步来,首先对这张表的220个字段进行分析,从属性上说,主要是用户信息,地址信息,GPS信息,辅助扩展信息(QQ号码、MSN号码等),操作日志等。
简单切分下,用户信息放用户表,用用户ID关联;地址信息和GPS保留,辅助扩展属性基本是空的,放到一对一的扩展表中,操作日志放日志表。
这样下来,GPS数据加工表的主表就只有30个字段,虽然有点多,但是比以前好太多了,剩下的问题,就是6000多万的数据了,那需要其他的处理方式。