V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
LoremIpSum
V2EX  ›  程序员

阿里巴巴技术手册:单表行数超过 500 万行或者单表容量超过 2GB,才推荐进行分库分表的理论依据?

  •  2
     
  •   LoremIpSum · 2022-10-16 03:10:50 +08:00 · 7085 次点击
    这是一个创建于 755 天前的主题,其中的信息可能已经有所发展或是发生改变。

    不少技术文章都直接引用了这个观点,但没说为什么?有大佬解释下这个理论依据吗?

    48 条回复    2022-10-17 15:01:13 +08:00
    zhilincom
        1
    zhilincom  
       2022-10-16 05:02:49 +08:00
    听说 MySQL 单表超过 1000 万行性能会急剧下降。
    akira
        2
    akira  
       2022-10-16 05:39:58 +08:00
    这应该是个经验数字,不一定绝对对。 但是如果你只有几十 几百万的数据,就大概率是直接用就好,不需要考虑那么多事情
    dayeye2006199
        3
    dayeye2006199  
       2022-10-16 07:11:17 +08:00 via Android
    可能和 b 树的深度,和 Page 的大小有关
    wxf666
        4
    wxf666  
       2022-10-16 07:18:44 +08:00   ❤️ 1
    反正 20 天前,在一个 [帖子]( https://www.v2ex.com/t/882773 ) 里,有很多人反映,MySQL 单表存 1~2 亿(#11 楼 #16 #18 #19 #21 #35 )、4 亿(#27 )、10 亿(#36 )、20 亿(#28 )都没问题,查询也很快(< 10 ms ,#27 #28 )
    wxf666
        5
    wxf666  
       2022-10-16 07:20:33 +08:00
    我在那个帖子里的 3 楼,也问了个类似的问题,也给出一点猜测(但没人理我。。)
    chendy
        6
    chendy  
       2022-10-16 07:29:12 +08:00   ❤️ 4
    1. 经验数字
    2. 阿里(也许)自己有足够完善的组建处理分库分表
    3. 阿里(也许)可以通过传播这个数字,卖更多的数据库或者其他服务
    liuzhaowei55
        7
    liuzhaowei55  
       2022-10-16 07:33:24 +08:00 via iPhone   ❤️ 1
    备份、恢复数据的难度,太大了也是灾难
    GTim
        8
    GTim  
       2022-10-16 08:14:19 +08:00
    很多业务,估计一个小时就要分一次表了
    makelove
        9
    makelove  
       2022-10-16 08:38:33 +08:00
    才 500 万,哪怕机械硬盘时代都毫无问题,更别提现在的高速 SSD
    jorneyr
        10
    jorneyr  
       2022-10-16 08:55:03 +08:00
    分库分表没那么好玩,应用端需要精心设计,不能像单库那样随心所欲的写 SQL 。
    Maboroshii
        11
    Maboroshii  
       2022-10-16 08:56:04 +08:00 via Android
    之前有人说是 2000w 行,查了一下是索引数深度的效率相关
    sadfQED2
        12
    sadfQED2  
       2022-10-16 08:58:27 +08:00 via Android
    @jorneyr 可以加一个 db proxy 层,这一层屏蔽分表分库细节,你代码里面依然可以当单表使用,随心所欲的写 sql 。
    bthulu
        13
    bthulu  
       2022-10-16 09:10:02 +08:00   ❤️ 1
    那是说的机械硬盘经验值, 还是偏保守的那种.
    现在的 M.2 SSD, 三星 980PRO, 随机 4k 读写速度是普通机械的 500 倍往上, 同样的, 500 万*500=25 亿, 也就是说, 保守点估计 25 亿行数据再考虑分库分表, 胆子大一点的, 100-1000 亿行数据以上再去考虑这个问题.
    jorneyr
        14
    jorneyr  
       2022-10-16 09:11:32 +08:00
    @sadfQED2 分布式数据库一般都有 DB Proxy 的,但是 SQL 落到多个库,数据量大的时候,Proxy 每个节点都取数据来处理的时候,一是慢,二是容易内存超量,例如有 1024 个节点,要查询 1000 行,不巧写的 SQL 没有分片键,那么就要去这 1024 个节点上各自都获取 1000 行数据,Proxy 得到 1024 * 1000 行数据进行 Merge Sort ,然后再判断一次取出合适的 1000 行。

    最直观的是使用 Sharding Sphere ,或者看看 TDSql 等的设计文档,没那么自由。
    Biggoldfish
        15
    Biggoldfish  
       2022-10-16 09:15:11 +08:00
    一张 table 2GB 就性能下降到不可接受了,怕是在用十年前的 DB 吧
    cooper
        16
    cooper  
       2022-10-16 09:17:11 +08:00   ❤️ 7
    lmshl
        17
    lmshl  
       2022-10-16 11:12:45 +08:00
    老民科八股文了,遗毒万年
    生产环境近两亿行的主表,0.2ms 查询时间,分库分表?分个 J2
    lmshl
        18
    lmshl  
       2022-10-16 11:19:09 +08:00
    我怀疑写八股文和背八股文的人不懂什么是 O(log(n)),就硬背树深了一层

    健康项目中:低效率查询,未命中索引的查询应该在 Code Review 阶段被驳回的。过早期的分库分表还会极大提高总持有成本,百害而无一利。因为只需要简单的主从读写分离架构就可以支撑到数万 TPS 了。
    dog82
        19
    dog82  
       2022-10-16 11:53:07 +08:00
    这应该是个经验之谈。主要是看表怎么用,如果仅仅是主键查询 10 亿都不要分表。
    ration
        20
    ration  
       2022-10-16 11:58:36 +08:00 via Android
    什么数据库,什么版本,硬件性能咋样,如果是 mysql 用的是什么引擎,条件不充分都是空谈。我觉得测试之后才能有结果,真正实践的话也要对数据库进行测试。
    reter
        21
    reter  
       2022-10-16 12:26:49 +08:00
    物理定律还有适用条件呢,更何况数据库的访问模式不同,硬件、软件也会不断地迭代和优化
    dog82
        22
    dog82  
       2022-10-16 12:39:46 +08:00
    分表并不会让事情变得更简单,仅仅是用逻辑复杂度代替空间复杂度而已
    murmur
        23
    murmur  
       2022-10-16 12:43:51 +08:00
    @lmshl 是不是民科不重要,重要的在于程序员的素养,如果考虑到外包团队普遍拉垮的质量,以及 java mysql 这些在企业应用中的高占比,我赞同 500w 分表
    JohnBull
        24
    JohnBull  
       2022-10-16 13:53:03 +08:00
    应该没这么夸张。
    自建的文件元数据索引表没能正确处理符号链接 loop ,结果整出来几百 G 的表,直到手工执行 count(*)的时候才发现不对劲,其它操作基本无感
    yohole
        25
    yohole  
       2022-10-16 14:11:21 +08:00
    应该是性能目标不一致造成的错觉

    [查询没有问题] 这个本身就很主观的东西,不同企业不同场景对 [查询没问题] 的定义可以差很大的啊

    其他企业敢说自己的查询目标要求与阿里场景和要求一致吗?
    iseki
        26
    iseki  
       2022-10-16 14:34:03 +08:00
    阿里的技术手册,其他实体应当仅供参考。
    0576coder
        27
    0576coder  
       2022-10-16 14:43:46 +08:00
    之前生产环境有张过亿的表,其实表大了 查询还好,插入更新的时候,cpu 磁盘都会飙升,而且索引建的不科学的话,大表真的是噩梦,大表再数据插入的时候,还不稳定,时间慢,所以我感觉查询并不是分库分表的原因
    这种情况在数据千万级别的时候就慢慢开始显现,但是这个 500W 的数字我也不知道怎么得出的
    mmdsun
        28
    mmdsun  
       2022-10-16 14:52:20 +08:00
    过亿有索引的查询肯定没问题。

    有没有人试过修改、更新、和连表的性能?
    0576coder
        29
    0576coder  
       2022-10-16 15:16:56 +08:00
    @mmdsun insert 跟 update 的时候会有问题 如果 update 的范围过大 可能该表就卡住了一样 而且时间还不稳定 尤其是索引多一点的时候 简直是噩梦
    Leviathann
        30
    Leviathann  
       2022-10-16 15:35:40 +08:00
    查单条肯定随便过亿,其他操作我擦我不好说
    romisanic
        31
    romisanic  
       2022-10-16 15:39:46 +08:00
    实际工作中遇到过表数据超过两千万的情况,没有分表,是公司内 IM 的聊天记录。
    结论是:查询、插入,以及主键更新,甚至索引做的不错,条件查询、翻页也还可以。
    但是:开发新功能时,表结构变更,一个不注意,就是灾难。变更一次锁表 20 分钟。
    Valid
        32
    Valid  
       2022-10-16 15:52:48 +08:00
    表设计的垃圾才需要
    Jooooooooo
        33
    Jooooooooo  
       2022-10-16 15:53:56 +08:00
    这当然是经验只谈.

    几百万的表, 单表查基本没事.

    越大单表风险越大, 还是趁早拆.
    victorc
        34
    victorc  
       2022-10-16 16:58:24 +08:00
    它就是随便一说,不要这样机械,一旦启用分表,你的程序也要对应的修改,分表的好处是:系统具备横向扩容的能力. 流量大幅度上涨之后,加点机器就能抗住,如果没有这个需求就不需要扩

    只要硬盘够大,单表存放数量随便
    shiny
        35
    shiny  
       2022-10-16 17:02:40 +08:00
    小马过河,自己趟一趟才知道深浅。索引做得如何、SQL 复杂度、硬件配置、每行数据的数据量都会对结果有影响。有十几亿记录数的表也跑得欢,也遇到过百万的表就已经很慢。
    tohuer00
        36
    tohuer00  
       2022-10-16 18:10:24 +08:00
    分表分库这些都是有代价的,分了以后业务开发难度会明显增大,越复杂的业务越是如此。
    很多公司负责技术架构的人并不参与业务开发,说得不好听,为了自己的 KPI ,纸上谈兵拍脑袋定方案,害人不浅。

    分不分表,怎么分,都要看具体业务和原有设计。
    HankLu
        37
    HankLu  
       2022-10-16 18:22:38 +08:00
    超过 500 万行或 2GB 才推荐,也就是说不超过 500 万行或 2GB ,不推荐分表,因为完全没有这个必要。
    cbdyzj
        38
    cbdyzj  
       2022-10-16 19:19:45 +08:00 via Android
    我们公司以前是 800w 行,但实际生产上也有超过 4000w 行的表跑着
    someonedeng
        39
    someonedeng  
       2022-10-16 19:27:50 +08:00
    甚至没提硬件。。就嗯背八股
    aptupdate
        40
    aptupdate  
       2022-10-16 19:51:47 +08:00 via iPhone
    我记得 oracle 是 1 亿,mysql 不至于这么拉胯吧?
    sean424
        41
    sean424  
       2022-10-16 21:01:36 +08:00
    12 年的时候,mysql 免费版 大概 600 多万 数据是个分界线
    keakon
        42
    keakon  
       2022-10-16 21:21:26 +08:00
    InnoDB 的一页默认是 16KB ,其中有 100 多字节是头部等不用于存储数据的,这里先忽略。
    索引页的每行要存储一个主键(假设是 int ,4 字节)和一个页号( 4 字节),共计 8 字节。即一页最多存储 2K 条。
    以一个 3 层的 B+ 树来计算,前两层是索引页,最多索引 2K * 2K = 4M 个节点。
    假设表的每行占用的空间是 1KB ,那么一个数据页(叶子节点)最多存储 16 条数据,所有节点共可以存储 64M 条数据( 64GB 大小)。
    超过这个量时,要用 4 层的 B+ 树,那么 IO 次数就至少多出 1/3 ,索引也很难全放在内存中,肯定会大幅影响性能。

    但是题目中提到的 500M 行和 2GB 并不是一个固定值,如果主键和每行占用的空间较小,就能存放更多的页。甚至你还能修改 innodb_page_size ,配置成更大的页,以在一页中存储更多行(但是可能造成 IO 的浪费,因为每次至少读一页)。
    lazyfighter
        43
    lazyfighter  
       2022-10-17 09:26:59 +08:00
    @keakon 非常赞
    sun1991
        44
    sun1991  
       2022-10-17 09:27:34 +08:00
    之前一个人能搞定, 分表后需要一个团队维护. 对部门有利.
    daoqiongsi1101
        45
    daoqiongsi1101  
       2022-10-17 13:07:02 +08:00
    我们存了十几亿数据,看你怎么查,不是所有查询都会很慢
    Seulgi
        46
    Seulgi  
       2022-10-17 14:13:57 +08:00
    阿里人家数据库实例是什么规格都没给你说, 你怎么确定自己的实例规格要按照 500w 或 2GB 来呢, 阿里的技术手册, 就看看就行吧. 经验值始终要去躺一次才知道什么效果, 没必要强硬生套.
    cubecube
        47
    cubecube  
       2022-10-17 14:27:53 +08:00
    @wxf666
    1. 十年前的 mysql 的确不太行( 5.7 之前)
    2. 十年前的 CPU 性能瓶颈也很大,不分库存在 CPU 瓶颈
    3. 之前的 Disk 是 HDD ,现在大部分是 ssd ,导致数据库性能有急剧提升。
    综上,以前的观点和现在大家的体感不一致很正常。
    motecshine
        48
    motecshine  
       2022-10-17 15:01:13 +08:00
    我们单表 670GB 数据 OLTP 查询 基本在 20-30ms
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2548 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 01:33 · PVG 09:33 · LAX 17:33 · JFK 20:33
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.