ShardManager 架构概览(非技术评审版)

用直观方式说明:为什么分库分表、怎么分、对现有系统的影响。

一页图:我们做了什么

flowchart LR
  subgraph App[业务应用]
    A[下单/报表/任务] -->|调用 SDK| B(ShardManager)
  end

  subgraph Core[ShardManager 内核]
    B --> C[按规则选库\n(Logical Region)]
    B --> D[按月份选表\n(shipments_YYYYMM)]
  end

  C -->|返回 databaseKey| E[(业务数据库集群)]
  D -->|返回 tableName| E

  subgraph Control[控制面]
    F[中央库\nwarehouse_shard_map]
    G[(Redis 缓存)]
  end

  B -->|读取映射| F
  B -->|版本前缀缓存| G

  style B fill:#eef,stroke:#446
  style C fill:#efe,stroke:#484
  style D fill:#efe,stroke:#484
  style F fill:#ffe,stroke:#a84
  style G fill:#ffe,stroke:#a84
  • 应用通过 SDK 得到“库 + 表”。
  • 选库:按“逻辑 Region(由 warehouse 映射)”;PoC 两个库。
  • 选表:按月份 shipments_YYYYMM
  • 映射来自中央库,Redis 缓存带有版本前缀,变更快速生效。

为什么这样做

  • 扩展性:按月拆表、按 region 分库,降低单库/单表压力。
  • 低侵入:SDK 只计算库表,不改你现有的数据库调用方式。
  • 可演进:分库/分表策略可插拔,后续可切换为“城市/租户/渠道”。

对现有系统的影响

  • 代码:新增一步“询问 SDK 要去哪张表”,其余不变。
  • 配置:新增 sharding.*;中央库连接由业务维护。
  • 运维:中央库维护映射与版本;Redis 缓存;Atlas 生成变更计划并审批执行。

变更如何生效(时序)

sequenceDiagram
  participant Ops as 运维
  participant Central as 中央库
  participant Redis as Redis
  participant App as 业务应用
  participant SDK as ShardManager

  Ops->>Central: 更新 warehouse_shard_map
  Ops->>Central: 更新 shard_version.version
  SDK->>Redis: 读 version 前缀 (miss)
  SDK->>Central: 读取最新 version
  SDK->>Redis: 写入 version,设置 TTL
  App->>SDK: route(warehouseId, ts)
  SDK->>Redis: 读 {prefix}{version}:wh:{id}
  alt miss
    SDK->>Central: 查询映射
    SDK->>Redis: setex 缓存映射
  end
  SDK-->>App: 返回 databaseKey + tableName

验收与演示

  • Demo:php examples/route_demo.php 输出如 uni_region_001.shipments_YYYYMM
  • 单测:
    • 默认策略路由;
    • 跨月表集合。

后续路线

  • 更多策略(城市/租户/渠道)。
  • 更精细的只读副本选择(延迟/权重)。
  • 开源拆分:uni/sharding-coreuni/sharding-lumen