读写分离解决数据库读写操作的压力;分库分表解决存储压力
读写分离
架构模式
一主多从,主负责写,从负责读
适用的场景
读多写少
该模式的问题
主从复制延迟
解法:
- 写之后立即读取(一段时间内的读取),仍然读主库
- 代码侵入高
- 二次读取,读“从”读不到,再读一次“主”
- 重要业务读主,非重要业务读“从”
- 典型场景:注册 + 登录的读写全部读主机
分配机制
啥叫分配机制,就是决定啥时候读主,啥时候读从
实现方式有两种
- 程序代码层封装:比如TDDL
- 封装中间件
分库分表
为什么要分库分表
- 单台服务器存储量级有限
- 单台存储越多,查询越慢,主备复制也更慢
- 数据都放在单台,数据风险越高
使用场景:是不是一定要分库分表呢
当由于数据量级大导致查询性能受影响时
应该先考虑如下,最后才是分库分表
- 硬件优化:磁盘
- 数据库调优:增加索引等
- 引入缓存
- 业务层优化:代码查询逻辑优化,表结构设计优化等
分库分表后会带来业务查询上的复杂性,没有好的方案,就是比较复杂
方式
业务分库: 按业务分库。问题
- 分库后join操作不好做了
- 事务问题:原本在一个数据库中的不同表可以放在同一个事务中更改,分库后就不可以了。比如,商品下单,需要插入订单表,并修改库存,订单数据和商品数据在不同库后,业务层需要保证数据一致性
- 成本增加;机器成本
分表
垂直切分
方式
- 不同的列切到不同的表;一般不怎么查询的大字段拆出来
问题(问题较水平切分少多了)
- 当需要查询所有字段时,要操作多个表
水平切分
方式
按范围切(比如ID):每个分表数据量该多大,小了分表数变多,大了单表查询性能还是慢,一般单表100w - 2000w
优点:易于扩充,数据量增加,平滑扩充新的表,不需要迁移数据
缺点:可能存在每个分表数据分布不均匀(按ID切不存在此问题,如按时间戳切可能存在)
按Hash切分(比如userId % 10 = n, 则落在第n台服务器上)
优点:表分布比较均匀
缺点:增加表比较麻烦,需要重新分配数据
配置路由(增加一张路由表,比如usr_id -> table_id)
优点:设计简单实用灵活,扩充表时只需迁移相应数据,增加路由表
- 缺点:查询次数增加了一次;路由表大了怎么办