白鳝
作者白鳝2022-04-13 10:37
技术总监, 南京基石数据技术有限责任公司

聊聊分布式数据库的SHARDING

字数 3340阅读 1816评论 1赞 4

最近我们团队的 D-SMART 在做蚂蚁的 OCEANBASE 的适配,因此又把 OB 的资料拿出来,重新做研究。要想让 D-SMART 纳管 OCEANBASE ,不像一些传统的监控软件那么简单,只要把一些关键指标接入进来,搞几个基线模板就可以做做简单的报警了。必须对 OB 的基本原理、配置信息、运维要点、常见故障、巡检要点等做大量的归纳总结,并找到一些实际的用户,进行大量的测试,才能完成初步的适配,随后不断积累运维经验,才能让这个工具的能力越来越强。这也是做数据库的智能运维工具的不易之处。要重新学习 OB ,所以近期我会和大家分享一些我学习 OB 的心得。

研究 OB 数据库,我们首先需要从这张 OB 架构图上开始分析。上面这张三个 ZONE 的 OB 架构图来自于 OB 的官方手册。从这张图上来看, OB 除了总控服务( Root Service )是主备模式,采用一主 N 备的模式,其他的组件都可以看成是分布式去中心化的。其 SQL 引擎、事务引擎、存储引擎是采用分区分片的方式的。每个 OBSERVER 都包含一个 SQL 引擎,一个事务引擎、一个存储引擎和一组数据分区。这种 SHARDING 架构的数据库系统十分适合高并发的小型交易,其中最为典型的就是支付宝业务。因为可以根据用户的 ID ,将大并发量的用户通过算法分散到各个对等的 OBSERVER 上去,通过扩展 OBSERVER 的数量就可以横向扩展 OB 的并发处理能力。

OB 的 ZONE 具备远程部署能力,因此 OB 原生态具有支持同城双活的能力,可以将不同的 ZONE 部署在不同的数据中心里。 OB 的数据是采用多副本的,在每个 ZONE 里存储一份,并通过 PAXOS 分布式选举算法选举 LEADER 。 OB 的数据副本粒度可以到分区级。

SHARE NOTHING 架构的分布式数据库一般被称为 MPP 数据库,集群上不共享任何数据,因此这种架构很容易横向扩展。作为 MPP 分布式数据库的设计理念,主要在高可用(采用多副本存储数据,单点故障不影响数据库)、可横向扩展(因为采用 SHARE NOTHING ,因此不存在缓冲区融合的问题,增加节点就可以增加处理能力)、使用简单(自动分库分表、自动数据路由,研发人员比较容易掌握)、运维方便等。

高可用这条毋庸置疑,比如 OB 这种架构,一份数据会在多个 ZONE 里有多个副本存储,甚至有的 ZONE 还可以位于远程或者异地,可用性方面是绝对没有问题的。不过 OB 这种靠一套数据库实现同城双活的方案,对于一般的系统来说可能够用了,不过对于一些可靠性要求十分高的系统来说,也是不够的。虽然 ZONE 可以跨数据中心,但是数据库本身也是一个单点,一旦整个数据库出问题了,那么业务也就中断了。使用可跨数据中心的分布式数据库之后,还需要不需要再搞高可用,还是只依赖于单一数据库的高可用,这一点就仁者见仁智者见智了。

可横向扩展也是没问题的,现在的网络能力下, SHARE NOTHING 集群可以很方便的扩展到数十个甚至数百个。可以构建十分庞大的数据库集群。这是 MPP 数据库的优势所在。不过对于大多数传统架构的业务系统来说,大集群的 MPP 所提供的处理能力不一定是必须的,有可能一台 2 路服务器就已经远远超出你的业务处理能力的需求了,这时候选择 MPP 数据库的目的应该就不是横向扩展了。在我遇到的很多用户的应用场景中,选择具有横向扩展能力的架构实际上是一个伪命题。

运维方便这一点目前来看要从两个方面来看,对于日常运维来说,如果不出一些特别的问题,那么 MPP 分布式数据库总体来说运维还是比较简单的,日常运维主要看看 SQL 优化就可以了,因为高可用架构屏蔽了大量的硬件单点故障带来的系统问题,因此日常运维的压力是会得到缓解的。如果出现一些大一点的问题,那么运维人员也是无能为力的, MPP 数据库的复杂性决定了,一旦出问题,很可能数据库原厂都不一定能很快搞定,因此故障处理的主力就是原厂了。从这一点上来讲,使用 MPP 数据库,运维人员的压力会比较小。

使用简单这一点,是 MPP 数据库最令客户喜欢的一点,不过这一点上往往争议也最大。实际上分布式数据库的最早雏形是互联网企业的分库分表,这方面在世纪之初我们在给运营商做优化的时候也大量的使用。把一个数据库按照业务分拆成多个,无法分拆的库做复制,进行读写分离处理,从而让已经达到纵向扩展极限的系统能够分拆负载,这个方法被称为分库。对于开发人员来说,分库还是比较容易实现的,只要开发厂家的水平不是太差,分库后的聚合计算方面的研发能力稍微好一点,分库还是比较容易实现的,因为分库是按照业务去分的,大部分的计算都会集中在库里,只有少量的计算才需要跨库的聚合计算。不过我也遇到过很极端的情况,一个数据库被分为 6 个小库后,开发人员不愿意自己程序里实现聚合计算,只能创建 OGG 复制链路,把部分分出去的数据再复制回来。这套系统上线不到半年,这种 OGG 复制链路已经有好几十条了。对于 MPP 数据库来说,分库就更为简单了, SQL 引擎可以自动实现跨库的表连接,开发人员也就不需要再去复制表数据了。

MPP 架构应用的另外一种模式是分表,当分库已经不能满足要求的时候,就需要分表了。可能大家刚开始的时候觉得分表不就是比分库分的更细一点吗,既然分库没问题,那么分表也不应有有问题了。实际上并不是这样的,分表有两种形式,一种是把一个库里的多张表分不到不同的 OBSERVER 中去,一种是把一张表分为多个片,存储到不同的 OBSERVER 中去。第一种分表对于应用开发来说还比较好办, MPP 数据库的 SQL 引擎会做聚合计算,因此对于开发来说并没有什么不同。有差异的是性能,跨多个 OBSERVER 的聚合查询的性能和单机数据库比,在很多方面都是存在差异的,这和分布式数据库的优化器和执行器的水平有很大的关系。跨库数据的聚合计算肯定会比单机有更多的延时,这些延时主要是在网络上的。不过这些都不是最主要的因素,最主要的是算子下推的操作。分布式数据库的算子下推可以利用并行执行的优势来加速,不过算子下推的粒度和能力,在不同的数据库厂商实现方面存在技术差距,这一点往往需要经过严格的对比才能看得出来。

分片是一个更复杂的问题,我们要把一张表分成多个片段分布到多个 OBSERVER 中去,那么我们必须要按照某个 SHARDING KEY 来分表。如果分表后,我们对这张表的查询语句上都带有这个 SHARDING KEY 的过滤条件,那么优化器在分解执行算子的时候,可以很方便的进行分区裁剪,从而降低执行成本。如果我们的 SQL 中不带 SHARDING KEY 过滤条件,那么这条 SQL 就会分布到所有的这张表所在的 OBSERVER 上去执行,这样可能会放大 SQL 执行的资源消耗,也会影响 SQL 的执行效率。

分库分表另外一个对性能影响较大的因素是多表关联查询方面的性能问题。比如某个表的某个分片在 OBS1 上,而关联表的分区在 OBS2 上,那么这个分布式关联操作的性能就不如二者都存放在 OBS1 上了。 OB 数据库引入了一个表组( table group )的逻辑结构。设置为同一个 table group 的多张表具有相同或者像类似的分区策略,其关联操作也比较多,这样可以确保这类业务的性能不会有太大的下降。

实际上我们还经常遇到一个问题就是一张分区的大表经常需要和一些小表进行关联,有些数据库也支持将一些小表复制到多个数据库分片中,从而提高这些关联操作的性能。

在很多分布式数据库的设计之初,数据库研发人员是希望分布式数据库能够很方便的让人使用,而实际上分布式数据库和集中式数据库在架构上的不同决定了,用好分布式数据库肯定需要有更高水平的设计,利用分布式数据库的特性,做精心的设计,尽可能避免分布式数据库中的那些坑,才能把应用做的更好。如果我们的数据库厂商总是避开这些不谈,等用户在他们的数据库上开发出了不那么令人满意的系统来,那时候再去说用户不会用分布式数据库,那就不够地道了。

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

4

添加新评论1 条评论

zhmwangzhmwangPD, OceanBase
2022-04-17 01:45
实际上我们还经常遇到一个问题就是一张分区的大表经常需要和一些小表进行关联,有些数据库也支持将一些小表复制到多个数据库分片中,从而提高这些关联操作的性能。 DB2 DPF也有类似概念,本概念OB也是支持的: create table t1(id bigint not null auto_increment , c1 varchar(50), c2 timestamp not null default current_timestamp) duplicate_scope='cluster' ; 这种方式在性能上还是有些损耗, 但相比以前的数据乱飞现象,还是提升很大的。
Ctrl+Enter 发表

本文隶属于专栏

最佳实践
不同的领域,都有先行者,实践者,用他们的最佳实践来加速更多企业的建设项目落地。

作者其他文章

相关文章

相关问题

相关资料

X社区推广