数据存储服务器集群的伸缩性设计

2019-11-29  本文已影响0人  代码的搬运工

1、关系数据库集群的伸缩性设计

关系数据库凭借其简单强大的SQL和众多成熟的商业数据库产品,占据了从企业应用到网站系统的大部分业务数据存储服务。市场上主要的关系数据库都支持数据复制功能,使用这个功能可以对数据库进行简单伸缩。下图为使用数据复制的MySQL集群伸缩性方案。

在这种架构中,虽然多台服务器部署MySQL实力,但是它们的角色有主从之分,数据写操作都在主服务器上,由主服务器将数据同步到集群中其他从服务器,数据读操作及数据分析等离线操作在从服务器上进行。

除了数据库主从读写分离,业务分割模式也可以用在数据库,不同业务数据表部署在不同的数据库集群上,即俗称的数据分库。这种方式的制约条件是跨库的表不能进行Join操作。

在大型网站的实际应用中,即使今夕了分库和主从复制,对一些单表数据仍然很大的表,比如FaceBook的用户数据库,淘宝的商品数据库,还需要进行分片,将一张表拆开分别存储在多个数据库中。

目前网站在线业务应用中比较成熟的支持数据分片的分布式关系数据库产品主要有开源的Amoeba和Cobar。这两个产品有相似的架构设计,以Cobar为例,部署模型如下图所示:

Cobar是一个分布式关系数据库访问代理,介于应用服务器和数据库服务器之间(Cobar也支持非独立部署,以lib的方式和应用程序部署在一起)。应用程序通过JDBC驱动访问Cobar集群,Cobar服务器根据SQL和分库规则分解SQL,分发到MySQL集群不同的数据库实例上执行(每个MySQL实例都部署为主/从结构,保证数据高可用)。

Cobar系统组件模型如下图所示:

前端通信模块负责和应用模块通信,接收到SQL请求(select * from users where userid in (12,22,23))后转交给SQL解析模块,SQL解析模块解析获得SQL中的路由规则查询条件(userid in (12,22,23))再转交给SQL路由模块,SQL路由模块根据路由规则配置(userid为偶数路由至数据库A,userid为奇数路由至数据库B)将应用程序提交的SQL分解成两条SQL(select * from users where userid in (12,22);select * from users where userid in (23);)转交给SQL执行代理模块,发送至数据库A和数据库B分别执行。

数据库A和数据库B的执行结果返回至SQL执行模块,通过结果合并模块将两个返回结果集合并成一个结果集,最终返回给应用程序,完成在分布式数据库中的一次访问。

那么Cobar如何做集群的伸缩呢?

Cobar的伸缩有两种:Cobar服务器集群的伸缩和MySQL服务器集群的伸缩。

Cobar服务器可以看作是无状态的应用服务器,因此其集群伸缩可以简单使用负载均衡的手段实现。而MySQL中存储着数据,要想保证集群扩容后数据一致负载均衡,必须要做数据迁移,将集群中原来机器中的数据迁移到新添加的机器中。

具体迁移哪些数据可以利用一致性Hash算法(即路由模块使用一致性Hash算法进行路由),尽量使需要迁移的数据最少。但是迁移数据需要遍历数据库中每条记录,重新进行路由计算确定其是否需要迁移,这会对数据库访问造成一定压力。并且需要解决迁移过程中数据的一致性、可访问性、迁移过程中服务器宕机时的可用性等诸多问题。

实践中,Cobar利用MySQL的数据同步功能进行数据迁移。数据迁移不是以数据为单位,而是以Schema为单位。在Cobar集群初始化时,在每个MySQL实例创建多个Schema(根据业务远景规划未来集群规模,如集群最大规模为1000台数据库服务器,那么总的初始Schema数>=1000)。集群扩容的时候,从每个服务器中迁移部分Schema到新机器中,由于迁移以Schema为单位,迁移过程可以使用MySQL的同步机制。如下图所示:

同步完成时,即新机器中Schema数据和原机器中Schema数据一致的时候,修改Cobar服务器的路由配置,将这些Schema的IP修改为新机器的IP,然后删除原机器中的相关Schema,完成MySQL集群扩容。

在整个分布式关系数据库的访问请求过程中,Cobar服务器处理消耗的时间是很少的,时间花费主要还是在MySQL数据库端,因此应用程序通过Cobar访问分布式关系数据库,性能基本和直接访问关系数据库相当,可以满足网站在线业务的实时处理需求。事实上由于Cobar代替应用程序连接数据库,数据库只需要维护更少的连接,减少不必要的资源消耗,改善性能。

但由于Cobar路由后只能在单一数据库实例上处理查询请求,因此无法执行跨库的JOIN操作,当然更不能执行跨库的事务处理。

相比关系数据库本身功能上的优雅强大,目前各类分布式关系数据库解决方案都显得非常简陋,限制了关系数据库某些功能的使用。但是当网站业务面临不听增长的海量业务数据存储压力时,又不得不利用分布式关系数据库的集群伸缩能力,这时就必须从业务上回避分布式关系数据库的各种缺点:避免事务或利用事务补偿机制代替数据库事务;分解数据访问逻辑避免JOIN操作等。

除了上面提到的分布式数据库,还有一类分布式数据库可以支持JOIN操作执行复杂的SQL查询,如GreenPlum。但是这类数据库的访问延迟比较大,因此一般使用在数据仓库等非实时业务中。

2、NoSQL数据库的伸缩性设计

在计算机数据存储领域,一直是关系数据库的天下,以致传统企业应用领域,许多应用系统设计都是 面向数据库设计——先设计数据库然后设计程序,从而导致关系模型绑架对象模型,并由此引申出扩日持久的业务对象贫血模型与充血模型之争。业界为了解决关系数据库的不足,提出了诸多方案,比较有名的是对象数据库,但是这些数据库的出现只是进一步证明关系数据库的优势而已。直到大型网站遇到了关系数据库难以客服的缺陷——糟糕的海量数据处理能力及僵硬的设计约束,局面才有所改善。为了解决上述问题,NoSQL这一概念提了出来,以弥补关系数据库的不足。

NoSQL,主要指非关系的、分布式的数据库设计模式。也是许多专家将NoSQL解读为Not Only SQL,表示NoSQL只是关系数据库的补充,而不是替代方案。一般而言,NoSQL数据库产品都放弃了关系数据库的两大重要基础:以关系代数为基础的结构化查询语言(SQL)和事务一致性保证(ACID)。而强化其他一些大型网站更关注的特性:高可用性和可伸缩性。

开源社区有各种NoSQL产品,其支持的数据结构和伸缩特性也各不相同,目前看来,应用最广泛的是Apache HBase。

HBase为可伸缩海量数据存储而设计,实现面向在线业务的实时数据访问延迟。HBase的伸缩性主要依赖其可分裂的HRegion及可伸缩的分布式文件系统HDFS实现。

HBase的整体架构如下图所示。HBase中,数据以HRegion为单位进行管理,也就是说应用程序如果想要访问一个数据,必须先找到HRegion,然后将数据读写操作提交给HRegion,由HRegion完成存储层面的数据操作。每个HRegion中存储一段Key值区间(key1,key2)的数据,HRegionServer是物理服务器,每个HRegionServer上可以启动多个HRegion实例。当一个HRegion中写入的数据太多,达到配置的阀值时,HRegion会分裂成两个HRegion,并将HRegion在整个集群中进行迁移,以使HRegionServer的负载均衡。

所有HRegion的信息(存储的Key值区间、所在HRegionServer地址、访问端口号等)都记录在HMaster服务器上,为了保证高可用,HBase启动多个HMaster,并通过Zookeeper(一个支持分布式一致性的数据管理服务)选举出一个主服务器,应用程序通过Zookeeper获得主HMaster的地址,输入Key值获得这个Key所在的HRegionServer地址,然后请求HRegionServer上的HRegion,获得需要的数据。调用时序如下图所示:

数据写入过程也是一样,需要先得到HRegion才能继续操作,HRegion会把数据存储在若干个叫做HFile格式的文件中,这些文件使用HDFS分布式文件系统存储,在真个集群内分布并高可用。当一个HRegion中数据量太多时,HReigion(连同HFile)会分裂成两个HRegion,并根据集群中服务器负载进行迁移,如果集群中有新加入的服务器,也就是说有了新的HRegionServer,由于其负载较低,也会把HRegion迁移过去并记录 到HMaster,从而实现HBase的线性伸缩。

上一篇下一篇

猜你喜欢

热点阅读