数据库的分库分表和读写分离的详细实施方案

打印 上一主题 下一主题

主题 1660|帖子 1660|积分 4980

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
以下是数据库的分库分表和读写分离的详细实施方案,结合实战场景和常见题目,恰当中大型高并发体系的架构设计:


  

一、分库分表(Sharding)

1. 焦点目标

• 办理单表数据量过大(如单表亿级数据)导致的查询性能降落。
• 水平扩展:通过拆分数据到多个表或数据库,分散压力。

2. 分库分表策略

(1) 水中分库(按行分)

• 实用场景:数据量大且访问热门均匀。
• 分片方式:
• 哈希分片:根据主键哈希值分配到差别分片。
sql -- 用户ID哈希分片到4个库 SELECT user_id, CONV(FLOOR(HASH(user_id) * 10000) / 10000, 10, 4) AS shard_id -- 0-9999分到0号库,10000-19999分到1号库,依此类推 FROM users;
• 范围分片:按时间、地域等维度划分范围。
sql -- 按订单时间分片到4个表 CREATE TABLE orders_2023_01 (...); -- 1月数据 CREATE TABLE orders_2023_02 (...); -- 2月数据
(2) 垂直分库(按列分)

• 实用场景:表中某些列访问频率极高,其他列极少利用。
• 示例:将 users 表拆分为 users_base(基础信息)和 users_profile(扩展信息)。

3. 实现方案

(1) 基于中间件的方案

• MySQL Cluster:内置分片功能,恰当读写高频场景。
• ShardingSphere:开源分布式数据库中间件,支持复杂查询路由。
• Vitess:云原生分片数据库,兼容 MySQL 协议。
(2) 应用层分片

• 自定义路由逻辑:在代码中实现分片算法。
  1. // Spring Boot + MyBatis 分片示例
  2. @MapperScan("com.example.sharding.mapper")
  3. public class ShardingConfig {
  4.     @Bean
  5.     public DataSource router() {
  6.         return new ShardingDataSource(Arrays.asList(
  7.             createDataSource("shard1"),
  8.             createDataSource("shard2")
  9.         ));
  10.     }
  11. }
复制代码
(3) 数据库级分片

• PostgreSQL 的 pg_sharding 扩展:支持水中分片。
• MongoDB 分片集群:按 shard key 自动分片。

4. 案例:电商订单表分库

背景

• 单表 orders 存储亿级订单,查询性能降落。
方案

• 分片键:order_id(哈希分片) + user_id(范围分片)。
• 目标:拆分为 16 个分片,每个分片存储约 6250 万订单。
数据迁移

  1. -- 使用 pt-table-checksum 和 pt-table-sync 工具迁移数据
  2. pt-table-checksum --host=localhost --user=root --database=orders
  3. pt-table-sync --host=localhost --user=root --database=orders shard_0
复制代码

二、读写分离(Read-Write Splitting)

1. 焦点目标

• 主库:处理惩罚写操作(INSERT/UPDATE/DELETE)。
• 从库:处理惩罚读操作(SELECT),分担主库压力。
• 高可用:主库故障时自动切换到从库(需结合熔断机制)。

2. 实现方案

(1) 基于主从复制的读写分离

• 配置步调:

  • 主库启用二进制日志:
    1. [mysqld]
    2. server_id=1
    3. log_bin=/var/log/mysql/mysqld-bin
    4. binlog_format=row
    复制代码
  • 从库配置:
    1. [mysqld]
    2. server_id=2
    3. relay_log=/var/log/mysql/relay-bin
    4. read_only=ON  # 从库只读
    复制代码
  • 主库创建复制用户:
    1. CREATE USER 'repl'@'%' IDENTIFIED BY 'password';
    2. GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
    复制代码
  • 从库同步数据:
    1. CHANGE MASTER TO
    2.     MASTER_HOST='master_ip',
    3.     MASTER_USER='repl',
    4.     MASTER_PASSWORD='password',
    5.     MASTER_USE_GTID=slave_pos;
    6. START SLAVE;
    复制代码
(2) 中间件方案

• Redis:作为查询缓存,从库数据同步到 Redis。
• Kafka:解耦读写,主库写入 Kafka,从库消耗并存储。
• ProxySQL:MySQL 代理,自动路由读写请求。
(3) 客户端分流

• 代码层分流:根据业务范例动态路由。
  1. # Python 示例:随机选择从库
  2. from random import choice
  3. slaves = ['slave1', 'slave2', 'slave3']
  4. slave_conn = connect_to_db(slaves[choice(len(slaves))])
复制代码

3. 主从耽误题目

(1) 产生原因

• 从库 CPU/IO 资源不敷。
• 大事务阻塞从库复制。
(2) 办理方案

• 半同步复制:至少一个从库确认写入后才提交主库事务。
  1. [mysqld]
  2. rpl_semi_sync_master_enabled=1
  3. rpl_semi_sync_master_timeout=1000  # 单位:毫秒
复制代码
• 多级复制:主库 → 中间从库 → 终端从库。
• 监控报警:及时检测 Seconds_Behind_Master。
  1. SHOW SLAVE STATUS\G
复制代码

三、进阶架构:分库分表 + 读写分离

1. 完整架构图

  1. 客户端 → 负载均衡器 → 读写路由器  
  2.                 ↓  
  3.            主库集群(Write)  
  4.                 ↑  
  5.            从库集群(Read)  
  6.                 ↑  
  7.         数据库中间件(如 ShardingSphere)  
  8.                 ↓  
  9.            物理分片数据库(MySQL/ShardingDB/TiDB)
复制代码
2. 实用场景

• 电商体系:用户表分库(按地域)、订单表分库(按时间)。
• 交际网络:动态表分库(按用户ID)、消息表读写分离。

四、常见题目与办理方案

1. 跨分片查询

• 题目:分库后无法直接关联查询。
• 办理方案:
• 应用层归并:在代码中分别查询多个分片并归并效果。
• 全局查询路由:利用中间件支持跨库 JOIN(如 ShardingSphere)。
2. 分布式事务

• 题目:跨分片事务同等性难以保证。
• 办理方案:
• Saga 模式:通过补偿机制实现最终同等性。
• Seata:开源分布式事务框架,支持 AT/TCC 模式。
3. 数据同等性迁移

• 工具推荐:
• Canal:监听 Binlog 实现增量同步。
• Debezium:Kafka 连接器,捕获数据库变动事件。

五、主流工具对比

工具特点实用场景ShardingSphere开源、支持复杂查询、MySQL 兼容中小型分布式体系TiDBHTAP 引擎、自动分片、云原生云原生、及时分析场景Vitess生态完善、YSQL 兼容Kubernetes 环境ProxySQL轻量级、MySQL 协议兼容快速接入、低资源场景
六、将来趋势


  • 云原生数据库:如 Amazon Aurora、Google Spanner,自动处理惩罚分片和复制。
  • Serverless 分库分表:按需自动扩缩容(如阿里云 PolarDB)。
  • 多模子数据库:支持文档、图等数据范例的分片(如 MongoDB)。

如果需要更详细的配置示例(如 TiDB 分片规则)或代码实现细节,请告诉我你的技术栈和业务场景!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

九天猎人

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表