ITPub博客

首页 > 数据库 > 国内数据库 > 阿里分布式数据库服务相关介绍

阿里分布式数据库服务相关介绍

原创 国内数据库 作者:tianxia 时间:2022-12-16 16:16:24 0 删除 编辑

TDDL 研发淘宝的历史和背景

淘宝 DRDS/TDDL 是阿里巴巴自主开发的 阿里分布式数据库 服务。 DRDS 脱胎于阿里巴巴开源的 Cobar 分布式数据库引擎,吸收了 Cobar 核心的 Cobar-Proxy 源代码,实现了一套类似于 MySQL-Proxy 协议的独立解析端,可以解析和处理传入的 SQL ,为应用屏蔽各种复杂的底层 DB 拓扑,获得与单机数据库相同的体验。同时,借鉴淘宝 TDDL 丰富的阿里分布式数据库实践经验,实现了对分布式 Join 、 SUM 、 MAX 、 COUNT 、 AVG 等聚合函数和排序函数的支持,通过异构索引和小表广播解决了分布式数据库使用场景中出现的一系列问题,最终形成了完整的分布式数据库方案。

 

使用场景

分布式数据库的核心需求是解决单机数据库的瓶颈。阿里分布式数据库在使用过程中必然会遇到数据库容量、连接数、事务数、读取性能的瓶颈。这些瓶颈的两种常见解决方案是单机垂直纵向扩展模型和水平横向扩展模型。

 

扩展模式与硬件资源绑定性强,一般采用升级单机硬件能力的方式来扩展数据库服务能力。比如 MySQL 本来是做单机数据库的,遇到访问瓶颈就把磁盘换掉了。当访问量更高的时候,就需要考虑使用 Oracle 的商用解决方案,高端存储设备,高端小型机,也就是 IOE 架构,甚至升级 IOE 设备来换取更高的扩展和服务能力。在这个过程中,会存在设备升级和数据迁移的成本。

 

多机横向扩展模式使用大量廉价的 PC-Server 通过数组实现数据库的横向扩展。优势在于成本更低,因为不需要淘汰老旧的设备和系统,不需要频繁迁移数据。必要时,只需扩大服务集群的规模。

 

使用分布式多机模式也需要一定的成本。分布式数据库架构的逻辑和物理分布与单机数据库有很大的区别。所以需要将单机数据库的数据迁移到分布式架构模型,也就是分片的数据切片过程。这个过程包括数据的分布式逻辑设计、数据库迁移以及 SQL 优化和转换。当然,这种迁移是一次性的。架构迁移完成后,不需要关心数据库扩展和数据迁移,因为分布式数据库的服务层已经集成了扩展功能,架构支持水平扩容。

 

2006 年以前,我们的核心应用普遍采用 Oracle 数据库,但随着业务的快速发展,淘宝的数据量和访问量急剧增加,数据库存在严重的访问性能问题,导致数据库频繁宕机,业务停滞。即使当时已经使用了 Oracle 亚洲最大的 RAC 集群,单机数据库的扩展能力也达到了极限,需要付出巨大的资金和运维成本。所以基于自己的实际情况,我们逐渐开始去 IOE 研发分布式关系数据库服务,实现数据库的高扩展性和成本可控。目前, DRDS 已经成为我们内部分布式数据库的标准,对外服务于金融、制造、政府机构、电子商务、社会等行业。

 

DRDS 的整体建筑

DRDS/TDDL 是一种典型的水平扩展分布式数据库模型,不同于传统的独立数据库共享任何东西的体系结构。 DRDS/TDDL 采用 SHARE NOYTHING 架构, SHARE NOYTHING 架构的核心思想是利用普通服务器将单机数据拆分成底层多个数据库实例,通过统一的代理集群进行 SQL 解析优化、路由和结果聚合,从而对外公开简单唯一的数据库链接。整体架构如图 1 所示,包括 DRDS 服务模块、 DRDS 控制模块、配置中心、监控运维、数据库服务集群和域名服务模块。

 

 

分布式集群管理模块用于控制集群节点。在数据安全性和服务可用性方面,通过高效的数据同步系统,实现数据库的扩展和数据库实例的主备数据同步。同时,依靠实例监控模块和 HA 模块实现主备监控和自动容灾切换。作为成熟的分布式数据库产品, TDDL 还拥有完善的运维控制体系,可以实现分布式数据库多个实例间的配置管理和变更,以及数据同步、扩展等任务管理,降低运维成本。

 

DRDS/TDDL 的功能特征

数据碎片

DRDS 的基本原理是分片,即数据分片。将单机数据库的数据拆分成多个单机数据库,对外保持逻辑一致性。拆分的后端数据库是一个子数据库,对应的表称为子表。每个子数据库负责读写一份数据,分散了整体的访问压力。当系统容量扩大时,只有通过横向增加子数据库数量和迁移相关数据,才能提高 DRDS 系统的整体容量。

 

 

对于数据分片,需要选择一个分片纬度,这是数据分布的基础。例如,对于一个用户订单信息表,如果按照订单 ID 拆分数据,那么相同订单 ID 的数据会被拆分到同一个阿里分布式数据库 storage 节点;如果根据用户 ID 分割数据,同一用户的订单将被分发到同一数据库存储实例的存储节点。

 

拆分纬度的选择很重要。一般来说,拆分键要根据实际的业务场景来选择。总的指导原则是尽可能保证每个数据库节点的数据量和负载更加均衡。单个 SQL 操作尽量在单个数据库节点执行,不同 SQL 的查询在不同的阿里分布式数据库节点执行。这样可以减少多个节点之间的网络传输,保持分布式查询的效率,平衡负载,方便扩展。

 

平滑扩展

数据库扩展是数据库操作和维护中的一种常见操作。当数据库的数据存储容量不足时,传统的单机数据库需要增加单机的存储空间来支持更多的数据写入。但是随着数据的膨胀,对于同一个 SQL 查询语句,基础数据的增加必然会降低查询效率。同时,随着数据量的增加,数据库的访问压力通常会翻倍,导致单机数据库的连接数达到极限。这时单机数据库需要升级硬件规格,使用磁盘阵列,使用高端存储介质设备和更高端的小型机服务器来承担数据量和访问的增加。这个过程将伴随着大量的数据迁移。为了保证数据的一致性,通常需要停止数据迁移,这对业务影响很大。

 

 

DRDS 的分布式架构采用平滑扩展来解决上述问题,通过增加更多的底层数据库实例来完成整体的集群扩展。

 

平滑扩展的前提是用户需要根据上述子数据库和子表逻辑将逻辑数据库拆分成多个物理子数据库,不同的子数据库落在不同的底层物理数据库机上。子数据库和子表的数量通常建议用户预估未来 3-5 年数据量的增长情况,并根据这个数据量计算整体数据应该分成多少个子数据库,因为单个子数据库的数据量通常有一个建议值,这会导致单个节点的性能下降。有了特定数量的子数据库,可以根据子数据库的逻辑将数据分割到不同的存储实例节点。当承载子数据库的物理数据库机出现容量和连接数不足等瓶颈时,可以增加新的物理数据库节点,将原有的子数据库迁移到新的物理数据库节点上,实现整体逻辑数据库的扩展。

 

扩展过程实际上就是物理数据迁移的过程。引擎层先在物理节点上根据子数据库迁移后的逻辑建立一个新的子数据库,然后预留一个时间点进行全量数据的迁移。完整迁移完成后,将根据之前保留的时间点开始增量数据捕获。当增量数据赶上两边数据几乎相同时,数据库瞬间停止写入,最后一个数据被捆绑。引擎层切换数据库划分逻辑的路由。路由规则切换后,核心扩展逻辑完成,整个切换过程在毫秒级完成。

 

为了保证数据本身的安全性,方便卷扩展和回滚,路由规范切换后,迁移前后的逻辑子库数据会实时同步,只有业务确认后才能清理原有的子库数据。

 

整个扩展过程上层的业务接入几乎察觉不到,是完全平滑的扩展。但还是要尽量注意阿里分布式数据库中扩展的操作,尤其是写低期,避免切换时数据追赶时间过长。

 

分布式 MySQL 执行引擎

分布式数据库的数据有规律地存储在多个底层存储实例中,数据物理存储的改变会造成与原生数据库引擎的不兼容。单机数据库的所有数据读写和计算都在单台物理机上进行,数据状态维护在单机上,主要性能消耗在于磁盘的数据读取。在分布式架构下,数据和状态需要在多个数据库实例之间、底层实例和代理之间传输,会造成网络 I/O 消耗,网络 I/O 造成的性能消耗远大于本地磁盘 I/O 和本地计算。

 

因此,分布式 SQL 引擎的主要目标是实现与单机数据库 SQL 引擎的完全兼容,实现 SQL 的智能下推。它可以智能分析 SQL ,分析哪些 SQL 可以直接发出,哪些 SQL 需要优化转换,优化成什么,路由到哪些实例节点执行,充分发挥阿里分布式数据库 instance 的全部能力,减少网络间的数据传输,最终将不同实例处理的少量结果数据汇总返回给应用调用者。这就是分布式 SQL 引擎的智能下推功能。

 

分布式引擎的职责包括四个过程 :SQL 解析、优化、执行和合并。

 

智能的核心原则如下 :

 

减少网络传输;

减少计算量,把计算尽量下推到更低的数据节点,让计算在数据所在的机器上执行;

充分发挥底层存储的全部容量。

基于上述原则的 SQL 引擎可以实现服务能力的线性扩展。比如一个简单的 AVG 操作,对于一些比较初级的分布式数据库模型,通常的做法是将 AVG 直接发送到所有的存储节点,这样就造成了语法兼容,语义不兼容,最后导致错误结果。 DRDS 的智能下推引擎对 SQL 的语法进行了充分的语义兼容适配。对于 AVG 操作,引擎只能将逻辑 AVG SQL 解析优化为 SUM 和 COUNT SQL ,然后下推。底层阿里分布式数据库 instance 节点完成求和计数计算,充分利用底层节点的计算能力,聚合计算引擎层各存储节点的求和计数结果,最终计算 AVG 。这只是一个典型案例。在分布式数据库模型下,多个数据表的连接操作、合并和排序的兼容性非常复杂。这里,我们将分析 TDDL/DRDS 如何解决分布式场景下的具体问题。

 

弹性膨胀

TDDL/DRDS 采用服务和存储分离的架构。 DRDS 实例服务层以集群方式部署,一个服务实例由多个服务节点组成,通过负载均衡和域名服务对外提供服务。多个服务节点是无状态和同步的,平均负载处理用户请求。当集群的业务处理能力不足时,可以随时扩展服务节点,增加业务处理能力。同样,在业务不景气时可以适当缩减集群的规模,从而实现灵活的服务能力扩展。

 

对于一些数据量较大的 OLAP 场景,当单个服务器节点的内存资源较高时,可以通过升级其规格来纵向扩展单个服务器节点的能力。

 

 

分布式连接和小表广播

分布式场景中的 Join 操作不同于单台机器中的操作。单机数据的 Jion 操作发生在单机上,没有内部网络数据传输。

 

在分布式架构下,对于多个数据表 Join ,如果参与 Join 的多个表的数据拆分纬度不同,那么数据会按照不同的拆分纬度分散到不同的数据库实例上。 Join 操作可能产生跨多个物理子数据库的 Join ,需要多个底层实例进行大量数据传输, SQL 的执行效率无法保证。因此,参与连接操作的数据表应尽可能保持拆分纬度一致,使连接操作尽可能发生在单台机器上,减少跨数据库连接。如果不能维持拆分纬度的统一性,并且存在跨库 Join 操作,那么原则就是尽量减少 Join 操作的输出传输。

 

 

DRDS 常用的连接算法是基于嵌套循环的。对于 Join 的左表和右表,首先从 Join 的左表 ( 驱动表 ) 中取出数据,然后将取出的数据中的 Join 列的值放入右表并进行 in 查询,从而完成 Join 过程。因此,左连接表中的数据越少, DRDS 查询右连接表的次数就越少。如果右表中的数据也很小或者建立了索引,那么 Join 的速度会更快。因此,在 DRDS 中,连接驱动表的选择对于连接的优化非常重要。

 

但在实际的数据库场景中,往往会有一些数据量小、更新频率低的源信息表,不需要拆分。类似于这些源信息表,一个逻辑表的数据存储在一个子数据库中,通常是 “ 0 ”数据库,这些表被定义为“小表”,而其他业务数据量大、更新频率高的表仍然采用子数据库、子表的拆分方式。当这些“小表”与子数据库、子表进行连接时,基于嵌套循环算法的原理,小表作为连接的驱动表,会大大减少右表的 in 查询次数。同时, DRDS 提供的小表广播功能,可以通过实时数据复制,将“小表”的所有数据和增量变化实时复制到子数据库中,将跨数据库的 join 转化为单机 Join 操作,从而减少多个底层实例中服务器节点和数据的计算。

 

异质指数

异构索引是 DRDS 提高分布式查询效率的解决方案之一,可以解决分布式场景下数据拆分纬度和使用纬度进行数据查询不一致导致的效率低下问题。

 

 

当数据表拆分成多个子数据库和子表时,数据在子数据库和子表中的分布规则是固定的。然而,数据的业务使用场景通常非常复杂。如果数据的查询纬度符合数据拆分和分布的规则,则在一个子数据库和子表中执行一条 SQL 。如果数据查询的纬度与数据拆分分布的规范不一致,很可能会在多个子数据库、子表上执行一条 SQL ,跨数据库查询会增加网络 I/O 的成本,查询效率必然下降。

 

解决这个问题的思路是分布式数据库的一贯原则,让 SQL 的执行可以在单个数据库上完成。实际的做法是使用“空间换效率”的方案,即冗余存储同一个数据表的多个副本,根据不同的业务使用场景进行拆分,使拆分纬度和使用纬度保持一致,同时可以在多个数据之间进行实时数据复制,解决数据一致性问题。这就是“异构索引”方案。当然,异构索引表不能被无限滥用。过多的异构索引表会影响同步效率,并对源数据表造成同步压力。

 

最优方法

分布式 SQL 优化

SQL 优化是数据库使用和运维的日常操作。阿里分布式数据库 SQL 优化不仅要考虑磁盘 I/O 开销,还要注意网络 I/O 开销。为了优化 SQL 执行,其核心优化思想是减少网络 I/O ,为此, DRDS 会尽力将原 DRDS 层的工作分配到子库 ( 如 RDS 等 ) 中。 ) 在最下面。这样,原本需要经过网络的 I/O 开销就可以转化为单机的磁盘 I/O 开销,从而提高查询执行效率。所以,如果我们在使用 DRDS 的时候遇到慢 SQL ,就需要根据 DRDS 的特点适当重写 SQL 。

 

首先,条件查询优化,根据 split key 对 DRDS 的数据进行水平拆分。如果在查询中使用 split key ,对于减少 SQL 在 DRDS 中的执行时间具有重要意义。只要查询尽可能具有子数据库关键字, DRDS 就可以根据子数据库关键字的值将查询直接路由到特定的子数据库,这有助于避免 DRDS 扫描整个数据库。数据库关键字的条件精度越高,查询速度就越快。只有这样的优化才能充分发挥分布式架构查询的优势,便于后续查询能力的扩展。

 

其次,针对连接的优化,选择条件查询数据量小的连接表作为左表 ( 驱动表 ) ,减少右表的 in 查询次数。在涉及“广播表”的数据量少、变化小的 Jion 操作中,使用“广播表”作为驱动表。

 

对于 LIMIT OFFSET 和 COUNT 语句, DRDS 的实际 SQL 执行是依次读出 OFFSET 前记录的数据并丢弃,只留下 OFFSET 后的数据,这样当 OFFSET 很大时,读取数据记录的数量很少,效率也很低,因为需要大量的磁盘 I/O 读取操作来读取 OFFSET 前的数据。优化方法是将 SQL 优化为两步 : 键的偏移读取和 in 操作。首先读取偏移后的记录键,将这些键缓存在内存中,然后通过 in 查询获得完整的记录信息。这将大大减少磁盘 I/O ,明显提高效率。

 

分布式事务优化

分布式数据库事务和 SQL 查询优化的逻辑是相同的原理。尝试在单个数据库中执行事务。只有在单个数据库中执行事务,才能在保持事务的 ACID 特性的同时,线性扩展事务能力。这种单库交易通常被称为“强交易”。

 

在实践中,业务经常面临分布式数据库架构,数据库事务将不可避免地跨数据库执行。跨数据库事务必须涉及一个事务的多个分支中事务分支的执行和状态同步。与单机事务相比,分布式跨数据库事务的吞吐量和延迟会大大增加。一个事务涉及的存储库越多,事务边界就越大,事务延迟就越高,性能就呈线性衰减。

 

当遇到跨库事务时,通常的实践优化方法是通过 “最终一致性”事务来保证事务执行的吞吐量。“最终一致性”事务的原理是优先执行核心事务分支的前向执行,然后保存事务的中间状态,其他事务分支异步执行。执行完成后,达到最终的事务一致性,避免了跨数据库事务时序执行的阻塞,提高了事务吞吐量。如图 8 所示,事务 3 和事务 5 是跨数据库事务。事务分支先在左数据库中执行,异步事务分支在右数据库中执行,分别在各自的子数据库中执行,最终实现事务一致性。

 

单机数据库迁移到 DRDS 的过程

单机数据库迁移到分布式数据库是为了保证业务的正常运行,平稳过渡,减少运维。整个迁移分为三个步骤。

 

第一步,保持对原数据库的读写,数据通过复制机制写入分布式数据库,前提是分布式目标数据库表已经建立;

 

第二步,验证云上的数据是否正确,切一部分读取流程到目标分布式数据库进行读取在线压力验证 ( 测试环境也可以提前验证 ) ;

 

第三步 : 口述业务几分钟,将读写流量切换到目标数据库,将数据反向复制到源单机数据库,保证随时可以切换回单机数据库,同时也可以做云下的数据备份。

 

 

未来的发展

在分布式数据库上读取在线压力验证 ( 测试环境也可以提前验证 ) ;

 

第三步 : 口述业务几分钟,将读写流量切换到目标数据库,将数据反向复制到源单机数据库,保证随时可以切换回单机数据库,同时也可以做云下的数据备份。

 

 

未来的发展

DRDS 作为分布式数据系统中数据库服务的中间层,未来将适应更多的底层存储引擎。在充分利用底层存储节点计算能力的同时,优化自身服务的计算能力,解决 OLAP 场景,成为一个完整的分布式数据库服务体系,能够完全覆盖 OLTP 、 OLAP 等数据库服务场景。同时完整的分布式数据库逻辑层的运维支持和分布式强一致事务的支持是完整的。



来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70025223/viewspace-2928418/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2022-12-15

  • 博文量
    3
  • 访问量
    1620