MySQL - 分库分表

分库分表原因

前文介绍MySQL主从模式,将读写分离以提高性能。 主从模式对于写少读多的场景确实非常大的优势,但是总会写操作达到瓶颈的时候,导致性能提不上去。

总的来说就是数据库出现性能瓶颈,对外表现有几个方面:
大量请求阻塞:
在高并发场景下,大量请求都需要操作数据库,导致连接数不够了,请求处于阻塞状态。

SQL 操作变慢:
如果数据库中存在一张上亿数据量的表,一条 SQL 没有命中索引会全表扫描,这个查询耗时会非常久。

存储出现问题:
业务量剧增,单库数据量越来越大,给存储造成巨大压力。

如果系统处于高速发展阶段,拿商城系统来说,一天下单量可能几十万,那数据库中的订单表增长就特别快,增长到一定阶段数据库查询效率就会出现明显下降。

这时候可以在设计上进行解决:

  • 采用分库分表的形式,对于业务数据比较大的数据库可以采用分表,使得数据表的存储的数据量达到一个合理的状态。
  • 也可以采用分库,按照业务进行划分,这样对于单点的写,就会分成多点的写,性能方面也就会大大提高。

分库分表方案更多的是对关系型数据库数据存储和访问机制的一种补充,而不是颠覆。

分库分表拆分思路

什么时候进行分库

MySQL 的高可用架构大多都是一主多从,所有写入操作都发生在 Master 上,随着业务的增长,数据量的增加,很多接口响应时间变得很长,经常出现 Timeout,而且通过升级 MySQL 实例配置已经无法解决问题了,这时候就要分库。

什么时候进行分表

分表的应用场景是单表数据量增长速度过快,影响了业务接口的响应时间,但是 MySQL 实例的负载并不高,这时候只需要分表,不需要分库(拆分实例)。

垂直拆分

垂直分库

垂直分库是按业务分库,例如一个电商系统shop库按业务分有订单表,会员表,商品表,按业务拆分后,响应的shop库被拆分到三个RDS实例中,数据库写入能力提升,服务的接口响应时间变短,提供稳定性。

垂直分表

以用户系统为例,将user表按字段拆分为user_base 和 user_info表,两个表通过userid进行联系。
例如登录系统只需要userid,username和password,如果不分表,则每次登录都需要把整张user表加载进内存进行判断,sex,address,age和nick_name这些无用到的字段也会占内存。

垂直拆分特点

基于表或字段划分,表结构不同

垂直拆分优点

  • 拆分后业务清晰,方便针对业务进行优化(专库专用按业务拆分);
  • 数据维护简单,按业务不同将业务放到不同机器上。

垂直拆分缺点

跨库关联查询

在单库未拆分表之前,我们可以很方便使用 join 操作关联多张表查询数据,但是经过分库分表后两张表可能都不在一个数据库中,如何使用 join 呢?

有几种方案可以解决:

  • 字段冗余:把需要关联的字段放入主表中,避免 join 操作;
  • 数据抽象:通过ETL等将数据汇合聚集,生成新的表;
  • 全局表:比如一些基础表可以在每个数据库中都放一份;
  • 应用层组装:将基础数据查出来,通过应用程序计算组装;

水平拆分

业务量比较大的时候,即使做了垂直拆分,依然会存在以下问题:

  • 如果单表的数据量大,读写压力依然很大;
  • 受某种业务来决定,或者被限制。 也就是说一个业务往往会影响到数据库的瓶颈(性能问题)。例如电商系统订单库的读写会远远大于其他功能;

水平分库


根据一定的逻辑,例如将userid取模,将数据放到不同的库上。

举个例子,交易数据库的订单表 orders 有2亿多数据,RDS 实例遇到了写入瓶颈,普通的 insert 都需要50ms,时常也会收到 CPU 使用率告警,这时就要考虑分库了。根据业务量增长趋势,计划扩容一台同配置的RDS实例,将订单表 orders 拆分20个子表,每个 RDS 实例10个。
这样解决了订单表 orders 太大的问题,查询的时候要先通过分区键 user_id 定位是哪个 RDS 实例,再定位到具体的子表,然后做 DML操作,问题是代码改造的工作量大,而且服务调用链路变长了,对系统的稳定性有一定的影响。其实已经有些数据库中间件实现了分库分表的功能,例如常见的 mycat,阿里云的 DRDS 等。

水平分表


根据一定的逻辑,例如将userid取模,将数据放到不同的表上。

水平拆分的方式也很多,除了上面说的按照 id 拆表,还可以按照时间维度取拆分,比如订单表,可以按每日、每月等进行拆分。

  • 每日表:只存储当天的数据。
  • 每月表:可以起一个定时任务将前一天的数据全部迁移到当月表。
  • 历史表:同样可以用定时任务把时间超过 30 天的数据迁移到 history表。

垂直拆分优点

基于数据划分,表结构相同,数据不同。

水平拆分优点

  • 单库(表)的数据保持在一定的量(减少),提高了系统的稳定性和负载能力;
  • 切分表的结构相同,程序改造较少。

水平拆分缺点

  • 数据扩容有难度,维护量大
    例如上面会员库一分为二,根据userid % 2将数据分库或分表存储存储,但随着业务量快速提升,两个库已经不够用,需要分成更多,例如10个,那么分库分表逻辑也会改成 userid % 10,原有的数据在新的逻辑后需要进行数据迁移。
  • 拆分规则很难抽象出来
  • 分布式事务的一致性问题,部分业务无法关联join,只能通过程序接口调用。

汇总分库分表带来的问题

  • 跨库关联查询,上面提到解决办法;
  • 分布式事务,单数据库可以用本地事务搞定,使用多数据库就只能通过分布式事务解决了。
    常用解决方案有:基于可靠消息(MQ)的解决方案、两阶段事务提交、柔性事务等。
  • 排序、分页、函数计算问题
    在使用 SQL 时 order by, limit 等关键字需要特殊处理,一般来说采用分片的思路:
    先在每个分片上执行相应的函数,然后将各个分片的结果集进行汇总和再次计算,最终得到结果。
  • 分布式 ID
    如果使用 Mysql 数据库在单库单表可以使用 id 自增作为主键,分库分表了之后就不行了,会出现id 重复。
    常用的分布式 ID 解决方案有:
    UUID
    基于数据库自增单独维护一张 ID表
    号段模式
    Redis 缓存
    雪花算法(Snowflake)
    百度uid-generator
    美团Leaf
    滴滴Tinyid
  • 多数据源
    分库分表之后可能会面临从多个数据库或多个子表中获取数据,一般的解决思路有:客户端适配和代理层适配。
    业界常用的中间件有:
    shardingsphere(前身 sharding-jdbc)
    Mycat

分库分表现成方案

  • 代码改造,入数据库中间件mycat,sharding-sphere;
  • 分布式数据库,实际业务中使用比较多的有 PingCAP TiDB,阿里云 DRDS,可以优先使用分布式数据库方案,虽然成本会有所增加,但对应用程序没有侵入性,同时也可以比较好的支撑业务增长和系统快速迭代。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,992评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,212评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,535评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,197评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,310评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,383评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,409评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,191评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,621评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,910评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,084评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,763评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,403评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,083评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,318评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,946评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,967评论 2 351

推荐阅读更多精彩内容