分库分表详解

分库分表概述

分库分表是数据库架构设计中的一种常见策略,尤其是在面对大规模数据和高并发场景时。这种策略通过将数据分散存储在多个数据库和表中,来提高系统的性能和可扩展性。
分库分表是为了解决由于数据量过大而导致数据库性能降低的问题,通过将原来独立的数据库拆分成若干数据库组成,将数据大表拆分成若干数据表组成,使得单一数据库、单一数据表的数据量变小,从而达到提升数据库性能的目的。
分库分表是提升数据库性能和扩展性的重要策略,但同时也带来了设计和维护上的复杂性。在具体实施时,需要综合考虑业务需求、数据特性和系统架构,选择最合适的分库分表方案。同时,可以借助分布式中间件来简化实现和管理。

分库分表详解

分库
分库是指将数据分散到多个数据库中,通常有以下几种方式:
垂直分库(Vertical Partitioning):
将数据库按照功能模块或业务划分成多个数据库。例如,一个电商系统可以将用户数据、订单数据、商品数据分别存储在不同的数据库中。
优点:可以减少单个数据库的压力,模块之间相对独立,易于管理和维护。
缺点:跨库查询复杂,事务管理难度增加。
水平分库(Horizontal Partitioning):
将相同结构的数据按照某种规则(如ID范围、哈希值等)分布到多个数据库中。例如,将用户数据按照用户ID进行拆分,ID为1-1000的用户存储在数据库A,ID为1001-2000的用户存储在数据库B。
优点:单个数据库的压力显著降低,易于扩展。
缺点:分片规则设计复杂,跨库查询和事务处理复杂度增加。

分表
分表是指将一个大表拆分成多个小表存储,主要有以下几种方式:
垂直分表:
将表的列进行拆分,不同的列存储在不同的表中。例如,将用户表的基本信息(ID、姓名、邮箱)和详细信息(地址、电话、年龄)分开存储在两个表中。
优点:减少表的宽度,提高查询效率。
缺点:需要进行表的联合查询,复杂度增加。
水平分表:
将表的数据行进行拆分,不同的行存储在不同的表中。例如,将订单表按照订单创建时间进行拆分,2023年的订单存储在orders_2023表中,2024年的订单存储在orders_2024表中。
优点:减少单个表的数据量,提高查询效率。
缺点:需要根据拆分规则进行数据的路由,跨表查询和统计较为复杂。

分库分表方案
水平分库:以字段为依据,按照一定策略(hash、range 等),将一个库中数据拆分到多个库中。
水平分表:以字段为依据,按照一定策略(hash、range 等),将一个表中数据拆分到多个表中。
垂直分库:以表为依据,按照业务归属不同,将不同表拆分到不同库中。
垂直分表:以字段为依据,按照字段活跃性,将表中字段拆到不同表

分库分表的策略

在实际应用中,分库和分表可以结合使用,具体的策略和方案应根据业务需求和数据特点来设计:

  1. 选择合适的分片键:
    分片键是决定数据如何分布的关键。通常选择数据的唯一标识(如用户ID、订单ID)作为分片键。
    分片键应满足均匀分布的要求,避免数据倾斜。
  2. 路由策略:
    数据存储时需要确定其存储的位置,通常通过哈希算法、取模算法等来实现路由。查询时需要根据分片键确定数据所在的库和表。
  3. 事务处理:
    分布式事务管理较为复杂,常用的解决方案包括两阶段提交(2PC)、三阶段提交(3PC)、基于消息队列的最终一致性等。
  4. 分布式中间件
    使用分布式中间件(如Sharding-JDBC、MyCAT等)可以简化分库分表的实现和管理,中间件负责数据的分片、路由和聚合查询。
  5. 数据迁移和扩展
    系统上线后,可能需要进行数据的迁移和扩展,如增加新的数据库和表。这时需要考虑数据迁移策略、数据一致性和系统的停机时间等问题。

分库分表的注意事项

  1. 数据一致性和完整性:在分库分表的过程中,需要确保数据的一致性和完整性,避免出现数据不一致或数据丢失的情况。
  2. 数据安全和可靠性:特别是在高并发访问的情况下,需要采取有效的安全措施来保护数据的安全性和可靠性。
  3. 跨分片事务一致性:当更新内容同时分布在不同库中时,可能会带来跨库事务问题,需要使用分布式事务处理方案。
  4. 跨节点关联查询:分库分表后,数据可能分布在不同的节点上,此时跨节点的关联查询(如JOIN)性能可能会较差,需要尽量避免或优化。
    分库分表的优点
  5. 提升性能:通过分散数据存储和查询负载,提高数据库性能和吞吐量。
  6. 扩展性:可以更容易地扩展数据库系统,以应对不断增长的数据量和查询需求。
  7. 灵活性:可以根据业务需求和数据特点灵活选择分库分表的方式和策略。

常用的分库分表中间件

常用分库分表中间件:
sharding-jdbc(当当)
Mycat
TDDL(淘宝)
Oceanus(58 同城数据库中间件)
vitess(谷歌开发数据库中间件)
Atlas(Qihoo 360)

sharding-jdbc 目前是基于 jdbc 驱动,无需额外的 proxy,因此也无需关注proxy 本身的高可用。
Mycat 是基于 Proxy,它复写了 MySQL 协议,将 Mycat Server 伪装成一个MySQL 数据库,而 Sharding-JDBC 是基于 JDBC 接口的扩展,是以 jar 包的形式提供轻量级服务的
在大规模数据库系统的设计和实现过程中,分库分表是提升系统性能和扩展性的常见策略。为了简化分库分表的实现和管理,业界广泛使用了一些分布式中间件。这些中间件在数据的分片、路由、聚合查询等方面提供了丰富的功能,以下是几种常用的分库分表中间件:

ShardingSphere
ShardingSphere(原名Sharding-JDBC)是Apache基金会的顶级项目之一,主要提供数据库的水平分片、读写分离、分布式事务等功能。
特性:
水平分片:支持按范围、哈希等规则进行分片。
读写分离:自动将读请求路由到从库,提高查询性能。
分布式事务:支持柔性事务(TCC、最大努力通知、最终一致性)和强一致性事务(XA)。
弹性伸缩:支持动态添加或删除分片。
优点:
透明化:对应用程序透明,支持JDBC和Proxy两种接入方式。
高可扩展性:可以与现有的数据库无缝集成,支持多种数据库类型。

MyCAT
MyCAT是一个基于Java开发的开源分布式数据库中间件,具有强大的分布式计算能力,常用于构建大规模、高并发的互联网系统。
特性:
分库分表:支持水平拆分和垂直拆分。
读写分离:支持多种读写分离策略。
分布式事务:支持XA事务和柔性事务。
高可用性:支持故障转移和负载均衡。
优点:
灵活性:配置灵活,支持多种分片规则和路由策略。
性能优异:具备良好的并发处理能力,适用于大规模数据场景。

Vitess
Vitess是一个由YouTube开发并开源的分布式数据库解决方案,专为处理大规模MySQL数据库集群而设计。
特性:
自动分片:支持数据的水平分片和自动分片管理。
读写分离:支持多主多从架构,自动路由读写请求。
容错性:提供自动故障转移和恢复功能。
高可用性:支持滚动升级和在线扩展。
优点:
云原生支持:适用于云环境,支持Kubernetes部署。
兼容性:与MySQL高度兼容,易于迁移和管理。

TiDB
TiDB是PingCAP开发的开源分布式NewSQL数据库,融合了传统关系型数据库和NoSQL数据库的优点,具有良好的扩展性和强一致性。
● 特性:
分布式架构:原生支持水平扩展和高可用性。
强一致性:采用Raft协议保证数据的一致性。
SQL兼容性:兼容MySQL协议和生态,支持复杂查询和事务。
在线弹性伸缩:支持在线扩展和收缩集群规模。
优点:
性能优异:在处理大规模数据和高并发场景下表现出色。
易于运维:提供完善的监控和管理工具,简化集群运维。

Citus

Citus是基于PostgreSQL的分布式数据库扩展,专为扩展和高性能设计,能够处理大规模OLTP和实时分析工作负载。
特性:
数据分片:自动分片数据到多个节点,实现高并发处理。
实时分析:支持高效的实时数据分析。
兼容性:完全兼容PostgreSQL,支持现有应用无缝迁移。
优点:
扩展性强:通过添加节点来扩展存储和计算能力。
灵活查询:支持复杂的SQL查询,适用于多种应用场景。
综上所述,这些分库分表中间件各具特点,适用于不同的业务需求和技术环境。选择合适的中间件需要综合考虑系统的性能要求、数据量规模、运维复杂度以及团队的技术栈和经验。

mysql单表达到多少数据量需要分库分表

理论上确实5000万以上才会性能急剧下降,有些db架构师也是这么说过。但是实际情况却不⼀定,按照⼀部分的真实项⽬,
500万以上就会开始慢了。当然,这个跟具体的业务逻辑、响应要求、表设计也是很有关系的。表字段全是int类型的,可以到1000万以上
再优化。到了300万,是时候作好优化的技术储备了。但是不⼀定分表,可以通过缓存、搜索引擎等技术也都可以提⾼性能。

单表数据量超过1000万或者超过2G
阿里的开发手册中有条建议,单表行数超500万行或者单表容量超过2GB,就推荐分库分表
单表行数超过 500 万行或者单表容量超过 2GB,才推荐进行分库分表。
说明:如果预计三年后的数据量根本达不到这个级别,请不要在创建表时就分库分表
数据量太大的话,SQL的查询就会变慢。如果一个查询SQL没命中索引,千百万数据量级别的表可能会拖垮整个数据库。
即使SQL命中了索引,如果表的数据量超过一千万的话,查询也是会明显变慢的。这是因为索引一般是B+树结构,数据千万级别的话,B+树的高度会增高,查询就变慢啦

数据库分库分表缺点

1.事务问题,已经不可以用本地事务了,需要用分布式事务。
2. 跨节点 Join 问题:解决这一问题可以分两次查询实现
3. 跨节点count,order by,group by 以及聚合函数问题:分别在各个节点上得到
结果后在应用程序端进行合并。
4. ID 问题:数据库被切分后,不能再依赖数据库自身主键生成机制啦,最简单可以考虑 UUID
5. 跨分片排序分页问题(后台加大 pagesize 处理?)

分表要停服吗,不停服怎么做

不用。不停服的时候,应该怎么做呢,分五个步骤:

  1. 编写代理层,加个开关(控制访问新DAO 还老 DAO,或者都访问),灰度期间,还访问老DAO。
  2. 发版全量后,开启双写,既在旧表新增和修改,也在新表新增和修改。日志或者临时表记下新表 ID 起始值,旧表中小于这个值数据就存量数据,这批数据就要迁移。
  3. 通过脚本旧表存量数据写入新表。
  4. 停读旧表改读新表,此时新表已经承载了所有读写业务,但这时候不要立刻停写旧表,需要保持双写一段时间。
  5. 当读写新表一段时间之后,如果没有业务问题,就可以停写旧表啦

有时候不推荐使用分库分表的原因

有时候不推荐使用分库分表的原因主要有以下几点:

  1. 架构设计难度大:分库分表需要谨慎选择分布键,并且需要考虑跨库查询、事务处理等问题,这需要仔细的架构设计和规划。如果设计不当,可能导致系统性能下降或数据一致性问题。
  2. 功能缺失和改造成本高:由于各个数据节点各自为政,分库分表模式下的SQL限制多、功能缺失多,这可能导致应用需要付出巨大的改造成本。
  3. 跨库查询性能差:在分库分表系统中,跨库查询需要将数据收到中间件节点再JOIN,这可能导致性能下降,甚至打爆中间节点。
  4. 分布式事务性能差:分库分表系统通常不支持分布式事务,或者性能较差。这可能导致业务受到影响。
  5. 运维难度大:分库分表系统需要额外的运维和管理成本,包括备份、恢复、监控等。
  6. 扩展性限制:分库分表系统的扩展性受到限制,需要预先分配一定的存储空间和计算资源。如果数据量增长超过预期,可能会导致存储空间不足或计算资源不够用的情况。
    综上所述,虽然分库分表可以解决一些问题,但同时也带来了很多额外的复杂性和维护成本。因此,在选择是否使用分库分表时,需要综合考虑系统的实际情况和需求,权衡利弊后做出决策。如果数据量还没有达到一定量级,或者对应用查询等性能没有明显影响,可以考虑不分库分表。

替代解决方案

除了分库分表,还有其他一些解决方案可以处理大量数据和提升数据库性能。

  1. 表设计的优化:在设计表的时候,可以考虑性能问题。例如字段尽量避免NULL,时间类型尽量使用TIMESTAMP,单表的字段不宜过多等等。
  2. 索引的优化:索引不是越多越好,也不是所有的字段都适合建立索引,使用多列索引的时候,要注意SQL中的条件顺序等。
  3. SQL的优化:查询尽量用到索引,避免错误的写法导致索引失效,避免使用select *查询出来所有的列,拆分复杂的SQL语句,查询使用分页等等。
  4. 分区:分区表是独立的逻辑表,底层由多个物理表组成,这些对用户来说是透明的。如果按照分区字段查询数据的话,就会在某一张分区表内查询,速度回比较快。分区字段的选择,需要根据实际业务来。
  5. 读写分离:就是将数据库的读写操作分开,比如让主服务器读,从服务器去做写操作,或者让性能比较好的服务器去做写操作,性能不太好的服务器做读操作。具体如何去读写分离,要看如何去分了。
  6. 静态缓存:分为本地缓存和服务缓存,本地缓存就是将数据加载到本地,服务缓存就是比如使用Redis这样的k-v数据库进行存储热点数据。但是使用服务缓存也有缺点,最常见的问题就是,“击穿”,就是假如缓存都失效了,这时候并发请求都去访问db,此时可能造成服务器挂掉。
    综上所述,除了分库分表外,还有很多其他的解决方案可以处理大量数据和提升数据库性能。需要根据实际情况和需求来选择最合适的方案。
  • 22
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

思静语

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值