数据库的弹性伸缩与WebServer相比,复杂了很多倍,对于WebServer的弹性伸缩直接用负载均衡 弹性伸缩组件搞定。但对于数据库的扩容、缩容将面临数据不一致等问题。这些问题在互联网企业上云是必须解决的,为提升我们对大型业务上云的理解,我们今天一起来看一看。
一、数据库的弹性伸缩究竟会出现什么问题?
传统公司习惯对数据库进行垂直伸缩,他们购买更强大的服务器,增加更多的内存,换更快更大的磁盘,期望数据库引擎能够利用这些资源实现伸缩。绝大多数传统公司都是这样做的,但随着互联网的屈起,系统的支撑数据量、并发量像火箭一样直升。
数据库的伸缩主要问题是,服务器是有数据业务,是重有状态化的数据,增加、删除服务器都会对数据的访问带来直接影响。例如:因数据量下降,自动删除一台数据库服务器,而上面有数据该怎么办?再如,业务量上升,自动增加了一台数据库服务器,新的服务器该承载哪些新的业务,与原服务器的关系是什么?
二、该如何解决这些问题?
1、传统方式是做数据库的主从同步、主主同步,但仍存在瓶颈。
主从同步:主用服务器只有一台,而从服务器N台。主用作为写使用,从服务器作为读。但写的服务器只有一台,还是会遇到数据处理能力的上限。
主主同步:此时各服务器之间的关系是同等的,主用1写入一条数据,主用2自动也同步写入该数据,反之亦然。但主主同步会遇到数据不一致的问题出现,在实际生产环境中很少使用。
2、数据库的拆库,解决了一部分问题,但仍在瓶颈。
将数据库的一个大库拆成若干小库,如用户管理库、商品库、订单库等。但随着用户的增加,瓶颈仍存在。
3、数据表切片,在互联网生产场景中很多。从根据上解决数据上限的问题。
将数据表进行拆分,单个表存放在若干个服务器中,才能真正解决数据上限的问题。
如果将MySQL的商品订单Orders表按用户名进行拆分,用户名1按10台服务器取模,则用户1的Orders数据放在数据库1服务器中;用户名2按10台服务器取模,则用户2的Orders数据放在数据库2服务器中,以此类推。此时,JAVA上层DOA数据访问层根据取模来决定与哪个数据源进行数据互通,由应用程序自身进行数据源的拆分、查询管理。
但新的问题来了,如果10台服务器不够,再增加了一台服务器,按取模的数据映射关系将变化,数据将异常,怎么办?解决办法是将映射关系拿出来,单独放在一台数据库服务器,进行管理。应用程序需要访问数据前,首先在映射关系数据库中查询该数据存放的数据路由,再发起数据连接访问。
上面讲得很复杂,实际在公有云中,很多服务商支持分布式数据库的功能,包括提供映射关系的中间件,客户直接使用就好了。云的好处就在于此,前人种树,后人乘凉。
四、数据表拆分将带来的新挑战
数据表按UserID进行拆分后,好像天下大吉,但新的问题产生了,不支持数据库的联合查询。
例如,在单数据库服务器的场景,需要查询最近7天的Top1商品销售情况,只需要一台SQL语句。select item_id,SUM(amount) total from orders where order_dat >'2019-07-07' order by total;
但在数据表拆分后,同一个数据表将拆分在很多个服务器,如果将每个服务器单独查询,再取最大值。听起来,好像正确,但实际结果也许将错误。因为随着服务器的增加,同一个商品的订单记录也许将散在很多服务器上,还需要应用程序进行累加计算,非常复杂。
因此,数据表拆分后,数据库的联合查询将产生新的问题。目前很多公有云的服务商都无法提供分布式数据库的联合查询动作,需要应用程序的更多参与解决。
技术与业务总是在同步变化、升级,相信问题将逐步解决。