一篇了解集中式数据库的集群计算

节前写过一篇关于分布式数据库的文章,当时有几个朋友和我讨论集中式数据库和分布式数据库如何选择的问题。实际上,数据库产品都不是万能的,对于不同的应用场景,不同的用户群体,其对数据库的选择有所不同。对于一些用户或者一些应用场景来说,可能选择分布式数据库是必然的选择,另外一些用户或者应用场景,选择集中式数据库更简单一些。

总体来说,集中式数据库因为相对简单,因此可能适用的场景更广泛一些,特别是对于中小型非关键性系统或者没有能力运行于维护大型分布式数据库系统的用户来说,选择集中式数据库可能更符合企业的需求。

实际上使用集中式数据库的客户也需要很多分布式数据库具有的特性,比如高可用、多副本、故障自动隔离、横向扩展等。

很多用户都怕集中式数据库的单机总体容量可能受限,实际上对于绝大多数系统来说,单机容量达到极限还是很困难的。无论是内存,CPU,IO,网络、存储容量,现在的上限都相当高,对于一般的系统来说还是比较难达到极限的。

虽然如此,集中式数据库支持某种意义上的横向扩展还是很有必要的。比如ORACLE 的RAC,虽然不能像分布式数据库一样横向扩展到几十上百个节点,RAC的横向扩展能力还是会让人感到比较放心。对于国产集中式关系型数据库来说,强一致性读写分离是很好的横向扩展方式,其实现方式没有Oracle RAC那么难,又能够解决大量的读操作消耗过多系统资源的问题。通过一个较好的方案实现强一致性读写分离,是国产集中式数据库在同质化竞争中脱颖而出的一个途径。

可能有些朋友会说了,现在的国产数据库,开源数据库,基本上都有类似的功能,这个有什么难的。实际上目前开源、国产数据库的集群计算都是外挂的,不是从数据库的底层设计开始的,仅仅是集群计算框架与原有RDBMS内核的整合。

要想把这个问题说清楚,首先我们需要分析一下客户为什么需要找个功能。有些时候客户需要强一致性的读写分离并不是为了横向扩展,而是用一种最简单的方式实现应用系统的高可用。

数据库的无数据丢失强一致性同步一直是保证数据库高可用的一种客户的强需求,虽然大部分用户可以接受部分的数据丢失,只要当主系统故障的时候,能够快速恢复业务就可以达到他们的最基本的要求。不过正是因为故障切换是有损的,所以在真正做切换的时候还是会有些犹豫。因为每次切换后,都有一些脏数据要处理,对于运维部门,业务部门,开发商来说,都是留下了一些尾巴。如果切换后能够实现0数据丢失,不需要做收尾的工作,那么当主系统故障时,就会十分坚决的进行故障切换了。

强一致性同步的另外一个好处是,我们的MIS类的系统中,读写比例高达8:2甚至9:1,在应用的角度上讲,把一些读操作都转移到只读副本上去,可以大大减少主实例的负担,也可以减少主实例故障的几率。如果主备实例的数据不是随时都是完全一致的,那么我们的应用需要做相应的修改,确保某些只读操作是可以在只读副本上运行,有些只读操作需要强一致性,必须在主实例上运行。不过如果主从数据库系统的数据随时都能确保强一致,那么在一个集群环境中写应用的难度就大大降低了。

除了强一致性的读写分离,客户的另外一个重要需求就是透明应用故障切换,这个词Oracle简称TAF,属于RAC故障切换的一种早期方式,虽然十多年前这种切换方式就已经被更为强大的快速连接故障切换(FCF)所替代,不过目前国内的大多数应用软件还在使用TAF。TAF的好处是当数据库实例故障时,应用可以自动切换。

Oracle 12.1后支持的GDS服务就可以在一个集群计算环境中支持读写分离、负载均衡与故障切换,我们的国产数据库厂商可以认真学习一下其功能与实现方式。

Oracle GDS可以构建一个统一而又复杂强大的统一计算环境,让RACADGOGG等复制技术与计算框架有效地整合成一个整体。

我们需要数据库集群计算环境的强一致性,强一致性读写分离的实现方式主要有以下几种:

  • 第一种模式:多实例共享存储+缓冲区融合的读写分离:多个读写分离的数据库实例共用一套存储数据,只有主实例支持读写,其他实例均为只读。对于未写盘的脏块,直接从主实例的缓冲区中获得。这种实现方式比ORACLE RAC的多主模式实现起来要简单一些;
  • 第二种模式:多实例共享存储+WAL APPLY:和第一种模式类似,采用一主多从模式,主实例可读写,其他实例只读。不同的是,多实例之间是完全独立的,不通过缓冲区融合来保证读写一致性,而是通过在备用实例上重演WAL数据来确保读写一致性。这种模式比第一种模式的优点是主从实例之间完全是独立的,互相的影响不大,只要底层存储支撑得住,从节点的数量多一点也问题不大。缺点是如果主实例存在大量的写操作,那么从实例的重演可能会产生一定的延时。Polardb-PG就是采用这种模式的一个例子;

  • 第三种模式是多实例存储复制+WAL APPLY:为了防止底层存储的IO性能达到极限,从底层实现存储的同步/半同步自动复制,确保多个存储副本之间的数据一致性。不同的实例可以使用独立的副本,或者某几个有限的实例共享一个独立的副本。其他的实现方式和第二种模式类似,这是第二种模式的变种方案。亚马逊的AURORA DB CLUSTER就是这种模式的典型案例;

  • 第四种模式是多实例非共享存储0数据丢失复制:主从实例是完全独立的数据库,在存储底层确保WAL数据自动实现无损复制,确保已经提交的事务的WAL文件能够复制到从库。从库通过日志重演确保与主库的同步或者半同步。

实际上,以目前的数据库与分布式数据库技术,实现上述的四种模式,在技术上并没有不可逾越的难关,最关键的是需要从数据库SQL引擎、存储引擎、缓冲区管理、DB WRITER、WAL WRITER等核心组件上到操作系统、存储系统、网络实现全栈贯通的设计和优化,使之成为一体化的数据库设计,而不是把一堆组件做简单的集成。这种一体化的设计与实现,才能够从整体上实现最优处理,自动处置各种异常,并自动进行相关的容错处理,从而确保数据库提供的强一致性读写、故障切换、故障数据修复等都是能够根据数据库底层模块自动完成的,而不是需要运维人员或者应用开发商去做相关的处理的。甚至今后在SQL执行算子方面实现下推,实现某些计算场景跨数据库实例的并行计算。

这种计算框架可以解决一些当前集中式数据库中比较麻烦的问题。比如大型数据库表分析时产生的大量IO导致的系统性能问题。在这种计算框架下,可以按照下面的方式实现集群计算。

当表分析任务发起后,主库分解分布式计算的任务,通过消息队列分发任务给各多个从库,由从库完成实际的计算任务,再把结果发送给主库,由主库统一入库。再通过复制技术分发到各个从库。

如果是十多年前,当硬件处理能力、分布式复制技术等还没有发展到今天的时候,集中式数据库的设计可能不会向这个方向去考虑,不过随着这些年软硬件与分布式计算框架的高速发展,我们的集中式数据库的架构设计是不是也可以脱离开已经使用了几十年的老方案,尝试一些适合现代软硬件技术的新的方案呢?

实际上Oracle GDS也不是原生态的集群计算框架,是集成了ADG、OGG、ONS、FAN、ADG FAR SYNC等技术基础上逐步发展起来的集成计算框架。不过从GDS我们也可以看出,集中式数据库完全可以从单打独斗模式过渡到了集群计算的新模式了。

实际上,集群计算模式在开源社区的发展也很迅速,MYSQL MGR就是一种典型的集群计算架构。只是目前的大多数集群计算架构大多数是以数据库与服务组件集成的方式组建的,并不是基于数据库原生态设计的,没有形成硬件、操作系统、数据库内核、服务网关的一体化设计,因此在应用上还需要大量的工程化的实施工作,运行时也还需要对整个集群进行监控和调整,无法像一个数据库一样一体化部署和一体化运行。

实际上我们完全可以从数据库底层开始一体化设计一个支持集群计算框架的集中式数据库系统,将现有集群计算的工程化工作变得十分简化,这种基于集群计算架构的集中式数据库在技术实现上会比分布式数据库简单不少,而其使用效果肯定也是相当不错的。

 
友情链接
鄂ICP备19019357号-22