最近我们团队的D-SMART在做OCEANBASE对蚂蚁的适配,所以把OB的数据拿出来重新研究。让D-SMART管理OCEANBASE并不像一些传统的监控软件那么简单,只要接入一些关键指标,使用几个基线模板就可以做简单的报警。需要对OB的基本原理、配置信息、运维要点、常见故障、检查点等进行大量总结,并找一些实际用户进行大量测试,完成初步适配,然后不断积累操作,才能让这个工具的能力越来越强。这也是做数据库智能运维工具的难点。又要学OB了,近期给大家分享一下我学OB的一些心得。研究OB数据库,首先要从这张OB架构图开始分析。以上三个ZONE的OB架构图均来自OB官方手册。从这张图上看,除了主控服务(RootService),OB采用master-n-standby的模式,其他组件都可以看做是分布式和去中心化的。其SQL引擎、事务引擎、存储引擎采用分区和分片。每个OBSERVER包含一个SQL引擎、一个事务引擎、一个存储引擎和一组数据分区。这种基于SHARDING的数据库系统非常适合高并发的小额交易,最典型的就是支付宝业务。因为可以根据用户ID通过算法将大量的并发用户分布到各个对端的OBSERVER上,通过扩展OBSERVER的数量来横向扩展OB的并发处理能力。OB的ZONE具备异地部署能力,因此OB的原生态具备支持同城双活的能力,不同的ZONE可以部署在不同的数据中心。OB的数据采用多副本,每个ZONE存储一份,通过PAXOS分布式选举算法选举出LEADER。OB的数据拷贝粒度可以达到分区级别。SHARENOTHING架构的分布式数据库一般称为MPP数据库,集群上不共享任何数据,因此该架构易于横向扩展。作为MPP分布式数据库的设计理念,主要体现在高可用(采用多副本存储数据,单点故障不影响数据库),以及水平扩展(因为使用了SHARENOTHING,所以不存在SHARENOTHING的问题bufferfusion,增加节点可以增加处理能力),易用(自动分库分表,数据自动路由,研发人员更容易掌握),方便运维等。高可用性是毋庸置疑的。例如,在OB架构中,一份数据会被存储在多个zone中的多个副本中,有些zone甚至可以位于远程或异地。在可用性方面绝对没有问题。但是,OB依靠一套数据库实现同城双活的方案,对于一般的系统来说可能是可以用的,但是对于一些可靠性要求非常高的系统就不够用了。虽然ZONE可以跨数据中心,但数据库本身也是一个单点。一旦整个数据库出现故障,业务就会中断。使用了可以跨数据中心的分布式数据库后,是要高可用还是只依赖单一数据库的高可用,就由仁者见仁智者见智了。水平扩展没有问题。在目前的网络能力下,SHARENOTHING集群可以轻松扩展到几十个甚至上百个。可以构建一个非常大的数据库集群。这就是MPP数据库的优势。但是,对于大多数传统架构的业务系统来说,大型集群的MPP所提供的处理能力并不是必须的。有可能2路服务器已经远远超出了您的业务处理能力需求。这时候选择MPP数据库的目的应该不是横向扩展。在我遇到的很多用户的应用场景中,选择具有水平可扩展性的架构其实是一个伪命题。目前运维的便利性应该从两个方面来看。对于日常运维来说,如果没有特别的问题,MPP分布式数据库的运维总体来说还是比较简单的。日常运维主要看SQL优化,因为高可用架构屏蔽了大量硬件单点故障导致的系统问题,日常运维的压力会得到缓解。如果出现一些比较大的问题,那运维人员就无能为力了。MPP数据库的复杂性决定了一旦出现问题,很可能原数据库厂商无法快速修复,所以排查问题的主力还是原厂商。.从这点来看,使用MPP数据库,对运维人员的压力会比较小。易用性是客户最喜欢MPP数据库的一点,但这一点往往也是争议最大的。其实分布式数据库最早的雏形就是互联网公司的分库分表,我们在世纪初给运营商做优化的时候也用的很多。将一个数据库按业务划分成多个数据库,将未划分的数据库复制,并进行读写分离处理,使已经达到垂直扩展极限的系统分担负载。这种方法称为数据库划分。对于开发者来说,分库实现起来还是比较容易的。只要开发厂商的水平不是太差,分库之后在聚合计算方面的研发能力稍微好一点,分库还是比较容易实现的,因为分库是基于业务划分,大部分计算会集中在库中,只有少量计算需要跨库聚合计算。但是,我也遇到过很极端的情况。一个数据库分成6个小库后,开发者不愿意在自己的程序中实现聚合计算。他们只能创建OGG复制链接,将部分被分割的数据复制回来。.这个系统上线不到半年,这样的OGG复制链接已经有几十个了。对于MPP数据库,子数据库就更简单了。SQL引擎可自动实现跨库表连接,开发者不再需要复制表数据。MPP架构应用的另一种模式是分表。当分库不能满足要求时,就需要分表。可能一开始大家认为分表比分库更详细。既然分库没有问题,那么分表应该也没有问题。事实上,情况并非如此。分表有两种形式。一种是将一个库中的多张表分到不同的OBSERVER中,另一种是将一张表分成多块存储在OBSERVER中不同的Go中。第一种分表方式对于应用程序开发来说比较容易。MPP数据库的SQL引擎可以进行聚合计算,所以开发上没什么区别。区别在于性能。跨多个OBSERVER的聚合查询的性能在很多方面都不同于单机数据库,这与分布式数据库的优化器和执行器的水平有很大关系。跨库数据的聚合计算肯定会比单机有更多的延迟,而这些延迟主要是在网络上。然而,这些都不是最重要的因素。最重要的是操作员下推操作。利用并行执行可以加速分布式数据库的算子下推。但不同数据库厂商在算子下推的粒度和能力上的实现存在技术差距。这只能通过严格的比较才能看出。.碎片化是一个更复杂的问题。如果我们要把一张表分成多个分片,分发给多个Observer,那么就必须按照一定的SHARDINGKEY来分表。如果分表后,针对这张表的查询语句有这个SHARDINGKEY过滤条件,那么优化器在分解执行算子的时候就可以方便的进行分区剪枝,从而降低执行成本。如果我们的SQL中没有SHARDINGKEY过滤条件,那么这条SQL会分发给这张表所在的所有OBSERVER去执行,这样可能会放大SQL执行的资源消耗,影响SQL执行的效率。另外一个对分库分表性能影响比较大的因素就是多表关联查询的性能问题。比如一个表的某个分片在OBS1上,关联表的一个partition在OBS2上,那么分布式关联操作的性能不如都在OBS1上。OB数据库引入了表组的逻辑结构。设置为同一个表组的多个表具有相同或相似的分区策略,关联操作较多,可以保证该类业务的性能不会大幅下降。事实上,我们经常会遇到一个问题,一个分区的大表往往需要关联一些小表,而一些数据库也支持将一些小表复制到多个数据库分片,从而提高这些关联操作的性能。很多分布式数据库在设计之初,数据库开发者都希望分布式数据库能够方便人们使用。事实上,分布式数据库和集中式数据库在架构上的差异决定了用好分布式数据库是一定的。需要更高层次的设计,利用分布式数据库的特点,精心设计,尽可能避免分布式数据库中的那些陷阱,才能让应用变得更好。如果我们的数据库厂商总是回避这些事情,坐等用户在自己的数据库上开发出不满意的系统,那么说用户不会使用分布式数据库就不够地道了。.
