写点什么

数据库国产化应用改造实践

作者:鲸品堂
  • 2023-08-22
    江苏
  • 本文字数:3940 字

    阅读完需:约 13 分钟

数据库国产化应用改造实践

​近年来,随着国产化大潮不断推进和数据库分布式技术趋势发展,越来越多的企业开始选择国产数据库替换原有数据库。然而,核心数据库迁移又是“令人闻风丧胆”的 IT 操作,稍有不慎就有“删库跑路”的巨大破坏性。


由于国产数据库主要采用分布式架构,技术差异大,很多企业在数据库国产化应用改造过程中,常常遇到各种问题,包括但不限于架构差异大、数据不兼容、语法差异、性能等问题,导致数据库迁移工作苦不堪言。


应用改造就那些事


数据库国产化应用改造,业务层面并没有发生变化,其本质是解决数据库之间的差异性,那么国产化与传统数据库间的差异,无非就以下几个方面:

  • 架构差异:在架构规划上存在差异,因此在进行数据模型设计时需注意这些差异,尽可能保证数据存储和分布合理性。

  • 功能差异:在语法和函数上存在差异,因此在进行改造时需要注意这些差异,避免出现语法错误、功能不完整或数据不一致的问题。

  • 性能差异:在性能方面也可能存在差异,因此在进行改造时需要注意这些差异,尽可能保证迁移后的数据库系统具有高性能和稳定性。

  • 其他方面:还有其他一些方面也需要注意,比如安全性、可扩展性、可维护性等等。


我们的实践之路


面对这些差异,我们在应用改造过程中,要综合考虑,并做出相应的调整和优化,以确保改造后的系统能够满足业务需求,并具备高性能、稳定性、安全性等特点。我们结合研发管理流程,采用“3 阶段 11 步骤”解决方案,实现国产化数据库迁移应用改造。


  • 规划设计:根据所选型的数据库特性,通过调整表类型、分片键、分片算法等重新规划数据库表结构,设计出最合理的模型。

  • 编码研发:细化数据库差异点,通过接口适配、数据类型、语法兼容、函数四方面兼容性对代码进行改造,以确保业务功能无损。

  • 性能调优:结合数据库优化模型,对驱动层、网络层、代理层、节点层进行数据库和 SQL 优化,确保性能和可靠性。


分布式数据模型设计


国产数据库一般采用分布式架构,其数据模型设计流程包括以下几个步骤,比传统集中式数据库多了分片设计、分布设计以及对象优化调整。在数据库应用改造时,我们补齐这三个步骤。


数据分片设计


在分片设计前,我们先了解一下国产数据库架构,它包括计算节点、数据节点、全局事务这三层,此外,还有一个非常重要的概念是,分布式数据库是把数据分散存储在各个分片中。例如,GoldenDB 分片存储在 MySQL 实例中。国产数据库需要关注一个非常重要的设计:正确地把数据分片,充分发挥分布式数据库架构的优势。



为满足分片键选择中唯一性、均匀性、高数据关联性的关键原则,有以下三个思路:

  • 尽量选择 distinct 值比较多的列,保证数据均匀分布。分布均匀是为了避免木桶效应,各个主机对等执行。

  • 尽量选择 join 列或 group 列,避免数据节点之间数据流动,提高性能。

  • 尽量选择带入参的列,减少中间结果集回流 CN 节点(计算节点)及 CN 节点的 SQL 拆分计算。


选出分片键后,就要选择分片算法,不同分布式数据库的拆分算法都支持 LIST、RANGE、HASH、复合分片等,选择拆分算法与业务场景密切相关,大多数业务场景都能根据需要作出良好的决策,以下是几种常见的场景。

  • 如果按照时间字段拆分,最好选 RANGE 或者 LIST。

  • 针对批量场景,主要涉及范围查询和批量写入两个场景,如果对范围查询性能要求高,那可以选用 RANGE,但可能导致写入各个分片承受压力不均衡;如果对批量写入性能要求高,就使用 HASH,但范围查询肯定会扫描全部分片,性能会较慢。


数据分布设计


数据库表分布设计,主要考虑数据的冗余分配和位置的条带化分配两个方面:

  1. 冗余分配:即将一份数据映射到多个节点,也称复制表。复制表是以空间换性能的做法,设计时,通过分析表类型、行数量、访问频次、关联复杂度,可将高频访问表、配置表、关联常用驱动表等设置成复制表。

  2. 条带化分配:分布式数据库中的表,要尽量选出一个统一的分片键,即大部分表都能根据这个分片键打散数据,这样当后续业务进行访问数据时,可以在一个分片中完成单元化的闭环操作,不用涉及跨分片的访问。在设计时,应分析高频 SQL 和慢 SQL,并不断调整表的分析键,以实现数据条带化分布。



对象优化设计


分布式数据库架构对象优化主要是对索引设计调整,需要充分发挥分布式架构的线性可扩展优势,主要有 2 类索引设计调整。


主键选择:集中式数据库,很多采用自增序号作为主键,但其自增性能差、安全性不高,不适用于分布式架构。建议用全局唯一的键作为主键,比如 MySQL 自动生成的有序 UUID;业务生成的全局唯一键;或者是开源的 UUID 生成算法,比如雪花算法(但存在时间回溯问题)。


普通索引设计:索引字段经常不包含分片键,那么使用索引时需要查询所有分片,性能比较差。可以采用以下两种设计:1)将索引字段设置为分片键,创建一个索引表实现;2)在索引中额外添加分片键的信息。


代码四大兼容性改造


在调整数据模型后,接着对代码进行兼容性改造,有两个要求:广适配数据库对象,深挖掘差异改造点。首先,在广度上,应对代码中涉及的数据库接口、数据类型、语法、函数等四方面进行全面兼容性改造。


接口适配改造


JAVA 应用通常使用 JDBC 协议连接数据库,除替换驱动程序外,还需要对分布式数据库的驱动连接和高可用特性参数进行设置,以更好地利用分布式数据库优势,以下是 GoldenDB 改造过程中的常用驱动协议属性改造点。


数据类型转换


数据类型转换涉及字段类型、精度、长度、字符集之间的转换,很多成熟第三方工具或厂家工具都可实现,这里不再详述。需要注意的是字符串长度算法和字符集问题,例如 Oracle 按字节算字符串长度,MySQL(GoldenDB/OB)按字符计算;UTF8 字符集,Oracle 默认 UTF8mb3, MySQL (GoldenDB/OB) 默认 UTF8mb4。这些类型都需要进行长度转换。以下是 GoldenDB 字段类型的精度、长度、字符集支持情况。



语法兼容改造


主流分布式数据库主要选型 PG(openGauss)和 MySQL(OB、GoldenDB),因此需要对 Oracle、PG、MySQL 之间的语法兼容性做一下差异分析(分布式厂家会对兼容性差异做适配,减少差异,该部分不在讨论范围),然后研发按图索骥对不兼容项进行改造,以下为三者之间的主要区别:


函数兼容改造


与语法兼容性类似,除厂家进行兼容性改造外,Oracle、PG、MySQL 之间也需要对函数差异进行改造,常见的函数差异如下:


需要注意的是字段 NULL 值,数据库中的 NULL 值是比较特殊的存在,不同数据库可能存在一些差异,例如,GoldenDB 对 NULL 存在以下限制:

  • NULL 字段不能作为全局索引和分片键。

  • NULL 不等于任何值(包括 TRUE、FALSE 或者 NULL);不能进行关系运算(大于、小于、等于、不等于)。

  • NULL 值能做 IS NULL 或 IS NOT NULL 判断,可以用函数转换为普通值,如 NVL 、NVL2 函数。

  • 在 NOT IN 子查询里,如果子查询返回结果集包含了 NULL 值,则整个 NOT IN 条件都是返回为空。


在广度剖析代码中的差异性后,如何深度挖掘存在差异的 SQL 呢?可以采用两种回放方式来收集数据库不兼容项。

方式一: 利用 MyBatis 插件机制,编写自定义插件,在 SQL Prepare 阶段插入自定义逻辑,从而获取 SQL 语句并输出,实现应用 SQL 的录制。

方式二: 利用 Oracle 的 WCR 工具录制数据库执行 SQL,虽然该种方式可以捕获所有的 SQL,但无法标识具备应用,且需要对 SQL 进行过滤,剔除运维和 Oracle 内部事务等非应用 SQL。


​WCR 回放流程


最后,将捕捉到的 SQL 转成目标库语法,进行回放检测出不兼容项,并形成改造标准项,以供研发和测试人员按图索骥修改。


数据库分层性能优化


分析数据库优化之前,我们先看看 SQL 执行的路径,以理解可能影响 SQL 执行速度的相关因素。


大多数分布式数据库的执行路径为:应用->驱动程序->Proxy->数据节点,即从应用发起 SQL,调用驱动程序,经过 Proxy 解析拆分后到达数据节点,数据节点执行 SQL 并将结果反馈给 Proxy 聚合处理或直接返回给应用,从这个过程中,可以得到几个影响 SQL 执行速度的因素:

  • 驱动程序的连接性能。

  • 应用与 Proxy 间的网络传输。

  • Proxy 的聚合处理能力。

  • 数据节点本身的 SQL 执行效率。


驱动层优化


驱动程序作为应用与数据库之间的桥梁和连接入口,在引入驱动时,往往忽略参数优化。可以通过优化驱动参数,如数据库连接、SQL 缓存、负载均衡等,来提高 SQL 执行性能,例如,GoldenDB 驱动可通过以下参数进行性能调优:


网络层优化


应用与 Proxy 间的网络传输也是重要问题,可能导致问题包括网络本身问题、数据获取机制、数据结果集过大等,以下是我们在 GoldenDB 改造踩过的一些坑及解决方案:



代理层优化


Proxy 主要负责数据汇聚处理,对从各 DN 获取到的数据进行二次关联,这涉及到分布式特有的关联操作,即“分布式 JOIN”。


分布式 JOIN 有多种情况,主要分为两大类:


可下推的 JOIN,即 JOIN 操作由数据节点完成,Proxy 层对 JOIN 结果进行汇总,这种方式效率更高,因为存储和计算在一起,例如,同维度的 JOIN 和复制表的 JOIN。


​同维度的 JOIN


复制表的 JOIN


不可下推的 JOIN,数据节点做单表查询,Proxy 完成 JOIN 操作,这种方式涉及大量数据同步,效率较低,如 Nested Loop Join。


​Nested Loop Join


SQL 在代理层调优时,主要考虑避免 Nested Loop Join。以下是我们在项目中积累的一些优化经验:


节点层优化


数据节点实际上就是单个 MySQL 或者 PG 实例,优化手段与传统数据库差异不大,这里不再赘述。


结语


数据库国产化不仅仅是为了“国产”这个标签,更是“分布式替代集中式”的云计算发展趋势的体现。这种技术革新对业务软件的重塑,需要在数据库国产化应用重构的过程中,将分布式架构的技术、特性和原理融入到规划设计、代码研发和性能优化的各个阶段,以充分利用分布式数据库的优势。这样,新系统才能拥有传统数据库无法比拟的能力,才能为业务提供更高的性能、稳定性和敏捷支持。只有通过专业团队的支持,才能帮助客户在数据库国产化的浪潮中脱颖而出,才能在数据库迁移的过程中苦中带一点乐。


本文是国产化数据库改造实践中的一点浅见,以期为正在 “国产化数据库改造”的您提供一些参考和启示。

发布于: 刚刚阅读数: 3
用户头像

鲸品堂

关注

全球领先的数字化转型专家 2021-03-16 加入

鲸品堂专栏,一方面将浩鲸精品产品背后的领先技术,进行总结沉淀,内外传播,用产品和技术助力通信行业的发展;另一方面发表浩鲸专家观点,品读行业、品读市场、品读趋势,脑力激荡,用远见和创新推动通信行业变革。

评论

发布
暂无评论
数据库国产化应用改造实践_数据库_鲸品堂_InfoQ写作社区