我的知识海洋

What are you following

  • 首页
  • 标签
  • 分类目录
  • 文章归档
  • 行路万里
  • 读书万卷
  • About Me

  • 搜索
面经 解决方案 操作系统 Java源码 开源 GSoC 哲学 中间件 回溯 链表 书 top 数据库 分布式 滑动窗口 配置 动态规划 前缀树 并查集 Redis 总结 年终总结 面试 算法基础

【Sharding-JDBC-3】分库分表策略及常见分片算法

发表于 2022-01-07 | 分类于 学习 | 阅读次数 1066
# 数据库 # 中间件
我不是教你zha-2
【随想录9 】回溯及模版(子集、排列问题)

水平分库分表常见策略讲解

range

  • 水平分库分表,根据什么规则进行?怎么划分?
  • 方案一:自增id,根据ID范围进行分表(左闭右开)
    • 规则案例
      • 1~1,000,000 是 table_1
      • 1,000,000 ~2,000,000 是 table_2
      • 2,000,000~3,000,000 是 table_3
      • ...更多
    • 优点
      • id是自增长,可以无限增长
      • 扩容不用迁移数据,容易理解和维护
    • 缺点
      • 大部分读和写都访会问新的数据,有IO瓶颈,整体资源利用率低
      • 数据倾斜严重,热点数据过于集中,部分节点有瓶颈

Range延伸进阶

  • Range范围分库分表,有热点问题,所以这个没用?

    • 关于怎么选择分库分表策略问题,如果业务适合就行,没有万能策略!!!!
    • 基于方案一:自增id,根据ID范围进行分表延伸解决方案,你能想到多少种
  • 范围角度思考问题 (范围的话更多是水平分表)

    • 数字

      • 自增id范围
    • 时间

      • 年、月、日范围
      • 比如按照月份生成 库或表 pay_log_2022_01、pay_log_2022_02
    • 空间

      • 地理位置:省份、区域(华东、华北、华南)
      • 比如按照 省份 生成 库或表

      比如外卖按照省份划分就不是很合理

  • 基于Range范围分库分表业务场景

    • 微博发送记录、微信消息记录、日志记录,id增长/时间分区都行

      • 水平分表为主,水平分库则容易造成资源的浪费
    • 网站签到等活动流水数据时间分区最好

      • 水平分表为主,水平分库则容易造成资源的浪费
    • 大区划分(一二线城市和五六线城市活跃度不一样,如果能避免热点问题,即可选择)

      • saas业务水平分库(华东、华南、华北等)

      不同城市量级不同,不会说某个区域特别火,某个区域请求量很少

Hash取模

方案二:hash取模(Hash分库分表是最普遍的方案)

  • 为啥不之间取模,如果取模的字段不是整数型要先hash,统一规则就行

案例规则

  • 用户ID是整数型的,要分2库,每个库表数量4表,一共8张表
  • 用户ID取模后,值是0到7的要平均分配到每张表
A库ID = userId % 库数量 2 
表ID = userId / 库数量 2 % 表数量4
userIdid % 2 (库-取余)id /2 % 4 (表)
110
201
311
402
512
603
713
800
910
  • 优点
    • 保证数据较均匀的分散落在不同的库、表中,可以有效的避免热点数据集中问题,
  • 缺点
    • 扩容不是很方便,需要数据迁移

分库分表常见中间件介绍和ShardingSphere

常见数据库分库分表中间件介绍

业界常见分库分表中间件

  • Cobar(已经被淘汰没使用了)
  • TDDL
    • 淘宝根据自己的业务特点开发了 TDDL (Taobao Distributed Data Layer)
    • 基于JDBC规范,没有server,以client-jar的形式存在,引入项目即可使用
    • 开源功能比较少,阿里内部使用为主
  • Mycat
    • 地址 http://www.mycat.org.cn/
    • Java语言编写的MySQL数据库网络协议的开源中间件,前身 Cobar
    • 遵守Mysql原生协议,跨语言,跨平台,跨数据库的通用中间件代理
    • 是基于 Proxy,它复写了 MySQL 协议,将 Mycat Server 伪装成一个 MySQL 数据库
    • 和ShardingShere下的Sharding-Proxy作用类似,需要单独部署

ShardingSphere 下的Sharding-JDBC

  • 地址:https://shardingsphere.apache.org/

  • Apache ShardingSphere 是一套开源的分布式数据库中间件解决方案组成的生态圈

    • 它由 Sharding-JDBC、Sharding-Proxy 和 Sharding-Sidecar 3个独立产品组合
  • Sharding-JDBC

    • 基于jdbc驱动,不用额外的proxy,支持任意实现 JDBC 规范的数据库
    • 它使用客户端直连数据库,以 jar 包形式提供服务,无需额外部署和依赖
    • 可理解为加强版的 JDBC 驱动,兼容 JDBC 和各类 ORM 框架
  • 最感兴趣的是Mycat和ShardingJdbc区别,也是被面试官问比较多的

    • 两者设计理念相同,主流程都是SQL解析-->SQL路由-->SQL改写-->结果归并
    • sharding-jdbc
      • 基于jdbc驱动,不用额外的proxy,在本地应用层重写Jdbc原生的方法,实现数据库分片形式
      • 是基于 JDBC 接口的扩展,是以 jar 包的形式提供轻量级服务的,性能高
      • 代码有侵入性
    • Mycat
      • 是基于 Proxy,它复写了 MySQL 协议,将 Mycat Server 伪装成一个 MySQL 数据库
      • 客户端所有的jdbc请求都必须要先交给MyCat,再有MyCat转发到具体的真实服务器
      • 缺点是效率偏低,中间包装了一层
      • 代码无侵入性

分库分表中间件Apache ShardingSphere

  • 什么是ShardingSphere

    • 已于2020年4月16日成为 Apache 软件基金会的顶级项目
    • 是一套开源的分布式数据库解决方案组成的生态圈,定位为 Database Plus
    • 它由 JDBC、Proxy 和 Sidecar这 3 款既能够独立部署,又支持混合部署配合使用的产品组成
  • 三大构成

    • ShardingSphere-Sidecar(规划中,简单知道就行)

      • 定位为 Kubernetes 的云原生数据库代理,以 Sidecar 的形式代理所有对数据库的访问
      • 通过无中心、零侵入的方案提供与数据库交互的啮合层,即 Database Mesh,又可称数据库网格
    • ShardingSphere-JDBC

      • 它使用客户端直连数据库,以 jar 包形式提供服务
      • 无需额外部署和依赖,可理解为增强版的 JDBC 驱动,完全兼容 JDBC 和各种 ORM 框架
      • 适用于任何基于 JDBC 的 ORM 框架,如:JPA, Hibernate, Mybatis,或直接使用 JDBC
      • 支持任何第三方的数据库连接池,如:DBCP, C3P0, BoneCP, HikariCP 等;
      • 支持任意实现 JDBC 规范的数据库,目前支持 MySQL,PostgreSQL,Oracle,SQLServer 以及任何可使用 JDBC 访问的数据库
      • 采用无中心化架构,与应用程序共享资源,适用于 Java 开发的高性能的轻量级 OLTP 应用
  • ShardingSphere-Proxy

    • 数据库代理端,提供封装了数据库二进制协议的服务端版本,用于完成对异构语言的支持
    • 向应用程序完全透明,可直接当做 MySQL/PostgreSQL
    • 它可以使用任何兼容 MySQL/PostgreSQL 协议的访问客户端(如:MySQL Command Client, MySQL Workbench, Navicat 等)操作数据

分库分表和Sharding-Jdbc常见概念术语讲解

  • 数据节点Node
    • 数据分片的最小单元,由数据源名称和数据表组成
    • 比如:ds_0.product_order_0
  • 真实表
    • 在分片的数据库中真实存在的物理表
    • 比如订单表 product_order_0、product_order_1、product_order_2
  • 逻辑表
    • 水平拆分的数据库(表)的相同逻辑和数据结构表的总称
    • 比如订单表 product_order_0、product_order_1、product_order_2,逻辑表就是product_order
  • 绑定表
    • 指分片规则一致的主表和子表
    • 比如product_order表和product_order_item表,均按照order_id分片,则此两张表互为绑定表关系
    • 绑定表之间的多表关联查询不会出现笛卡尔积关联,关联查询效率将大大提升
  • 广播表
    • 指所有的分片数据源中都存在的表,表结构和表中的数据在每个数据库中均完全一致
    • 适用于数据量不大且需要与海量数据的表进行关联查询的场景
    • 例如:字典表、配置表

分库分表和Sharding-Jdbc常见分片算法

  • 数据库表分片(水平库、表)

    • 包含分片键和分片策略
  • 分片键 (PartitionKey)

    • 用于分片的数据库字段,是将数据库(表)水平拆分的关键字段
    • 比如prouduct_order订单表,根据订单号 out_trade_no做哈希取模,则out_trade_no是分片键
    • 除了对单分片字段的支持,ShardingSphere也支持根据多个字段进行分片

分片策略

  • 行表达式分片策略 InlineShardingStrategy(必备)

    • 只支持【单分片键】使用Groovy的表达式,提供对SQL语句中的 =和IN 的分片操作支持

    • 可以通过简单的配置使用,无需自定义分片算法,从而避免繁琐的Java代码开发

    • prouduct_order_$->{user_id % 8}` 表示订单表根据user_id模8,而分成8张表,表名称为`prouduct_order_0`到`prouduct_order_7
      
  • 标准分片策略StandardShardingStrategy(需了解)

    • 只支持【单分片键】,提供PreciseShardingAlgorithm和RangeShardingAlgorithm两个分片算法
    • PreciseShardingAlgorithm 精准分片 是必选的,用于处理=和IN的分片
    • RangeShardingAlgorithm 范围分配 是可选的,用于处理BETWEEN AND分片
    • 如果不配置RangeShardingAlgorithm,如果SQL中用了BETWEEN AND语法,则将按照全库路由处理,性能下降
  • 复合分片策略ComplexShardingStrategy(需了解)

    • 支持【多分片键】,多分片键之间的关系复杂,由开发者自己实现,提供最大的灵活度
    • 提供对SQL语句中的=, IN和BETWEEN AND的分片操作支持
  • Hint分片策略HintShardingStrategy(需了解)

    • 这种分片策略无需配置分片健,分片健值也不再从 SQL中解析,外部手动指定分片健或分片库,让 SQL在指定的分库、分表中执行

    • 用于处理使用Hint行分片的场景,通过Hint而非SQL解析的方式分片的策略

    • Hint策略会绕过SQL解析的,对于这些比较复杂的需要分片的查询,Hint分片策略性能可能会更好

  • 不分片策略 NoneShardingStrategy(需了解)

    • 不分片的策略。
# 数据库 # 中间件
我不是教你zha-2
【随想录9 】回溯及模版(子集、排列问题)

  • 文章目录
  • 站点概览
erdengk

erdengk

91 日志
5 分类
24 标签
RSS
Github E-mail
Creative Commons
友链
  • 星球球友
  • Joey
  • 北松山(itwaix)-TP在职
  • JooKS' Blog-GSoC 2022 Mentor
  • Chever-John-Shein在职
  • 一堆网页小游戏
  • 飞鸟记
0%
© 2019 — 2025 erdengk
由 Halo 强力驱动
陕ICP备2021015348号-1
川公网安备 51011202000481号
轻点广告,请我喝水,非常感谢 (。・ω・。)ノ(*/ω\*)