网站首页 > 技术文章 正文
大家好,我是mikechen。
分库分表是大数据拆分的必备技能,而且大厂面试也特别喜欢考察,下面我就全面来详解分库分表的拆分,希望对你有所帮助@mikechen
本篇已经收纳于mikechen原创超30万字《阿里架构师进阶专题合集》里面。
什么是分库分表?
分库分表是在海量数据下,由于单库、表数据量过大,导致数据库性能持续下降的问题,演变出的技术方案。
分库分表是由分库和分表这两个独立概念组成的,只不过通常分库与分表的操作会同时进行,以至于我们习惯性的将它们合在一起叫做分库分表。
通过一定的规则,将原本数据量大的数据库拆分成多个单独的数据库,将原本数据量大的表拆分成若干个数据表,使得单一的库、表性能达到最优的效果(响应速度快),以此提升整体数据库性能。
为什么要分库分表?
类似淘宝网这样的网站,海量数据的存储和访问成为了系统设计的瓶颈问题,日益增长的业务数据,无疑对数据库造成了相当大的负载。
随着规模的扩大,数据库面临如下问题:
- 读压力:并发 QPS、索引不合理、SQL 语句不合理、锁粒度;
- 写压力:并发 QPS、事务、锁粒度;
- 物理性能:磁盘瓶颈、CPU 瓶颈、内存瓶颈、IO 瓶颈、事务数、连接数等总是有限;
- 数据量太大:数据规模达到几千万行,数据库索引树庞大,查询性能出现瓶颈;
- 可用性低:如果是单库数据库宕机会导致 100%服务不可用,N 库则可以将影响面降低 N 倍;
最终数据库的数据处理能力都将遭遇瓶颈,所以分表分库就可以排上用场了,当然出之外还有缓存等一系列优化手段都可以采用。
分库分表带来的问题?
1.事务性问题
- 方案一:在进行分库分表方案设计过程中,从业务角度出发,尽可能保证一个事务所操作的表分布在一个库中,从而实现数据库层面的事务保证。
- 方案二:方式一无法实现的情况下,业务层引入分布式事务组件保证事务性,如事务性消息、TCC、Seata 等分布式事务方式实现数据最终一致性。
- 分库可能导致执行一次事务所需的数据分布在不同服务器上,数据库层面无法实现事务性操作,需要更上层业务引入分布式事务操作,难免会给业务带来一定复杂性,那么要想解决事务性问题一般有两种手段:
2.主键自增 ID唯一性问题
- 在数据库表设计时,经常会使用自增 ID 作为数据主键,这就导致后续在迁库迁表、或者分库分表操作时,会因为主键的变化或者主键不唯一产生冲突,要解决主键不唯一问题,有如下方案:
- 方案一:自增 ID 做主键时,设置自增步长,采用等差数列递增,避免各个库表的主键冲突。但是这个方案仍然无法解决迁库迁表、以及分库分表扩容导致主键 ID 变化问题
- 方案二:主键采用全局统一 ID 生成机制:如 UUID、雪花算法、数据库号段等方式。
3.跨库多表 join 问题
首先来自大厂 DBA 的建议是,线上服务尽可能不要有表的 join 操作,join 操作往往会给后续的分库分表操作带来各种问题,可能导致数据的死锁。可以采用多次查询业务层进行数据组装(需要考虑业务上多次查询的事务性的容忍度)
4.跨库聚合查询问题
分库分表会导致常规聚合查询操作,如 group by,order by 等变的异常复杂,需要复杂的业务代码才能实现上述业务逻辑。
如何分库分表?
1.垂直拆分
垂直拆分又可以分为:垂直拆表和垂直拆库。
1)垂直拆表
即大表拆小表,将一张表中数据不同”字段“分拆到多张表中,比如商品库将商品基本信息、商品库存、卖家信息等分拆到不同库表中。
2)垂直拆库
垂直拆库则在垂直拆表的基础上,将一个系统中的不同业务场景进行拆分,比如把一个数据库拆分为:商品数据库、用户数据库、交易数据库。
如下图所示:
2.水平拆分
前边说了垂直切分还是会存在单库、表数据量过大的问题,当我们的应用已经无法在细粒度的垂直切分时, 依旧存在单库读写、存储性能瓶颈,这时就要配合水平切分一起了,水平切分能大幅提升数据库性能。
这里的水平拆分又可以分为:水平拆表和水平拆库。
1)水平拆表
将数据按照某种维度拆分为多张表,但是由于多张表还是从属于一个库,其降低锁粒度,一定程度提升查询性能,但是仍然会有 IO 性能瓶颈。
2)水平拆库
将数据按照某种维度分拆到多个库中,降低单机单库的压力,提升读写性能。
分库分表中间件有哪些
常用的分库分表中间件,如下图所示:
更加详细的内容请查看:数据库中间件最全详解(图文全面总结)
以上
本篇已经收纳于mikechen原创超30万字《阿里架构师进阶专题合集》里面。
- 上一篇: 微服务架构数据一致性的解决思路
- 下一篇: 如何保证redis缓存与数据库数据一致性
猜你喜欢
- 2024-11-30 分布式系统最全详解(图文全面总结)
- 2024-11-30 架构设计最全详解(万字图文总结)
- 2024-11-30 最佳实践:确保MySQL和Redis数据一致性的方法
- 2024-11-30 面试京东实习,如何保障三个数据库的数据一致性?
- 2024-11-30 无锁编程——从CPU缓存一致性讲到内存模型
- 2024-11-30 分布式系统一致性保障:CAP理论与BASE原则
- 2024-11-30 如何保证redis缓存与数据库数据一致性
- 2024-11-30 微服务架构数据一致性的解决思路
- 2024-11-30 如何确保高并发秒杀场景下Redis与数据库库存的一致性
- 2024-11-30 CPU缓存一致性原理
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)