分库分表深度解析

一、为什么要分库分表?

通常,数据库性能受到如下几个限制:

  1. 硬件瓶颈:单机的 CPU、内存、磁盘 I/O 等资源总是有限。例如,当单表中的记录达到上亿、甚至更高时,表扫描、索引维护和数据迁移会变得非常慢。
  2. 单点压力:所有业务都依赖单数据库实例,一旦主库宕机,整个系统面临服务不可用的风险。
  3. 高并发访问:瞬时的并发读写流量可能压垮数据库连接数,导致业务性能急剧下降。

分库分表的目标

  • 提高数据库性能:通过分布式扩展,将数据压力分散到多个独立的数据库节点上,减少单库读写开销。
  • 提高系统可用性:分库分表支持分布式架构,单节点故障不会影响整体服务。
  • 支持海量数据存储:横向扩展减少单表大小,优化查询稳定性,降低表扫描的可能性。

二、分库与分表的核心概念

1. 水平分表 & 垂直分表

  • 水平分表:将一个表根据某种规则(如主键范围或哈希值)分成多张子表,数据均匀分布。

    • 优点:解决单表数据量大引起的性能问题。
    • 缺点:跨分片查询变复杂,插入引发分片路由。
    • 应用场景:订单表、聊天消息表等高增长、海量记录的表。
  • 垂直分表:按字段将一个表分拆为多张表,按功能属性划分。

    • 优点:减小单表字段数,降低查询扫描的 IO。
    • 缺点:可能涉及跨表关联查询,开发复杂度提升。
    • 应用场景:拆分用户主表和扩展表等。

2. 分库

分库是将数据库从单实例扩展为多实例的架构部署方式。一种常见方式是结合分表逻辑,将分表数据分别存储到不同的数据库实例中。分库后的数据库实例可以分布在不同的物理节点上,独立运行并扩展。

分库更关注于系统间负载的隔离,可以:

  • 减少资源竞争。
  • 增加数据库服务器扩展能力。

三、分库分表的设计原则与实现策略

1. 划分规则的设计

分库分表依赖于科学合理的分片规则,具体包括以下几类方法:

  1. 范围分片

    • 将数据按照一定的范围划分,例如将表按照时间、ID区间分成若干份。
    • 优点:规则简单,插入和查询性能高。
    • 缺点:数据热点问题容易产生。
    • 适用场景:按时间维度分的日志表、账单表。
  2. 哈希分片

    • 基于主键进行哈希运算,哈希函数值映射到多个分片中。
    • 优点:分布均匀,减少单点压力。
    • 缺点:不支持区间查询。
    • 适用场景:商品表、用户表。
  3. 按维度分片(Sharding By Key)

    • 针对业务逻辑,将数据通过特定业务字段分拆。
    • 举例:电商系统按商户 ID、用户 ID 或地区分片。
    • 特点:满足业务隔离规则,关联性同维度数据通常集中。
  4. 动态拆分

    • 初期无需分片,当数据规模达到一定的阈值后,通过动态调整分片规则,逐步将数据迁移到多个分片中进行存储与查询。
    • 优点:初期设计简单,降低复杂度,灵活扩展,资源利用率高。
    • 缺点:数据迁移过程中存在一定成本,设计与实施难度较高。
    • 适用场景:初期数据量较少,后续可能随业务增长呈指数级扩大,例如不断增长的订单表、用户表等。

2. 分库分表的关键问题与挑战

在进行分库分表的实际实施过程中,需要面对一些挑战性问题。以下是常见的几个问题以及应对策略:

(1) 数据路由与查询复杂度
  • 问题描述:分库分表后,数据分散存储,传统的单库查询方式不再适用。每次请求必须先确定目标库或目标表。
  • 解决方案
    1. 路由规则的设计:通过统一的分片键(sharding key,通常是 ID 或某些范围字段),以程序化的方法路由。多使用中间件或配置静态哈希路由规则。
    2. 中间件支持:通过分库分表中间件(如 MyCat、ShardingSphere)简化数据路由层的开发。
    3. 分布式环境下的聚合查询:针对跨库查询,通过中间件层负责分布式查询聚合(MapReduce 类逻辑)。如 Elasticsearch 使用的分布式分片存储结合索引设计。
(2) 跨分片事务
  • 问题描述:传统关系型数据库通过锁定机制或分布式回滚保障事务一致性,但分库分表的多实例环境中,事务很难局限在单节点内管理。
  • 解决方案
    1. 分布式事务协议:使用两阶段提交(2PC)或三阶段提交,协调资源的一致性。
    2. 本地事务 + 最终一致性:通过异步补偿(如消息队列)实现弱一致性。
    3. TCC 模型:Try-Confirm-Cancel,通过应用逻辑隔离事务状态,适用于电商订单场景。
    4. 去中心化事务落地:结合 CAP 理论,优先将核心操作放在单库内完成,避免高频跨分片事务。
(3) ID 唯一性问题
  • 问题描述:分库分表后,自增 ID 会失去意义,因为每个分片的序列号冲突可能性大。
  • 解决方案
    1. 分布式 ID 生成
      • UUID:优点是全局唯一,容易生成;缺点是过长,查询和索引效率较低。
      • 雪花算法(Snowflake):Twitter 提出的分布式 ID 生成器(64 位),结合时间戳、机器 ID 等信息生成递增的全局唯一 ID。
      • 数据库序列/步长生成:如 MySQL 的 auto_increment,步长分片,避免冲突。
      • Redis 计数器:利用 Redis 的原子性操作(如 INCR)生成唯一 ID。
    2. 联合主键:以分片键和记录本地自增 ID 为联合主键。
(4) 跨节点关联查询问题
  • 问题描述:传统的多表关联查询(JOIN)随着表横向拆分,可能涉及多个库或多个节点的操作,使得查询性能急剧下降。
  • 解决方案
    1. 查询拆分:通过业务逻辑解耦查询,将复杂的多表关联拆分成多次单表查询。
    2. 数据冗余与同步:在不同分片中保存可能关联的冗余数据,减少 JOIN 的发生。
    3. 实时索引同步:使用分布式搜索引擎(如 Elasticsearch)作为辅助索引服务。
    4. 分布式 SQL 中间件:使用支持分布式 JOIN 查询的中间件,如 ShardingSphere 等,自动完成查询优化和数据路由。
(5) 数据迁移与扩容
  • 问题描述:随着业务增长,最初设计的分片规则可能无法满足需求。例如,新加入一个数据库实例需要重新分片迁移大量数据。

  • 解决方案

    1. 添加分片规则的灵活性:在设计初期预留一定的扩展字段,如虚拟分区粒度更细。
    2. 数据迁移策略
      • 全量数据迁移:冷备快照 + 增量数据补偿。
      • 迁移中间态机制:迁移过程中适配读写的双写
  • 迁移过程中避免服务中断

    1. 双写机制:读写同时进行到新旧数据库,直至新数据库中的数据完全同步后切换流量。
    2. 灰度迁移:逐步将少量的业务流量切换到新分片库,通过迁移过程的稳定性测试最终完成全量服务转移。
    3. 数据备份与回滚:做好迁移失败时的应急回滚策略,例如通过定时快照还原到旧数据库。

3. 分库分表中间件的选型与特点

在分库分表实践中,中间件扮演了举足轻重的角色,它们屏蔽了分布式架构的复杂性,简化了开发人员的实现难度。以下是几种流行的分库分表中间件及其特点:

(1) MyCat
  • 开源的数据库分库分表中间件,支持 MySQL 等数据库。
  • 特点
    • 支持水平拆分和垂直拆分。
    • 兼容多种分表算法(哈希、范围等)。
    • 提供简单的跨分库关联查询支持,通过全局聚合完成最终结果。
  • 缺点
    • 高并发场景性能相对较低,事务支持能力较弱。
(2) ShardingSphere
  • Apache 社区支持的开源分布式数据库生态,包含 Sharding-JDBC、Sharding-Proxy 等模块。
  • 特点
    • 灵活的分布式 SQL 查询支持,能在程序中无缝集成。
    • 完善的动态分片、负载均衡、高可用机制。
    • 支持柔性事务(TCC)和分布式事务(2PC)。
  • 缺点
    • 学习曲线较陡,配置复杂度较高。
(3) TiDB
  • 分布式 NewSQL 数据库,天然支持数据分片,具备良好的集群扩展能力。
  • 特点
    • 兼容 MySQL 协议,可直接无缝迁移。
    • 自动分布式事务支持,避免人工分片逻辑。
    • 水平扩展能力强,擅长解决 PB 级别的存储需求。
  • 缺点
    • 对高性能实时写入会产生一定延迟。

四、分库分表实战案例分析

以下结合具体场景,详细介绍分库分表的一个落地方案:

场景:大型电商平台的订单系统

业务特点
  • 每天高峰期存在数百万级订单写入请求。
  • 滞留订单需要长期统计与查询。
  • 支付状态、物流信息等多维度数据需要实时更新。
传统痛点
  1. 单表数据过亿,索引查询效率下降。
  2. 高频订单写操作导致数据库连接池不堪重负。
  3. 跨表关联(如订单 → 用户)深受大表影响。
分库分表架构设计
  1. 分表模型设计

    • 对订单表按用户 ID 进行哈希分片,每 10 万用户分为一个分片(Hash(user_id) % 16 = 库编号),单表内按时间分区存储。
    • 利用时间字段按天创建分区索引,确保历史订单查询性能。
  2. 分库设计

    • 将订单数据存储在 16 个数据库实例中,每个实例组成主从集群。
    • 数据库实例之间物理隔离,分布式部署,减少单机资源竞争。
  3. ID 唯一性生成

    • 通过 Twitter 的 Snowflake 算法生成包含时间戳、节点号、自增序列的全局唯一订单编号。
  4. 事务保障

    • 主流程订单写入尽量避免跨分片操作。
    • 对于支付、库存

参考文档: https://blog.csdn.net/weixin_61669379/article/details/141648151

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/news/906893.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

QListWidget的函数,信号介绍

前言 Qt版本:6.8.0 该类用于列表模型/视图 QListWidgetItem函数介绍 作用 QListWidget是Qt框架中用于管理可交互列表项的核心组件,主要作用包括: 列表项管理 支持动态添加/删除项:addItem(), takeItem()批量操作:addItems()…

ModbusRTU转profibusDP网关与RAC400通讯报文解析

ModbusRTU转profibusDP网关与RAC400通讯报文解析 在工业自动化领域,ModbusRTU和ProfibusDP是两种常见的通信协议。ModbusRTU以其简单、可靠、易于实现等特点,广泛应用于各种工业设备之间的通信;而ProfibusDP则是一种高性能的现场总线标准&am…

Python容器

一、容器 1. 列表【】:有序可重复可混装可修改 [元素1,元素2,元素3,...] • 可以容纳多个元素 • 可以容纳不同类型的元素(混装) • 数据是有序存储的(有下标序号) • 允许重复数…

webpack面试问题

一、核心概念 Webpack的构建流程是什么? 答案: 初始化:读取配置,创建Compiler对象编译:从入口文件开始,递归分析依赖关系,生成依赖图模块处理:调用Loader转换模块(如babel-loader)输出:将处理后的模块组合成Chunk,生成最终文件Loader和Plugin的区别? Loader:文件…

uniapp-商城-66-shop(2-品牌信息显示,数据库读取的异步操作 放到vuex actions)

完成页面的显示,但是还需要进行修改,这里涉及到修改中的信息同步显示。也会涉及到数据的读取,修改和同步。 本文介绍了如何使用Vuex管理品牌数据,实现数据的同步显示和修改。主要内容包括:1.将获取品牌数据的异步操作封…

使用Pyinstaller打包python,全过程解析【2025最详细】

一、如何使用 Pyinstaller 打包 Python 程序 1.打开终端 右键点击文件夹空白处,选择 打开于 > 打开终端 2.安装 pyinstaller 在打开的终端中,输入命令【pip install pyinstaller】 使用 Python 包管理工具 pip 来安装 Pyinstaller。等待安装过程结…

GPU加速Kubernetes集群助力音视频转码与AI工作负载扩展

容器编排与GPU计算的结合,为追求性能优化的企业开辟了战略转型的新路径 基于GPU的托管Kubernetes集群不仅是技术选择,更是彻底改变企业处理高负载任务的战略部署方式。 随着人工智能和机器学习项目激增、实时数据处理需求的剧增,以及高性能媒…

LINUX 524 rsync+inotify 调试(问题1:指定端口无法同步/已通过;问题2:rsync.log文件中时间不显示/已显示)

怎么把java文件夹给传过去了 rsync inotify 监控代码实时传输调试 没看到日志 这里面有了 rsync -e"ssh -p 3712" -av /root/app/java/ code192.168.235.100:/home/code/backup/java_backup/ 文件夹后面的/要加上 [rootlocalhost java]# cat /var/log/rsync.log…

Python入门手册:条件判断

条件判断是编程中不可或缺的一部分,它允许程序根据不同的条件执行不同的代码块。Python提供了if、elif和else语句来实现条件判断。通过这些语句,你可以控制程序的流程,使其能够根据不同的情况做出相应的反应。本文将详细介绍Python中的条件判…

x-cmd install | cargo-selector:优雅管理 Rust 项目二进制与示例,开发体验升级

目录 功能亮点安装优势特点适用场景总结 还在为 Rust 项目中众多的二进制文件和示例而烦恼吗?cargo-selector 让你告别繁琐的命令行,轻松选择并运行目标程序! 功能亮点 交互式选择: 在终端中以交互方式浏览你的二进制文件和示例&…

Baklib知识中台高效实践路径

知识中台全周期构建路径 Baklib在构建知识中台全周期管理体系时,以知识价值转化为核心导向,通过三阶段递进实现闭环运作。在知识采集阶段,运用智能爬虫与API接口技术,聚合分散在业务系统、文档库及沟通工具中的碎片化知识资产&am…

mapbox进阶,手写放大镜功能

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.1 ☘️mapboxgl.Map style属性二、🍀手写放大镜功能1. ☘️实现思路2. ☘️…

康佳Java开发面试题及参考答案

面向对象三大特性是什么?请举例说明多态。 面向对象编程(OOP)的三大核心特性是封装、继承和多态。封装是将数据和操作数据的方法绑定在一起,并隐藏对象的内部实现细节;继承允许一个类继承另一个类的属性和方法&#x…

Spark集群架构解析:核心组件与Standalone、YARN模式深度对比(AM,Container,Driver,Executor)

一、核心组件定义与关系拆解 1. ApplicationMaster(AM) 定义:YARN 框架中的应用管理器,每个应用程序(如 Spark 作业)对应一个 AM。职责: 向 YARN 的 ResourceManager 申请资源(Con…

IS-IS报文

前言: IS-IS采用分层架构,所有Level-2和Level 1-2路由器构成了骨干区域,同一区域的Level-1路由器构成了普通区域IS-IS支持三种认证方式,分别是接口认证、区域认证、路由域认证IS-IS有四种报文类型,分别是IIH、CSNP、P…

【Flutter】多语言适配-波斯语RTL从右到左

前言 在多语言适配的时候,波斯语的显示是从右到左的,需要针对一些控件进行单独适配。 核心逻辑:根据语言动态设置 Directionality Widget build(BuildContext context) {final isRtl Localizations.localeOf(context).languageCode fa;r…

【VSCode】在远程服务器Linux 系统 实现 Anaconda 安装与下载

【远程服务器】Anaconda 安装与下载 一、 安装Anaconda【方式一】直接在远程服务器下载,通过 wget 命令:【方式二】在本地电脑下载,在同意 vscode上传到服务器二、配置环境变量 本文基于 VSCode 进行远程服务器的配置,VSCode 相关安装可参考下…

【深度学习-Day 17】神经网络的心脏:反向传播算法全解析

Langchain系列文章目录 01-玩转LangChain:从模型调用到Prompt模板与输出解析的完整指南 02-玩转 LangChain Memory 模块:四种记忆类型详解及应用场景全覆盖 03-全面掌握 LangChain:从核心链条构建到动态任务分配的实战指南 04-玩转 LangChai…

线性回归神经网络从0到1

1.线性方程和向量乘法 深度学习的基础就是从线性回归方程的理论进入的。简单的线性回归方程为 比如大家日常中买房子,价格受到哪些因素影响呢? 比如房龄、交通、是否是学区、有无配套超市、公园,这些基本是外部条件,内部条件诸如…

11|省下钱买显卡,如何利用开源模型节约成本?

不知道课程上到这里,你账户里免费的5美元的额度还剩下多少了?如果你尝试着完成我给的几个数据集里的思考题,相信这个额度应该是不太够用的。而ChatCompletion的接口,又需要传入大量的上下文信息,实际消耗的Token数量其…