5.7 KiB
5.7 KiB
微服务数据库拆分设计方案
1. 现状分析
当前PHP单库结构
erp_db (单库,所有表)
├── 用户相关表
│ ├── users
│ ├── roles
│ ├── permissions
│ └── user_roles
│
├── 订单相关表
│ ├── orders
│ ├── order_items
│ └── order_operations
│
├── 商品相关表
│ ├── goods
│ ├── brands
│ ├── suppliers
│ └── categories
│
├── 库存相关表
│ ├── stock
│ └── stock_logs
│
├── 财务相关表
│ ├── finance_transactions
│ └── account_balances
│
└── 其他业务表
├── files
├── notifications
├── tenants
└── system_configs
2. 拆分原则
2.1 按业务领域拆分
- 每个微服务拥有独立的数据库
- 数据库按业务领域划分
- 服务间通过API或消息队列通信
2.2 数据所有权原则
- 谁创建数据,谁拥有数据
- 其他服务通过服务间调用访问数据
- 避免直接数据库访问
2.3 数据一致性策略
- 强一致性:分布式事务(Seata)
- 最终一致性:消息队列+事件驱动
- 数据同步:CDC变更数据捕获
3. 拆分方案
3.1 数据库拆分设计
| 微服务 | 数据库名 | 包含表 | 数据量预估 |
|---|---|---|---|
| 用户服务 | user_db |
users, roles, permissions, user_roles, login_logs | 10万+ |
| 订单服务 | order_db |
orders, order_items, order_operations, order_logs | 100万+ |
| 商品服务 | product_db |
goods, brands, suppliers, categories, product_prices | 5万+ |
| 库存服务 | inventory_db |
stock, stock_logs, warehouses, locations | 50万+ |
| 财务服务 | finance_db |
finance_transactions, account_balances, invoices, payments | 50万+ |
| 文件服务 | file_db |
files, file_groups, file_metadata | 100万+ |
| 租户服务 | tenant_db |
tenants, packages, tenant_features | 1万+ |
| 通知服务 | notification_db |
notifications, notification_templates, message_queue | 100万+ |
| 配置服务 | config_db |
system_configs, config_groups, config_history | 1万+ |
3.2 共享数据表
| 表名 | 用途 | 归属服务 | 访问方式 |
|---|---|---|---|
| 字典表 | 通用字典数据 | 配置服务 | API调用 |
| 地区表 | 省市区数据 | 配置服务 | API调用 |
| 日志表 | 操作日志 | 日志服务 | 消息队列 |
4. 迁移策略
4.1 分阶段迁移
阶段1: 数据库逻辑拆分 (本周)
- 创建独立数据库
- 迁移表结构
- 保持PHP系统正常运行
阶段2: 数据同步 (下周)
- 建立数据同步通道
- 实时同步关键数据
- 验证数据一致性
阶段3: 服务切换 (下下周)
- 逐步切换服务到新数据库
- 监控数据一致性
- 回滚机制准备
阶段4: 完全切换 (下下下周)
- 所有服务使用新数据库
- 停用旧数据库
- 清理同步通道
4.2 数据同步方案
方案1: 双写模式
PHP应用 → 同时写入 → 旧数据库 + 新数据库
↓
数据一致性校验
方案2: CDC同步模式
旧数据库 → Debezium CDC → Kafka → 新数据库
(变更数据捕获) (消息队列)
方案3: 应用层同步
PHP应用 → 写入旧数据库 → 同步服务 → 写入新数据库
5. 技术实现
5.1 数据库连接配置
# 用户服务配置
spring:
datasource:
url: jdbc:mysql://mysql-server:3306/user_db
username: user_service
password: ${DB_PASSWORD}
# 订单服务配置
spring:
datasource:
url: jdbc:mysql://mysql-server:3306/order_db
username: order_service
password: ${DB_PASSWORD}
5.2 数据同步配置
# Debezium CDC配置
debezium:
connector:
class: io.debezium.connector.mysql.MySqlConnector
database.hostname: mysql-server
database.port: 3306
database.user: cdc_user
database.password: ${CDC_PASSWORD}
database.server.id: 184054
database.server.name: erp_cdc
table.include.list: erp_db.*
database.history.kafka.bootstrap.servers: kafka:9092
database.history.kafka.topic: dbhistory.erp
5.3 服务间数据访问
// 订单服务需要用户信息时,调用用户服务API
@FeignClient(name = "user-service")
public interface UserServiceClient {
@GetMapping("/api/users/{userId}")
UserDTO getUserById(@PathVariable Long userId);
}
// 而不是直接查询用户数据库
6. 风险与应对
6.1 数据一致性风险
- 风险: 拆分过程中数据不一致
- 应对: 实时数据校验,不一致时告警并自动修复
6.2 性能风险
- 风险: 服务间调用增加延迟
- 应对: 缓存常用数据,批量查询优化
6.3 复杂性风险
- 风险: 系统复杂度增加
- 应对: 完善监控告警,自动化运维
7. 实施计划
7.1 时间计划
第1周: 方案设计 + 环境准备
第2周: 数据库创建 + 表结构迁移
第3周: 数据同步通道建立
第4周: 服务逐步切换
第5周: 完全切换 + 验证
7.2 团队分工
- DBA团队: 数据库拆分、备份恢复
- 开发团队: 服务改造、API适配
- 运维团队: 监控部署、性能优化
- 测试团队: 数据一致性验证
8. 成功指标
8.1 技术指标
- 数据一致性: 99.99%
- 服务响应时间: < 200ms (P95)
- 系统可用性: 99.9%
8.2 业务指标
- 零数据丢失
- 业务无感知切换
- 性能不下降
下一步行动:
- 评审设计方案
- 准备数据库环境
- 开始阶段1实施