分库分表实战
为什么分表解决单表数据量过大查询性能下降ddl困难问题分库解决单库连接数不足写并发高通过分摊压力提高吞吐量单机瓶颈。问题引入了分布式复杂性方式垂直分库分表按照业务模块拆分库按列拆分表水平分库分表按行拆分解决单表过大问题应对大数据量核心手段分片键怎么选查询频率高的路由算法范围分片按照id或时间分。扩容查询方便缺点容易数据倾斜哈希取模分片键哈希取模数据分布均匀缺点扩容困难需要迁移数据一致性哈希解决扩容问题节点变化前只需迁移少量数据。缺点实现复杂存在哈希倾斜风险分库分表数量为什么是2的幂次方和hashMap是一个道理。位运算优化hash % 8 等价于 hash (8-1)性能更高。均匀分配便于将表均匀分配到多个库中。易于扩容从N张表扩容到2N张表时只需迁移一半数据。利用了“高位运算”因为容量永远是 2 的幂扩容时只需看 hash 值新增的那一位高位是 0 还是 1。是 0 就留在原索引低位是 1 就迁移到 原索引 旧容量高位。分布式ID雪花算法redis自增(挂了怎么办)跨库JOIN常用字段冗余全局表每个库存一份变动少基础表(配置)。本地join应用层组装查好数据在内存中组装相关联的数据强制放在一个节点。比如订单和订单详情相同的订单数据要放在同一个节点。分布式事务如何处理比如强一致性的二阶段提交。但是不建议使用因为性能差。最终一致性比如tcc和saga。 Tcc比较复杂每种事务都要实现三个方法 Try confirm和cancel。本地消息表加重试或者rocket mq事务消息。非分片键如何查询一建立映射表非分片键和分片键建立映射表二异构索引根据另一个维度再建立一套分库分表。三基因法将分片信息植入到id中。比如订单表和用户id。订单号包含用户id分片信息。生成订单号的时候可以将用户id生成二进制然后放到订单号的尾部。查询的时候解析出来即可。或者是生成雪花id的时候专门划分几位保存库表编号。基因法的一个优点就是不用去查映射表也不用去配置中心拉取路由规则计算路由。速度会很快就是单纯的位运算。那他的一个缺点也很明显就是灵活性很差比如说我一个节点挂了或者发生数据倾斜或者是要扩容迁移数据的时候就没有办法使用。这里一个解决方案就是可以兜底使用映射覆盖就是在中间件层设置一个优先级更高的热迁移配置。如果有设置配置那么就去读取配置强制使用配置中的路由否则就使用id中的路由。如何设计当查询遇到分页怎么办先查出来然后再在内存中聚合。但是性能比较差。尽量能不分页就不分页或者使用es。如何设计动态扩容方案一停机扩容但是不推荐数量大的时候会很慢。二一次性规划好预分配。一次性就设计好32个库每个库32张表一共是1024张表。够用好久避免扩容迁移数据。