数据库分库分表的一些思路总结

分库分表方案

垂直切分

垂直分库

根据业务耦合度,将数据库表进行分类,不同的业务表放入不同的数据库中

垂直分表

对于表字段列非常多的表进行字段切分,将不常用的字段单独放入辅助表,提升行数据查询效率

优点:根据业务耦合度切分,业务清晰,高并发情况下,一定程度的提升IO效率、解决单机资源瓶颈

缺点:部分表无法join,只能通过业务层做聚合;依然存在单表数据量过大的情况

 

水平切分

库内分表:解决单表数据量大问题,但解决不了单机资源瓶颈问题

分库分表:解决单表数据大,单机性能瓶颈;但引入分布式事务的复杂性,跨库join性能差、一些聚合操作复杂性能低;

 

数据分片的策略:

根据数值范围

按时间区间或者数值区间进行切分,可以按日、月切分到不同的数据库,或者按数值区间进行切分

优点:单表大小可控,水平扩展方便

缺点:热点数据可能成为瓶颈,比如新增的数据访问频繁集中于一个数据库表

 

根据数值取模

根据指定数据列进行hash取模,切分到不同的数据库中

优点:数据分布均匀,解决热点数据瓶颈问题

缺点:扩容时需要重新分片迁移数据;跨分片查询复杂,如果对于非分片列的查询,不能确定数据在哪个库,需要有分片数据列的映射关系才能确定数据库

分库分表引入的一些问题

事务一致性问题(2PC(两阶段提交)\全局事务处理器(springcloud txmanage):若要保证节点的事务性,需要牺牲一定的高可用,延长事务的执行时间;最终一致性,提高可用性,通过事务补偿机制,对数据进行最终检查,保证最终一致性

跨库join问题:一些策略,全局映射关系表,每个库都存在,减少表的join,存放不经常变化的元数据;字段冗余,冗余一些需要join查询得到的字段;系统层面分别查询后再次组装;

跨库分页、排序、函数问题:通过多库查询之后再次聚合,性能影响较大

全局主键唯一问题:保证主键唯一性,需要引入高可用的ID生成系统

 

分布式ID生成方案

UUID:32个16进制的数组,性能非常高、本地生成,没有网络消耗

缺点:占用16字节的内存,不利于存储;在mysql Innodb中不适用于主键,B+数的每个节点存放的数据少导致树深度大,索引查询效率低;uuid无序,在插入时需要寻找插入位置移动数据多,效率慢

 

DB自增:使用DB主键自增的特性,每次插入数据前先查询最新的ID,再进行插入

缺点:DB单机性能问题;对于一些业务场景不适用,如订单,会泄露信息

 

雪花算法:使用64位long数值存储(1+41+10+12);41位时间戳在高位,自增序列在低位,整个ID是自增的趋势;不依赖第三方数据库;以服务的方式部署,稳定性高;

缺点:依赖于机器时钟,如果机器时钟回拨,可能导致ID重复

 

 

美团leaf方案(https://tech.meituan.com/2017/04/21/mt-leaf.html

优化DB主键自增方案:

解决单机问题:通过多机部署,分别设置不容的主键自增步长保证id自增且唯一

解决数据库查询效率问题:每次生成一定范围的id放入缓存中给业务使用

解决缓存id使用完后大并发查db问题:双buffer,每次在缓存id使用一定量时,通过更新线程获取下一段id,放入缓存

缺点:同样的使用db自增的不适用于某些业务,如订单;数据库压力只能通过堆机器解决;

 

优化雪花算法法案:

解决workId生成问题:通过zookeepr的持久顺序节点的特性生成workId,缓存本地使用

解决时钟回拨问题:每次获取Id时判断当前时间与上一次ID生成时间的大小,若小于则等待或者生成失败发送告警;定时检查最新ID的时间戳和当前时间做对比;

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值