一、分库分表的背景

在数据爆炸的年代,单表数据达到千万级别,甚至过亿的量,都是很常见的情景。这时候再对数据库进行操作就是非常吃力的事情了,select个半天都出不来数据,这时候业务已经难以维系。不得已,分库分表提上日程,我们的目的很简单,减小数据库的压力,缩短表的操作时间。

二、如何进行数据切分

数据切分(Sharding),简单的来说,就是通过某种特定的条件,将存放在同一个数据库中的数据拆分存放到多个数据库(主机)中,从而达到分散单台机器负载的情况,即分库分表。根据数据切分规则的不同,主要有两种模式,

垂直切分(纵向切分),是对不同的表(或者Schema)进行切分,存储到不同的数据库(主机)之上。

水平切分(横向切分),是对同一个表中的数据进行切分,存储到不同的数据库(主机)之上。规则是根据表中数据的逻辑关系,按照某种条件拆分。

垂直切分

垂直切分,强调的是业务的拆分。一个数据库由多个表构成,每个表对应不同的业务,那么我们可以指按照业务的不同将表进行分类,并将其分布到不同的数据库上,这样就将数据分摊到了不同的库上面,做到专库专用。

举个例子,原数据库中有商品表、交易表、订单表,我们可以按照业务的不同进行垂直切分,把商品表、交易表、订单表分别拆分到商品库、交易库、订单库中去。

垂直拆分的优点:

拆分规则明确,拆分后业务清晰;系统之间进行整合或扩展变的容易;数据维护变的容易;按照成本、应用的等级、应用的类型等将表放到不同的机器上,便于管理。垂直拆分的缺点:

部分业务表无法关联(Join),只能通过接口方式解决,提高了系统的复杂度;受每种业务的不同限制,存在单库性能瓶颈,不易进行数据扩展和提升性能;分布式事务处理复杂。

水平切分(重点)

水平切分,强调的是技术层面的拆分。她是将其按照一定的逻辑规则将一个表中的数据分散到多个库中,在每个表中包含一部分数据,所有表加起来就是全量的数据。简单来说,我们可以将对数据的水平切分理解为按照数据行进行切分,就是将表中的某些行切分到一个数据库表中,而将其他行切分到其他数据库表中。

比如,原数据库有一张交易记录表,数据量非常大,其中表中有个地区字段,经过深入考证符合水平拆分的条件。我们就按照这个字段进行水平拆分,按不同的地区(北京、上海、江苏、浙江、广东等)拆分成10个库。

高峰时段同时有100万次请求,如果是单库,数据库就会承受100万次的请求压力,拆分成100个表分别放入10个库中,每个表进行1万次请求,则每个数据库会承受10万次的请求压力,这样压力就减少了很多,并且是成倍减少的。

水平拆分的优点:

拆分规则抽象好,join 操作基本可以数据库做;不存在单库大数据,高并发的性能瓶颈;应用端改造较少;提高了系统的稳定性跟负载能力。水平拆分的缺点:

拆分规则不好抽象;分片事务一致性难以解决;数据多次扩展难度大;跨库 join 性能较差。

三、数据切分导致的一些问题

上面我们也讲了两种数据切分方式的优点和缺点,但是他们有些共同的缺点,

分布式事务的问题;跨节点 Join 的问题;跨节点合并排序分页的问题;多数据源管理问题。一般来说,业务上存在着复杂 join 的场景是很难切分的,往往业务独立的易于切分。如何切分,我们遵循如下原则,

能不切分尽量不要切分;如果要切分一定要选择合适的切分规则,提前规划好;数据切分尽量通过数据冗余或表分组来降低跨库 Join 的可能;由于数据库中间件对数据 Join 实现的优劣难以把握,而且实现高性能难度极大,业务读取尽量少使用多表 Join。

四、数据源管理的问题

分库分表之后,数据源的管理是系统实现的关键。

系统应用层面系统应用代码层面,目前主要有两种思路,

客户端模式,也就是在每个应用程序模块中配置管理自己需要的一个(或者多个)数据源,直接访问各个数据库,在模块内完成数据的整合。比如可以依赖spring注解实现。中间代理模式,统一管理所有的数据源,后端数据库集群对前端应用程序透明。考虑到系统的复杂性和扩展性,建议第二种中间代理模式。虽然短期内需要付出的成本可能会相对更大一些,但是对整个系统的扩展性来说,是非常实用的。

2. 中间件层面

上面的系统层面,需要的代码实现比较复杂,中间件是在数据集群前面加一层代理,比如Cobar、Mycat等数据库中间件。实用数据库中间件,对代码层面的实现是很大的解放。

五、分布式事务的解决方案

分库分表导致的最突出的问题就是分布式事务的处理。大家如果有兴趣可以参考下之前的文章互联网架构下的分布式技术面试要点概览中的分布式事务部分,后面如果有时间,可以单独再探讨下。

超实用的mysql分库分表策略,轻松解决亿级数据问题的更多相关文章

  1. Java互联网架构-Mysql分库分表订单生成系统实战分析

    概述 分库分表的必要性 首先我们来了解一下为什么要做分库分表.在我们的业务(web应用)中,关系型数据库本身比较容易成为系统性能瓶颈,单机存储容量.连接数.处理能力等都很有限,数据库本身的“有状态性” ...

  2. 【分库、分表】MySQL分库分表方案

    一.Mysql分库分表方案 1.为什么要分表: 当一张表的数据达到几千万时,你查询一次所花的时间会变多,如果有联合查询的话,我想有可能会死在那儿了.分表的目的就在于此,减小数据库的负担,缩短查询时间. ...

  3. mysql分库分表(二)

    mysql分库分表 参考: https://www.cnblogs.com/dongruiha/p/6727783.html https://www.cnblogs.com/oldUncle/p/64 ...

  4. mysql分库分表(一)

    mysql分库分表 参考: https://blog.csdn.net/xlgen157387/article/details/53976153 https://blog.csdn.net/cleve ...

  5. 《MyCat分库分表策略详解》

    在我们的项目发展到一定阶段之后,随着数据量的增大,分库分表就变成了一件非常自然的事情.常见的分库分表方式有两种:客户端模式和服务器模式,这两种的典型代表有sharding-jdbc和MyCat.所谓的 ...

  6. Mysql分库分表方案

    Mysql分库分表方案 1.为什么要分表: 当一张表的数据达到几千万时,你查询一次所花的时间会变多,如果有联合查询的话,我想有可能会死在那儿了.分表的目的就在于此,减小数据库的负担,缩短查询时间. m ...

  7. MYSQL分库分表和不停机更改表结构

    在MYSQL分库分表中我们一般是基于数据量比较大的时间对mysql数据库一种优化的做法,下面我简单的介绍一下mysql分表与分库的简单做法. .分库分表 很明显,一个主表(也就是很重要的表,例如用户表 ...

  8. MySQL分库分表备份脚本

    MySQL分库备份脚本 #脚本详细内容 [root@db02 scripts]# cat /server/scripts/Store_backup.sh #!/bin/sh MYUSER=root M ...

  9. MySQL分库分表浅谈

    一.分库分表类型 1.单库单表 所有数据都放在一个库,一张表. 2.单库多表 数据在一个库,单表水平切分多张表. 3.多库多表 数据库水平切分,表也水平切分. 二.分库分表查询 通过分库分表规则查找到 ...

随机推荐

  1. jumper-server-资源管理

    https://cloud.tencent.com/developer/article/1460469 此链接是百度搜索的 , 比较详细 https://www.cnblogs.com/zsl-fin ...

  2. Mybatis使用入门,这一篇就够了

    mybatis中,封装了一个sqlsession 对象(里面封装有connection对象),由此对象来对数据库进行CRUD操作. 运行流程 mybatis有一个配置的xml,用于配置数据源.映射Ma ...

  3. 大文件分割、命令脚本 - Python

    日志文件分割.命名 工作中经常会收到测试同学.客户同学提供的日志文件,其中不乏几百M一G的也都有,毕竟压测一晚上产生的日志量还是很可观的,xDxD,因此不可避免的需要对日志进行分割,通常定位问题需要针 ...

  4. 数位DP 详解

    序 天堂在左,战士向右 引言 数位DP在竞赛中的出现几率极低,但是如果不会数位DP,一旦考到就只能暴力骗分. 以下是数位DP详解,涉及到的例题有: [HDU2089]不要62 [HDU3652]B-n ...

  5. JVM调优—Jstack

    Java命令学习系列(二)——Jstack   jstack是java虚拟机自带的一种堆栈跟踪工具. 功能 jstack用于生成java虚拟机当前时刻的线程快照.线程快照是当前java虚拟机内每一条线 ...

  6. 坑爹的tp-link管理密码设置

     tp-link管理密码最长14位,我设置了15位的密码,突然等不上去,上网发现不少人也有类似情况,后来看到一个文章说tp-link管理密码,可以设置6-15,于是抱着试一试的态度,输入我设置密码的前 ...

  7. Spring Environment的加载

     这节介绍environment,默认环境变量的加载以及初始化.  之前在介绍spring启动过程讲到,第一步进行环境准备时就会初始化一个StandardEnvironment.下图为Environm ...

  8. Java静态代理&动态代理&Cglib代理详解

    一.静态代理 根据被代理的类的时机的不同,如果在编译阶段就能确定下来的被代理的类是哪一个,那么,就可以使用静态代理的方式. 申明一个接口: /** * @author jiaqing.xu@hand- ...

  9. Spring Cloud Gateway 使用

    简介 Spring Cloud Gateway是Spring Cloud官方推出的网关框架,网关作为流量入口,在微服务系统中有着十分重要的作用,常用功能包括:鉴权.路由转发.熔断.限流等. Sprin ...

  10. .Net Core 商城微服务项目系列(六):搭建自己的Nuget包服务器

    当我们使用微服务架构之后,紧接而来的问题便是服务之间的程序集引用问题,可能没接触过的同学不太理解这句话,都已经微服务化了为什么还要互相引用程序集,当然可以不引用.但是我们会有这样一种情况,我们的每个接 ...