读写分离解决数据库读写操作的压力;分库分表解决存储压力

读写分离

架构模式

一主多从,主负责写,从负责读

适用的场景

读多写少

该模式的问题

主从复制延迟

解法:

  1. 写之后立即读取(一段时间内的读取),仍然读主库
  • 代码侵入高
  1. 二次读取,读“从”读不到,再读一次“主”
  2. 重要业务读主,非重要业务读“从”
  • 典型场景:注册 + 登录的读写全部读主机

分配机制

啥叫分配机制,就是决定啥时候读主,啥时候读从
实现方式有两种

  • 程序代码层封装:比如TDDL
  • 封装中间件

分库分表

为什么要分库分表

  • 单台服务器存储量级有限
  • 单台存储越多,查询越慢,主备复制也更慢
  • 数据都放在单台,数据风险越高

使用场景:是不是一定要分库分表呢

当由于数据量级大导致查询性能受影响时
应该先考虑如下,最后才是分库分表

  1. 硬件优化:磁盘
  2. 数据库调优:增加索引等
  3. 引入缓存
  4. 业务层优化:代码查询逻辑优化,表结构设计优化等

分库分表后会带来业务查询上的复杂性,没有好的方案,就是比较复杂

方式

业务分库: 按业务分库。问题

  • 分库后join操作不好做了
  • 事务问题:原本在一个数据库中的不同表可以放在同一个事务中更改,分库后就不可以了。比如,商品下单,需要插入订单表,并修改库存,订单数据和商品数据在不同库后,业务层需要保证数据一致性
  • 成本增加;机器成本

分表

垂直切分

方式

  • 不同的列切到不同的表;一般不怎么查询的大字段拆出来

问题(问题较水平切分少多了)

  • 当需要查询所有字段时,要操作多个表

水平切分

方式

  • 按范围切(比如ID):每个分表数据量该多大,小了分表数变多,大了单表查询性能还是慢,一般单表100w - 2000w

  • 优点:易于扩充,数据量增加,平滑扩充新的表,不需要迁移数据

  • 缺点:可能存在每个分表数据分布不均匀(按ID切不存在此问题,如按时间戳切可能存在)

  • 按Hash切分(比如userId % 10 = n, 则落在第n台服务器上)

  • 优点:表分布比较均匀

  • 缺点:增加表比较麻烦,需要重新分配数据

  • 配置路由(增加一张路由表,比如usr_id -> table_id)

  • 优点:设计简单实用灵活,扩充表时只需迁移相应数据,增加路由表

  • 缺点:查询次数增加了一次;路由表大了怎么办