一、MyCat
官方网站,技术文档
MyCat是一款由阿里Cobar演变而来的用于支持数据库读写分离、分片的数据库中间件。它基于MySQL协议,实现了MySQL的协议和能力,并作为代理层位于应用和数据库之间,可以隐藏底层数据库的复杂性。
原理
MyCat需要独立部署,1.6版本已经支持集群模式,通过Zookeeper保障mycat各节点间的高可用性,另外Mycat还提供了后台Mycat-eye,提供对sql执行线程,mycat各节点线程,jvm,网络,磁盘的监控。
MyCat的核心原理是“拦截”和“分片”,它拦截用户发送过来的SQL语句,并根据预设的分片规则(如哈希算法、取模算法等)将SQL语句分发到不同的数据节点去执行。
优势
- 支持多种数据库,支持MySQL、Oracle、SQLServer、PostgreSQL等关系型数据库,还支持MongoDB等非关系型数据库。
- 社区活跃,丰富的文档和教程,易于上手使用。
- 相对成熟,2013年发展至今历经10多年,有不少生产应用案例。
劣势
- 资源开销:Mycat是独立部署在应用,数据库中间的代理。拦截解析sql请求,转发到各分库,聚合结果返回。需要部署额外的机器资源。
- 性能损耗:应用和数据库中间多了一层网络转发,性能有一定损耗。官方性能损失测试报告显示1.2.3插入性能的损失率为6%-12%左右,查询性能损失率约为17%左右,更新性能损失率约为18%-25%左右。
- 配置复杂:MyCat的配置涉及多个文件(如server.xml、schema.xml、rule.xml等),需要精细配置以满足业务需求,官方文档。
- 开源生态集成支持较弱:例如和mysql各种高可用架构的集成,和大数据flink框架等的集成支持较弱。需要自己摸索集成方案。
二、ShardingSphereJDBC
官方文档
ShardingSphere是一套开源的分布式数据库中间件解决方案,由Apache发起和捐赠,并进入Apache顶级项目孵化器。ShardingSphere包含3个组件Sharding-JDBC、Sharding-Proxy、Sharding-Sidecar(Sharding-Mesh)。
Sharding-JDBC
- Sharding-JDBC是一个轻量级Java数据库访问层,它类似于JDBC驱动,嵌入到应用程序中。
- 通过拓展原生的JDBC API,Sharding-JDBC实现了对分库分表、读写分离、分布式事务等功能的支持。
- 它是一个去中心化的架构,没有中间代理集中统一管理连接数据库的连接资源。
- 适用于需要分库分表但不想改变现有数据库访问层代码的Java应用程序,在单体应用、微服务架构中都可以使用。
Sharding-Proxy
- Sharding-Proxy是ShardingSphere的一个独立的代理层,它类似于Mycat,可以作为一个独立的服务部署。
- Sharding-Proxy代理SQL请求,将其路由到正确的数据库实例和表中,支持多种语言的应用程序,如Java、Python、PHP等。
- 它提供了数据库二进制协议的服务端版本,用于对异构语言的支持。
Sharding-Sidecar(Sharding-Mesh)Sharding-Sidecar(也称为Sharding-Mesh)是ShardingSphere计划中的一个组件,旨在与容器化和微服务架构紧密集成。
重点讲Sharding-JDBC。
原理
Sharding-JDBC与Mycat不同,它是一个轻量级Java数据库访问层,它类似于JDBC驱动,嵌入到应用程序中。
集群模式下需要单独部署一个配置中心Sharding-JDBC-Orchestration。它提供了配置集中化与动态化、数据治理等核心功能,使得数据库的分片、读写分离等配置可以更加灵活和动态。
配置中心可以配置数据源,分库策略,分表策略,主键生成算法,SQL是否包含分库分表列审计功能,是否支持Hint路由到指定分表,广播表等丰富功能配置。具体YAML配置示例:
#数据源配置,配置了两个数据源ds_0,ds_1
dataSources:ds_0:dataSourceClassName: com.zaxxer.hikari.HikariDataSourcedriverClassName: com.mysql.jdbc.DriverjdbcUrl: jdbc:mysql://localhost:3306/demo_ds_0?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8username: rootpassword:ds_1:dataSourceClassName: com.zaxxer.hikari.HikariDataSourcedriverClassName: com.mysql.jdbc.DriverjdbcUrl: jdbc:mysql://localhost:3306/demo_ds_1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8username: rootpassword:#分库分表策略配置
rules:
- !SHARDINGtables:t_order: actualDataNodes: ds_${0..1}.t_order_${0..1} #t_order分两个库ds_0,ds_1,每个库分2张表t_order_0,t_order_1tableStrategy: standard:shardingColumn: order_id #t_order表依据order_id列分表shardingAlgorithmName: t_order_inline #t_order_inline是分表算法keyGenerateStrategy: #t_order表主键列,以及主键生成算法column: order_idkeyGeneratorName: snowflake #采用雪花算法生成主键auditStrategy: #审计策略配置,拦截并审核SQL语句,SQL必须包含分片列order_id,审计不通过报错auditorNames:- sharding_key_required_auditorallowHintDisable: true#控制是否禁用Hint分片路由的提示功能,启用则可以在应用线程中指定分片策略t_order_item:actualDataNodes: ds_${0..1}.t_order_item_${0..1}tableStrategy:standard:shardingColumn: order_idshardingAlgorithmName: t_order_item_inlinekeyGenerateStrategy:column: order_item_idkeyGeneratorName: snowflakedefaultShardingColumn: order_idbindingTables:- t_order,t_order_itemdefaultDatabaseStrategy: #默认兜底数据库分库策略,依据user_id分库standard:shardingColumn: user_idshardingAlgorithmName: database_inlinedefaultTableStrategy:none:shardingAlgorithms:database_inline:type: INLINEprops:algorithm-expression: ds_${user_id % 2}t_order_inline:type: INLINEprops:algorithm-expression: t_order_${order_id % 2}t_order_item_inline:type: INLINEprops:algorithm-expression: t_order_item_${order_id % 2}keyGenerators:snowflake:type: SNOWFLAKEauditors:sharding_key_required_auditor:type: DML_SHARDING_CONDITIONS#DML_SHARDING_CONDITIONS算法要求在执行逻辑表查询时,必须带上分片键。#如果SQL语句中缺少分片键或分片键不正确,该审计策略将拒绝执行该语句,并返回相应的错误信息。#广播表配置,t_address做为广播表,在各分库中的结构数据一致
- !BROADCASTtables:- t_addressprops:sql-show: false
优势
- 功能全面:ShardingSphere支持水平拆分、读写分离、全局表、数据加密、分布式事务等多种功能,能够很好地满足大型分布式系统的需求。
- 性能损耗相对小:Sharding-JDBC相比Mycat,采用本地jar包嵌入本地应用程序,去中心化架构,性能损耗相对较小。
- 社区活跃:作为Apache顶级项目,ShardingSphere拥有更庞大的社区支持,文档和教程更加丰富。
劣势
- 配置复杂:配置还是有一定复杂度,当然相对Mycat要简单一些,官方文档。
- 开源生态集成支持较弱:例如和mysql各种高可用架构的集成,和大数据flink框架等的集成支持较弱。需要自己摸索集成方案。
三、阿里tddl
tddl是一个分布式数据库中间件,它在阿里内部被广泛使用,淘天系几乎所有的核心应用都有使用,主要是做为链接阿里数据库AliSql链接池,分库分表组件。
原理
tddl原理和Sharding-JDBC类似,也是嵌入到应用程序中的,有一个配置中心负责应用分库分表策略的存储。由于该组件是非开源的,这里不做过多介绍。
优势
- 性能非常强大,阿里包括交易,会员,广告等各种核心系统都是使用tddl来实现分库分表的。
- 功能强大,支持全局唯一id高效生成,和db配合实现高可用,分库分表sql处理等。
- 配置简单,配置非常简单,比Sharding-JDBC简单,在配置中心配置非常少量xml说明分库分表策略即可。
劣势
- 非开源组件,目前还未开源,外部无法使用。
四、OceanBase分区表
OceanBase是由蚂蚁集团完全自主研发的国产原生分布式数据库,始创于2010年。支付宝大部分核心系统,包括交易采用的都是OceanBase,已连续10年平稳支撑双11。oceanbase官网
原理
OceanBase通过节点多副本和Paxos协议来确保写入时WAL日志写入到多数节点确保高可靠性,充分利用内存来存储新写入数据,等待写入低峰刷内存数据批量刷磁盘来确保高性能写入,查询时通过内存,磁盘数据合并保障数据一致性。官方文档
OceanBase数据库本身天然支持分区策略,且天然支持高可用架构,且支持关系数据库的事务特性。在实际联机事务处理系统中,建议采用手动指定分区策略的方式,尽量避免跨分片的事务。
下图假设业务只有一张表t_order,手动将表分成了 8 个分区 P1-P8,那么 P1-P8 就分别均衡每个 Zone 到两个 OBServer 上,每个分区三个副本,从中选出一个 Leader,通过 Paxos 协议进行数据同步。同一台机器上的多个 Leader 一般会在同一个 Log Stream 中,这种跨分片级别的事务,仍然是本地事务,如 P1 和 P2 的关联查询。
分区表创建示例:
CREATE TABLE sales_orders (order_id INT,customer_id INT,order_date DATE,total_amount DECIMAL(10, 2),PRIMARY KEY(order_id, order_date)
) PARTITION BY RANGE(order_date) (PARTITION M202001 VALUES LESS THAN(TO_DATE('2020/02/01', 'YYYY/MM/DD')),PARTITION M202002 VALUES LESS THAN(TO_DATE('2020/03/01', 'YYYY/MM/DD')),PARTITION M202003 VALUES LESS THAN(TO_DATE('2020/04/01', 'YYYY/MM/DD')),PARTITION M202004 VALUES LESS THAN(TO_DATE('2020/05/01', 'YYYY/MM/DD')),PARTITION MMAX VALUES LESS THAN (MAXVALUE)
);
优势
- 使用简单:相比较Sharding-JDBC、MyCat + mysql的方式,不需要大量复杂的配置运维工作,也不需要在考虑如何与mysql高可用组件集成方式,只需要创建表时指定好分区策略即可。
- 可靠稳定,经过阿里双11流量洪峰的考验。只要分区策略配置合理,确保数据库操作访问被路由到单机节点,在保证高可用的前提下,能提供较好的性能。
- 阿里系生态集成较好,在阿里云上和阿里各种大数据技术集成较好。可简单的实现阿里云环境下db数据同步到离线、实时数仓中。
劣势
- 费用昂贵:OB服务器需要万兆网络,LSM树结构的元数据管理库占据内存较大,需要购买专用的云服务器。
- 备份恢复繁琐:备份恢复为单独的组件,运行机制为逻辑备份恢复,配置繁琐,备份恢复均较慢。
- OLTP事务处理能力不如PolarDB:OB也能提供高并发联机事务处理能力,但在某些特定场景下可能不如PolarDB优化得更好。
五、PolarDB
PolarDB是阿里巴巴自研的新一代云原生数据库,脱胎于淘天系经过10多年考验的xdb,综合各方面对比,PolarDB个人认为是需要分库分表场景下,对于小公司性价比最高,最简单有效的技术方案。官方文档
原理
PolarDB在内核实现层面更接近于mysql内核,脱胎于淘天系经过10多年考验的xdb,内核使用了X-Paxos、基于Batching & Pipelining 进行异地网络优化、基于代价的CBO优化器实现索引选择等黑科技,在控制成本的前提下实现了极致的性能。技术架构
PolarDB数据库本身也是天然支持分区策略,且天然支持高可用架构,支持关系数据库的事务特性。在实际联机事务处理系统中,建议采用手动指定分区策略的方式,尽量避免跨分片的事务。
分区表创建示例:
CREATE TABLE `orders` (`o_orderkey` int(11) NOT NULL,`o_custkey` int(11) NOT NULL,`o_orderstatus` char(1) DEFAULT NULL,`o_totalprice` decimal(10,2) DEFAULT NULL,`o_orderDATE` date NOT NULL,`o_orderpriority` char(15) DEFAULT NULL,`o_clerk` char(15) DEFAULT NULL,`o_shippriority` int(11) DEFAULT NULL,`o_comment` varchar(79) DEFAULT NULL,PRIMARY KEY (`o_orderkey`,`o_orderDATE`,`o_custkey`),KEY `o_orderkey` (`o_orderkey`),KEY `i_o_custkey` (`o_custkey`),KEY `i_o_orderdate` (`o_orderDATE`)
) ENGINE=InnoDB
PARTITION BY RANGE (TO_DAYS(o_orderdate))
(PARTITION item1 VALUES LESS THAN (TO_DAYS('1992-01-01')),PARTITION item2 VALUES LESS THAN (TO_DAYS('1993-01-01')),PARTITION item3 VALUES LESS THAN (TO_DAYS('1994-01-01')),PARTITION item4 VALUES LESS THAN (TO_DAYS('1995-01-01')),PARTITION item5 VALUES LESS THAN (TO_DAYS('1996-01-01')),PARTITION item6 VALUES LESS THAN (TO_DAYS('1997-01-01')),PARTITION item7 VALUES LESS THAN (TO_DAYS('1998-01-01')),PARTITION item8 VALUES LESS THAN (TO_DAYS('1999-01-01')),PARTITION item9 VALUES LESS THAN (MAXVALUE));
EXPLAIn select * from orders where o_orderDATE = '1992-03-01';
+----+-------------+--------+------------+------+---------------+---------------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+------+---------------+---------------+---------+-------+------+----------+-------+
| 1 | SIMPLE | orders | item2 | ref | i_o_orderdate | i_o_orderdate | 3 | const | 1 | 100.00 | NULL |
+----+-------------+--------+------------+------+---------------+---------------+---------+-------+------+----------+-------+
优势
- 使用简单:相比较Sharding-JDBC、MyCat + mysql的方式,也不需要大量复杂的配置运维工作,也不需要在考虑如何与mysql高可用组件集成方式,只需要创建表时指定好分区策略即可。
- 可靠稳定,只要分区策略配置合理,确保数据库操作访问被路由到单机节点,在保证高可用的前提下,能提供较好的性能。
- 阿里系生态集成较好,在阿里云上和阿里各种大数据技术集成较好。可简单的实现阿里云环境下db数据同步到离线、实时数仓中。
- 费用相较OceanBase低,PolarDB费用远低于OceanBase。因为PolarDB内核原理接近于mysql,X-Paxos协议相较OceanBase Paxos同步全部副本网络交互次数少,且PolarDB不会像OceanBase将大量写、更新数据长时间放到内存中,因此对网络,内存要求不高,不需要专用服务器。
- 极致弹性:通过存储与计算分离的架构,实现了分钟级别的弹性伸缩能力,用户可以根据业务需求快速调整资源规模。
劣势
- OLAP处理能力不如OceanBase:PolarDB在OLAP(联机分析处理)场景下的表现可能稍逊一筹,其数据处理和复杂查询能力可能不如OceanBase强大。