【Mycat2】什么是原型库(Prototype)
文章目录
- 前言
- 正文
- Mycat2 原型库
- 分库分表
- 评价
前言
因目前 Mycat2 官方的资料质量太差了,晦涩难懂,让人看了云里雾里,不知所谓,笔者也是摸索、实验了一段时间才形成了一定的“理解”。注意,本文仅是个人理解,可能出错,欢迎探讨指正。
正文
Mycat2 原型库
Mycat2 中的原型库(Prototype) 既是一个元数据库(Metadata Store),又是一个当 Mycat2 的 SQL 解析器无法解析下发到物理库时默认在其中执行 SQL 的数据库,比如诸如 CREATE DATABASE
的 DDL 语句。
当前版本的 Mycat2 显然做得不够好,只能处理简单的 DML 操作,无法跟上 MySQL 8.0 的版本更新,无法使用新语法和功能特性,且在跨库分布式事务处理方面表现不好,甚至不支持某些操作。这些也是数据库分库分表和分布式中间件的通病。笔者认为使用 MySQL 原生的分布式数据库集群解决方案 InnoDB Cluster 优于使用数据库中间件,但同样也有一些限制,具体还要结合业务具体分析,并经过充分的基准测试和性能测试,选择最适合的高可用、高性能、弹性伸缩集群解决方案。
此外,Mycat2 在作为逻辑表的元数据库同时,还作为执行不支持 SQL 的默认执行库,并没有选择报错拒绝这些 SQL 操作。这与一些其他的 MySQL 数据库中间件不同,可能出于不同的考虑,各有优劣。
Mycat 本质上是一个 MySQL 数据库中间件,其主要功能是以一定的规则将物理对象(表/库/视图等)抽象整合为逻辑模型。
**测试证明过程详见 3.6 测试 。
分库分表
Mycat 主要用于数据库分片(Sharding),即分库分表。
可以使用 Mycat 将多个物理库整合成一个逻辑库,或者反过来说,把一个逻辑库拆分为多个物理库,即分库。
同样,可以使用 Mycat 将多个物理表整合成一个逻辑表,或者反过来说,把一个逻辑表拆分为多个物理表,即分表。
分库、分表又按切分方向(水平、垂直)分为水平分库、垂直分库,水平分表、垂直分表。
关于分表,可以想象切割(拆分)一块围棋棋盘,横向表示列(或字段),纵向表示数据(记录)行。
- 横向切割一次,将一个表拆分为两个字段与原表相同的表,即表结构相同,缩小了每张表的长度。这有点类似分区表的概念,只不过分区表因是单库操作,所以所有表分区都位于在同一个库中;而水平分表的子表可以分布在不同数据库中。在 MySQL InnoDB 存储引擎中单库分表(
innodb_file_per_table=1
)几乎等同于分区(Partitioning),分区为一种数据库内的分表实现,水平分表往往依赖数据库自带的分表组件/插件/应用程序,或第三方中间件实现。在其他 RDBMS 实现中会有些差异,比如 Oracle Database 分区表涉及全局索引和本地索引。实际场景中可切割多次。 - 纵向切割一次,将一张表拆分为两个分别包含原表部分列的表,缩小了每张表的宽度。这有点类似与范式化,只不过垂直分表后的子表未必满足范式的要求。另外,范式化一般也是在单库范围讨论,而垂直分表后的子表可以分布在不同的数据库中。实际场景中可切割多次。
分库同理,只是操作对象换成了“库(或方案)”
- 水平分库,全称应为水平分库分表,即多库分表,因为水平分库不可避免的要进行水平分表。对一个库中所有表进行分库分表,复制库的逻辑结构到多个库,使每个库都包含相同数量、名称、表结构的表,但各库中的表的表数据不同。
- 垂直分库,即将原本位于一个库内的表拆分到多个库中,一般是按业务逻辑拆分。比如,将一个电商库拆分为用户库,商品库,店铺库等。
评价
笔者认为 Mycat2 的原型库设计有问题,只需要设计为元数据库即可。而开发者还试图将其作为处理数据库管理语句、DDL 语句等 SQL 语句的默认数据库。所有 MySQL 分库分表中间件的最终目的都是构建一个完整的 SQL 解析器,既要解析中间件自定义的语法,又要解析 MySQL 不断更新的所有语法,无疑会带来很高的实现复杂度。Mycat2 则选择了一种折中的办法,将无法解析处理的 SQL 在原型库上执行,以提高业务连续性,但他们没有考虑到用户很少使用、甚至不要该功能。在底层为复制拓扑,Mycat2 原型库为复制拓扑的 (复制)源(Source/Master) 时,还算有点用处。
首先,使用数据库中间件是需要一定的学习成本的,尤其是涉及到复杂的分库分表规则时。
其次使用 Mycat 中间件的用户,主要需求就是分库分表、分布式事务,对于 DDL、数据库管理语句等,基本不会在 Mycat 上操作。
最后,当前的原型库设计即便运行了DDL、数据库管理语句这些无法解析的语句,但却违背了用户本意,实属无用功,用户还要去处理 Mycat 因误解而带来的后果,比如删除在原型库中创建的数据库。