当前位置: 首页 > article >正文

分库分表技术方案选型

一、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.HikariDataSource
    driverClassName: com.mysql.jdbc.Driver
    jdbcUrl: jdbc:mysql://localhost:3306/demo_ds_0?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
    username: root
    password:
  ds_1:
    dataSourceClassName: com.zaxxer.hikari.HikariDataSource
    driverClassName: com.mysql.jdbc.Driver
    jdbcUrl: jdbc:mysql://localhost:3306/demo_ds_1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
    username: root
    password:

#分库分表策略配置
rules:
- !SHARDING
  tables:
    t_order: 
      actualDataNodes: ds_${0..1}.t_order_${0..1} #t_order分两个库ds_0,ds_1,每个库分2张表t_order_0,t_order_1
      tableStrategy: 
        standard:
          shardingColumn: order_id  #t_order表依据order_id列分表
          shardingAlgorithmName: t_order_inline  #t_order_inline是分表算法
      keyGenerateStrategy: #t_order表主键列,以及主键生成算法
        column: order_id
        keyGeneratorName: snowflake #采用雪花算法生成主键
      auditStrategy: #审计策略配置,拦截并审核SQL语句,SQL必须包含分片列order_id,审计不通过报错
        auditorNames:
          - sharding_key_required_auditor
        allowHintDisable: true
        #控制是否禁用Hint分片路由的提示功能,启用则可以在应用线程中指定分片策略
    t_order_item:
      actualDataNodes: ds_${0..1}.t_order_item_${0..1}
      tableStrategy:
        standard:
          shardingColumn: order_id
          shardingAlgorithmName: t_order_item_inline
      keyGenerateStrategy:
        column: order_item_id
        keyGeneratorName: snowflake
  defaultShardingColumn: order_id
  bindingTables:
    - t_order,t_order_item
  defaultDatabaseStrategy: #默认兜底数据库分库策略,依据user_id分库
    standard:
      shardingColumn: user_id
      shardingAlgorithmName: database_inline
  defaultTableStrategy:
    none:
  
  shardingAlgorithms:
    database_inline:
      type: INLINE
      props:
        algorithm-expression: ds_${user_id % 2}
    t_order_inline:
      type: INLINE
      props:
        algorithm-expression: t_order_${order_id % 2}
    t_order_item_inline:
      type: INLINE
      props:
        algorithm-expression: t_order_item_${order_id % 2}
  keyGenerators:
    snowflake:
      type: SNOWFLAKE
  auditors:
    sharding_key_required_auditor:
      type: DML_SHARDING_CONDITIONS
    #DML_SHARDING_CONDITIONS算法要求在执行逻辑表查询时,必须带上分片键。
    #如果SQL语句中缺少分片键或分片键不正确,该审计策略将拒绝执行该语句,并返回相应的错误信息。

#广播表配置,t_address做为广播表,在各分库中的结构数据一致
- !BROADCAST
  tables:
    - t_address

props:
  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强大。

http://www.kler.cn/a/533000.html

相关文章:

  • 【PyQt】pyqt小案例实现简易文本编辑器
  • 游戏引擎 Unity - Unity 下载与安装
  • 【数据结构】栈与队列
  • 【C语言设计模式学习笔记1】面向接口编程/简单工厂模式/多态
  • [Proteus仿真]基于51单片机的智能温控系统
  • Java JWT 技术详解与实践指南
  • Spring理论知识(Ⅴ)——Spring Web模块
  • java-(Oracle)-Oracle,plsqldev,Sql语法,Oracle函数
  • 2.4学习记录
  • Vue 组件化开发指南:父子组件传值、emit、refs、事件总线、Provide/Inject
  • 【AI大模型】DeepSeek API大模型接口实现
  • 深入探讨前端新技术:CSS Container Queries 的应用与实践
  • Meta财报解读:营收超预期,用户增长放缓,AI与元宇宙仍是烧钱重点
  • BUU11 [极客大挑战 2019]Secret File1
  • 结合机器视觉与深度学习的 Python 项目
  • fastDFS简介及应用
  • Node.js与嵌入式开发:打破界限的创新结合
  • Qt网络相关
  • 25.02.04 《CLR via C#》 笔记 13
  • Linux——ext2文件系统(二)
  • 亚博microros小车-原生ubuntu支持系列:21 颜色追踪
  • 安全实验作业
  • 【Hadoop】Hadoop的HDFS
  • Docker技术相关学习二
  • oracle: 表分区>>范围分区,列表分区,散列分区/哈希分区,间隔分区,参考分区,组合分区,子分区/复合分区/组合分区
  • Tag注解