Sharding-JDBC 核心问答总结(面试速记版)

1. 不支持的查询类型

  • ❌ 跨分片JOIN:非绑定表/广播表的JOIN

  • ❌ 复杂子查询:分片键不一致的子查询

  • ❌ 跨分片分页LIMIT 100000,10 类大偏移量查询

  • ❌ 精确DISTINCT:跨分片去重结果可能不准确

  • ❌ 存储过程/函数:全不支持

  • ❌ UNION操作:跨分片UNION查询

规避方案

  • 绑定表处理关联查询

  • 将小表设为广播表

  • 分页改用连续查询WHERE id > ? LIMIT n


2. 扩展机制与难点

扩展方式

// 1. 自定义分片算法
class CustomSharding implements PreciseShardingAlgorithm<Long> {
  String doSharding(Collection<String> targets, PreciseShardingValue<Long> value) {
    return "ds_" + (value % 2); // 示例:按奇偶分库
  }
}

// 2. 自定义分布式ID生成器
class SnowflakeGenerator implements KeyGenerator {
  Comparable<?> generateKey() {
    return Snowflake.nextId(); // 雪花算法
  }
}

扩展难点

  • 🔥 SQL方言兼容性(如Oracle vs MySQL)

  • 🔥 跨分片事务一致性保障

  • 🔥 流式归并的内存控制

  • 🔥 全路由查询的性能劣化


3. 关键场景解决方案

场景解决方案
跨分表范围查询绑定表策略 + 范围分片算法(RangeShardingAlgorithm
跨天数据查询按时间分片(如log_202301)+ create_time BETWEEN ? AND ?
不停服扩容双写 → 增量同步(Canal)→ 数据校验 → 灰度切流 → 下线旧分片
兜底方案配置回滚 + 数据补偿(消息队列) + 熔断机制(maxConsecutiveErrors: 5
多库表数据聚合分片本地聚合 → 内存归并(SUM/COUNT)→ 流式归并(大数据量)

4. 核心流程剖析

执行特点

  • 解析引擎:基于ANTLR生成语法树

  • 改写引擎:逻辑表名→物理表名(t_order → t_order_01

  • 归并引擎:

    • 排序归并(ORDER BY

    • 分组归并(GROUP BY

    • 聚合归并(SUM/COUNT


5. Sharding-JDBC vs MyCAT

维度Sharding-JDBCMyCAT
架构无中心化(客户端嵌入)中心化(独立代理层)
性能⭐⭐⭐⭐ 无网络跳转⭐⭐ 有代理层开销
扩展性⭐⭐⭐ 灵活定制分片算法⭐⭐ 依赖插件机制
运维成本⭐ 应用集成,无需独立部署⭐⭐⭐ 需维护中间件集群
适用场景高性能Java应用多语言/遗留系统改造

选型依据

优先Sharding-JDBC:云原生/高性能场景
选MyCAT:非Java语言/需MySQL协议代理


6. 分库分表规则设计

分片键选择

  1. 高基数原则:用户ID > 订单ID > 时间戳

  2. 业务导向:高频查询条件字段(如user_id

  3. 避坑指南

    • 禁止选频繁更新的列

    • 避免数据倾斜(如按性别分片)

经典分片策略

sharding:
  tables:
    t_order:                   # 逻辑表名(应用程序中使用的表名)
      actualDataNodes: ds${0..1}.t_order${0..15}  # 物理表分布配置
      databaseStrategy:        # 分库策略配置
        standard:
          shardingColumn: user_id  # 分库键(根据此字段值决定数据存到哪个库)
          algorithmClassName: HashModDBSharding  # 分库算法实现类
      tableStrategy:           # 分表策略配置
        standard:
          shardingColumn: order_id  # 分表键(根据此字段值决定数据存到哪个表)
          algorithmClassName: HashModTBSharding  # 分表算法实现类
6.1 配置详解:
  1. 物理表分布 (actualDataNodes)

    • ds${0..1}:2个数据库(ds0, ds1)

    • t_order${0..15}:每个库有16张物理表(t_order0 到 t_order15)

    • 总量:2(库) × 16(表) = 32个物理存储单元

  2. 分库策略 (databaseStrategy)

    • 分片键user_id

    • 算法HashModDBSharding(自定义的取模算法)

    • 分库逻辑

      // 伪代码实现
      public class HashModDBSharding {
          public String doSharding(String user_id) {
              int dbIndex = hash(user_id) % 2;  // 对2取模
              return "ds" + dbIndex;  // 返回 ds0 或 ds1
          }
      }
  3. 分表策略 (tableStrategy)

    • 分片键order_id

    • 算法HashModTBSharding(自定义的取模算法)

    • 分表逻辑

      // 伪代码实现
      public class HashModTBSharding {
          public String doSharding(String order_id) {
              int tableIndex = hash(order_id) % 16;  // 对16取模
              return "t_order" + tableIndex;  // 返回 t_order0 到 t_order15
          }
      }
6.2 数据路由示例:

假设插入一条订单记录:

INSERT INTO t_order (order_id, user_id, ...) 
VALUES ("202308151234", "user_789", ...)

路由过程:

  1. 分库路由

    • 计算:hash("user_789") % 2 = 1

    • 目标库:ds1

  2. 分表路由

    • 计算:hash("202308151234") % 16 = 7

    • 目标表:t_order7

  3. 最终物理位置ds1.t_order7

6.3 配置特点分析:
  1. 双维度分片

    • 水平分库:按用户分散到不同数据库

    • 水平分表:按订单分散到不同表

  2. 路由优势

    • 相同用户的订单 → 同一数据库(便于用户维度查询)

    • 单个订单表数据量可控(分表解决单表过大问题)

  3. 扩容考虑

    • 库扩容:需修改取模基数(如 %2 → %3)

    • 表扩容:需修改取模基数(如 %16 → %32)

  4. 潜在热点问题

    • 高频用户可能造成库热点(需配合用户分桶)

    • 订单ID需保证哈希均匀性(避免表倾斜)

实际开发建议

  1. 在算法类中添加日志,验证哈希分布均匀性

  2. 对高频用户实现分桶策略(如 user_id_bucket = user_id % 10

  3. 使用一致性哈希减少扩容时的数据迁移量


7. 高频面试题速答

Q:如何解决跨分片分页?
A
① 业务侧改用连续查询(WHERE id > ? LIMIT n
② 限制最大归并行数(max.connections.size.per.query: 5
③ 禁止大偏移量查询(业务层面拦截)

Q:怎么保证扩容时数据一致?
A
① 双写阶段用事务消息确保新旧库原子写入
② 增量同步阶段通过binlog位点校对
③ 切换前用CRC32校验全量数据

Q:分布式ID如何生成?
A

// 集成Snowflake
shardingRule:
  defaultKeyGenerator:
    type: SNOWFLAKE
    props:
      worker.id: ${server.port} % 1024

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值