从0开始学架构
李运华
资深技术专家
立即订阅
38968 人已学习
课程目录
已完结 59 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 照着做,你也能成为架构师!
免费
基础架构 (13讲)
01 | 架构到底是指什么?
02 | 架构设计的历史背景
03 | 架构设计的目的
04 | 复杂度来源:高性能
05 | 复杂度来源:高可用
06 | 复杂度来源:可扩展性
07 | 复杂度来源:低成本、安全、规模
08 | 架构设计三原则
09 | 架构设计原则案例
10 | 架构设计流程:识别复杂度
11 | 架构设计流程:设计备选方案
12 | 架构设计流程:评估和选择备选方案
13 | 架构设计流程:详细方案设计
高性能架构模式 (8讲)
14 | 高性能数据库集群:读写分离
15 | 高性能数据库集群:分库分表
16 | 高性能NoSQL
17 | 高性能缓存架构
18 | 单服务器高性能模式:PPC与TPC
19 | 单服务器高性能模式:Reactor与Proactor
20 | 高性能负载均衡:分类及架构
21 | 高性能负载均衡:算法
高可用架构模式 (10讲)
22 | 想成为架构师,你必须知道CAP理论
23 | 想成为架构师,你必须掌握的CAP细节
24 | FMEA方法,排除架构可用性隐患的利器
25 | 高可用存储架构:双机架构
26 | 高可用存储架构:集群和分区
27 | 如何设计计算高可用架构?
28 | 业务高可用的保障:异地多活架构
29 | 异地多活设计4大技巧
30 | 异地多活设计4步走
31 | 如何应对接口级的故障?
可扩展架构模式 (6讲)
32 | 可扩展架构的基本思想和模式
33 | 传统的可扩展架构模式:分层架构和SOA
34 | 深入理解微服务架构:银弹 or 焦油坑?
35 | 微服务架构最佳实践 - 方法篇
36 | 微服务架构最佳实践 - 基础设施篇
37 | 微内核架构详解
架构实战 (13讲)
38 | 架构师应该如何判断技术演进的方向?
39 | 互联网技术演进的模式
40 | 互联网架构模板:“存储层”技术
41 | 互联网架构模板:“开发层”和“服务层”技术
42 | 互联网架构模板:“网络层”技术
43 | 互联网架构模板:“用户层”和“业务层”技术
44 | 互联网架构模板:“平台”技术
45 | 架构重构内功心法第一式:有的放矢
46 | 架构重构内功心法第二式:合纵连横
47 | 架构重构内功心法第三式:运筹帷幄
48 | 再谈开源项目:如何选择、使用以及二次开发?
49 | 谈谈App架构的演进
50 | 架构实战:架构设计文档模板
特别放送 (7讲)
架构专栏特别放送 | “华仔,放学别走!”第1期
架构专栏特别放送 | “华仔,放学别走!” 第2期
如何高效地学习开源项目 | “华仔,放学别走!” 第3期
架构师成长之路 | “华仔,放学别走!” 第4期
架构师必读书单 | “华仔,放学别走!” 第5期
新书首发 | 《从零开始学架构》
致「从0开始学架构」专栏订阅用户
结束语 (1讲)
结束语 | 坚持,成就你的技术梦想
从0开始学架构
登录|注册

15 | 高性能数据库集群:分库分表

李运华 2018-05-31
上期我讲了“读写分离”,读写分离分散了数据库读写操作的压力,但没有分散存储压力,当数据量达到千万甚至上亿条的时候,单台数据库服务器的存储能力会成为系统的瓶颈,主要体现在这几个方面:
数据量太大,读写的性能会下降,即使有索引,索引也会变得很大,性能同样会下降。
数据文件会变得很大,数据库备份和恢复需要耗费很长时间。
数据文件越大,极端情况下丢失数据的风险越高(例如,机房火灾导致数据库主备机都发生故障)。
基于上述原因,单个数据库服务器存储的数据量不能太大,需要控制在一定的范围内。为了满足业务数据存储的需求,就需要将存储分散到多台数据库服务器上。
今天我来介绍常见的分散存储的方法“分库分表”,其中包括“分库”和“分表”两大类。

业务分库

业务分库指的是按照业务模块将数据分散到不同的数据库服务器。例如,一个简单的电商网站,包括用户、商品、订单三个业务模块,我们可以将用户数据、商品数据、订单数据分开放到三台不同的数据库服务器上,而不是将所有数据都放在一台数据库服务器上。
虽然业务分库能够分散存储和访问压力,但同时也带来了新的问题,接下来我进行详细分析。
1.join 操作问题
业务分库后,原本在同一个数据库中的表分散到不同数据库中,导致无法使用 SQL 的 join 查询。
例如:“查询购买了化妆品的用户中女性用户的列表”这个功能,虽然订单数据中有用户的 ID 信息,但是用户的性别数据在用户数据库中,如果在同一个库中,简单的 join 查询就能完成;但现在数据分散在两个不同的数据库中,无法做 join 查询,只能采取先从订单数据库中查询购买了化妆品的用户 ID 列表,然后再到用户数据库中查询这批用户 ID 中的女性用户列表,这样实现就比简单的 join 查询要复杂一些。
2. 事务问题
原本在同一个数据库中不同的表可以在同一个事务中修改,业务分库后,表分散到不同的数据库中,无法通过事务统一修改。虽然数据库厂商提供了一些分布式事务的解决方案(例如,MySQL 的 XA),但性能实在太低,与高性能存储的目标是相违背的。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《从0开始学架构》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(122)

  • 海盗
    分库,分表带来的问题都知道,能不能介绍些好的方便的改进方案?
    2018-05-31
    229
  • 明日之春
    应该是这些操作依次尝试
    1.做硬件优化,例如从机械硬盘改成使用固态硬盘,当然固态硬盘不适合服务器使用,只是举个例子
    2.先做数据库服务器的调优操作,例如增加索引,oracle有很多的参数调整;
    3.引入缓存技术,例如Redis,减少数据库压力
    4.程序与数据库表优化,重构,例如根据业务逻辑对程序逻辑做优化,减少不必要的查询;
    5.在这些操作都不能大幅度优化性能的情况下,不能满足将来的发展,再考虑分库分表,也要有预估性

    作者回复: 赞,写的很完善

    2018-05-31
    1
    92
  • 公号-代码荣耀
    分库分表,可以理解为是一种空间换时间的思路,同时分流了存储压力与读写压力。

    数据库性能不够时,首先应该想到是否可以通过改善硬件条件等垂直扩容手段;其次可引入读写分离、缓存/NoSQL、全文检索等手段;然后,单库单表的访问仍然存在性能瓶颈,可考虑分库分表,并且分库分表可以按照业务进行垂直拆分,接着进行水平拆分。

    我的问题是:当线上已经进行了分库分表的系统,需要进一步水平扩容时,有什么好的设计方案?

    作者回复: 没有太好的方案,要么一开始的分表方案就是按照id范围来设计的,要么就需要数据迁移

    2018-05-31
    23
  • kylexy_0817
    其实在同一个库里做数据拆分,无需分表吧?就例如MySQL,只需要对表做分区就可以了。分表的目的主要是为后面把表分到不同的数据库实例作准备?
    还有个疑问,文中提到,用户表的description等字段内容不是经常查到,所以做垂直划分可以提高查询性能,意思是,如果表中有内容较长的字段,查询的时候不查出来(不使用select *),也会有性能问题?
    最后,我觉得当单实例的访问量,已达到机器的60%承载能力,就要考虑分库,而具体如何拆分,则要分析访问量主要集中在哪些表。至于分表,主要依据还是单表的数据量和查询性能。

    作者回复: 关系数据库是行存储,即使不用那一列,也会从存储读取到内存

    2018-05-31
    1
    15
  • 李元霸
    老师,使用tidb方案来代替分库分表是否推荐?
    2018-06-01
    13
  • Snway
    我们是在设计初就考虑进去了,预估单表数据容量,再考虑未来三年的数据增长,不过现在反观这种做法,感觉有点过度设计,如当初一张用户表,分了127张,2个库,然而实际数据容量根本没这么多,顶多千万级别,不仅带来存储资源浪费,也给编码带来不少复杂度!所以我还是觉得得遵循演化原则,业务真正发展起来再考虑分库分表

    作者回复: 我们也这样做过,后来受不了了又缩表😂😂😂

    2018-05-31
    12
  • Kongk0ng
    如果使用hash进行分表的话,为什么大多方案推荐2的n次方作为表的总数,除了收缩容易还有什么好处吗?谢谢

    作者回复: 这个是hash函数实现的一个技巧,当计算hash值的时候,普通做法是取余操作,例如h%len,但如果len是2的N次方,通过位操作性能更高,计算方式为h & (len-1)

    2018-07-10
    11
  • 鲁伊李
    分库分表的痛点大家都知道,可否介绍下解决方案…

    作者回复: 没有很好的,要么中间件要么代码中间层,业务代码处理总是很麻烦的

    2018-05-31
    10
  • oddrock
    分库分表的实施前提:
    1. 数据库存在性能问题,且用加索引、慢查询优化、缓存和读写分离都无法彻底解决问题的时候
    2. 复杂查询对应的单表数据量级一般超过千万以上,或简单查询的单表数据量级一般超过5000万以上
    3. 对一致性要求不是特别高,只要求最终一致性。
    4. 用hadoop等大数据技术因为业务需求、技术成本、时间成本无法解决该问题

    其他:
    1. 业务对数据的操作主要集中在某些字段上,比较适合垂直分表
    2. 业务对数据的操作在整个表层面较均匀分布,适合水平分表
    2018-05-31
    10
  • 刘志刚
    我们公司业务增长比较平稳,已经经历了几个过程,
    1.先是最基础的主备,Oracle 扛了3年到15年,中间优化了几次硬件和数据库上的配置
    2.到16年左右开始扛不住了,数据量在3千万,但是订单表列太多,导致性能开始不理想,这个时候做了一把分区,性能勉强接受,继续扛着
    3.到17年之后做到18年开始做去O项目换MySQL了,顺带着分表和分区了,目前按业务,把一些非核心业务分出去其他库了,订单的库还没分,按照历史年表和热表来做的,做滚表实现的,热表数据差不多在1千万以内,现在性能还不错,历史数据用搜索聚合的,查询性能还不错!
    4.到后面如果业务再持续增长的话,估计就要拆订单库了
    总结一句话,分库分表要在业务需要之前一点,看数据量和业务特性!

    作者回复: 这样做没错,如果你们12年就开始分库分表,可能当时的方案也不一定适应后来的业务变化

    2018-06-06
    1
    9
  • 老师,针对mysql,发现如果字段有blob的字段,select 不写这个字段,和写这个字段,效率差异很大啊,这个是什么原因?一直没弄明白😊 ,谢谢

    作者回复: blob的字段是和行数据分开存储的,而且磁盘上并不是连续的,因此select blob字段会让磁盘进入随机IO模式

    2019-03-28
    6
  • 张国胜
    数据库优化顺序:
    1. 慢查询
    2. 根据业务特点,对表设计进行优化
    3. 业务逻辑问题
    4. 多用短查询
    5. 部分表加缓存
    这些做完再考虑分库分表吧?
    2018-06-29
    6
  • Jonah
    其实hash还有一个问题,就是当新增一张表时,怎么处理,比如说我原来是10张表,现在要增加到11张表,可以用一致性hash解决,但也会有数据迁移问题
    2018-05-31
    6
  • 文竹
    首先并不是数据库性能不够的时候就分库分表,提升数据库性能方式很多,若有其他能在单数据库操作的方式则毫不犹豫使用,因为使用分表有固有的复杂性(join操作,事务,order by等)。

    分库使用时机:
    1、业务不复杂,但整体数据量已影响了数据库的性能。
    2、业务复杂,需要分模块由不同开发团队负责开发,这个时候使用分库可以减少团队间交流。

    分表时机:
    1、单个数据表数据量太大,拖慢了SQL操作性能。

    作者回复: 分析正确

    2018-08-19
    4
  • 食指可爱多
    想请教老师一个设计问题,以电商平台交易系统为例,订单数据量非常大的时候也可以考虑水平分库分表。
    我的思考是针对消费者端订单表按用户ID哈希规则分表,这样所有对用户订单的查询条件全都带上用户ID,达到了数据分片的效果。
    但这时商家端需要对订单做管理,就很尴尬了。于是我想到,可以将订单数据做同步到另一个数据源,表结构一致只是按照商家ID进行哈希规则分表,所有商家端查询走此数据源,条件全部带上商家ID,也可以做到数据分片的效果。
    接下来问题又来了,系统还有一个平台的视角,这时貌似不好沿着这个思路继续了,恳请老师提点提点。

    作者回复: 淘宝的单元化改造就面临你说的问题,最后他们选择了买家纬度拆分,卖家纬度不拆分,详细可以搜网上的公开资料。

    2018-06-15
    4
  • 耶愿
    您好!请教一个问题,目前线上业务遇到一个问题,就是订单表需要在单库里分100张表,使用uid%100分的表,前端用户查数据没有问题,后台需要查天、周、月、年的统计信息,这个应该怎么实现?而且要求每行统计记录点击后可以看到该汇总信息下所有的订单记录,这个该怎么做?

    作者回复: 后台统计库不拆分,冗余一份线上数据,既可以应对复杂的统计需求,也不担心影响线上业务

    2018-12-30
    2
    3
  • allen.huang
    看了李老师的文章,真的是受益匪浅。
    我也想请教一个问题,就是我们的数据库是使用阿里云的RDS,现在是单实例,没做分库。所有业务都在同一个库上跑一共有1000个表,包括分表,也是库内分表,主要是这两年都在快速迭代业务,性能上欠考虑,到现在也遇到瓶颈,一到业务高峰,RDS就会报警,前几天做了硬件升级。暂时稳住了。

    我们想从数据库架构上要优化它,但一时也不好优化,不知老师有什么好的建议,让我参考

    作者回复: 先分表到不同数据库服务器,估计还能再撑一两年😄

    2018-08-14
    3
  • Interesting
    所以在分库分表前,一般的业务用优化sql就搞定了。不用分库分表这把牛刀。老师对sql优化有什么指导建议麽?

    作者回复: 高性能mysql,把explain的结果能完全看懂就很厉害了

    2018-06-15
    3
  • ASCE1885
    应该要对数据库做监控,在下面两种情况出现时,就要给出告警,架构师就要把分库分表提上日程:1)对数据库表做监控,根据具体业务场景,当表行数超过某个阈值时;2)对数据库查询等性能做监控,同样当时间超过某个阈值时。
    2018-05-31
    3
  • sea
    请问配置路由具体如何实现呢?
    2018-05-31
    3
收起评论
99+
返回
顶部