Java性能调优实战
刘超
金山软件西山居技术经理
立即订阅
7535 人已学习
课程目录
已完结 48 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 怎样才能做好性能调优?
免费
模块一 · 概述 (2讲)
01 | 如何制定性能调优标准?
02 | 如何制定性能调优策略?
模块二 · Java编程性能调优 (10讲)
03 | 字符串性能优化不容小觑,百M内存轻松存储几十G数据
04 | 慎重使用正则表达式
05 | ArrayList还是LinkedList?使用不当性能差千倍
加餐 | 推荐几款常用的性能测试工具
06 | Stream如何提高遍历集合效率?
07 | 深入浅出HashMap的设计与优化
08 | 网络通信优化之I/O模型:如何解决高并发下I/O瓶颈?
09 | 网络通信优化之序列化:避免使用Java序列化
10 | 网络通信优化之通信协议:如何优化RPC网络通信?
11 | 答疑课堂:深入了解NIO的优化实现原理
模块三 · 多线程性能调优 (10讲)
12 | 多线程之锁优化(上):深入了解Synchronized同步锁的优化方法
13 | 多线程之锁优化(中):深入了解Lock同步锁的优化方法
14 | 多线程之锁优化(下):使用乐观锁优化并行操作
15 | 多线程调优(上):哪些操作导致了上下文切换?
16 | 多线程调优(下):如何优化多线程上下文切换?
17 | 并发容器的使用:识别不同场景下最优容器
18 | 如何设置线程池大小?
19 | 如何用协程来优化多线程业务?
20 | 答疑课堂:模块三热点问题解答
加餐 | 什么是数据的强、弱一致性?
模块四 · JVM性能监测及调优 (6讲)
21 | 磨刀不误砍柴工:欲知JVM调优先了解JVM内存模型
22 | 深入JVM即时编译器JIT,优化Java编译
23 | 如何优化垃圾回收机制?
24 | 如何优化JVM内存分配?
25 | 内存持续上升,我该如何排查问题?
26 | 答疑课堂:模块四热点问题解答
模块五 · 设计模式调优 (6讲)
27 | 单例模式:如何创建单一对象优化系统性能?
28 | 原型模式与享元模式:提升系统性能的利器
29 | 如何使用设计模式优化并发编程?
30 | 生产者消费者模式:电商库存设计优化
31 | 装饰器模式:如何优化电商系统中复杂的商品价格策略?
32 | 答疑课堂:模块五思考题集锦
模块六 · 数据库性能调优 (8讲)
33 | MySQL调优之SQL语句:如何写出高性能SQL语句?
34 | MySQL调优之事务:高并发场景下的数据库事务调优
35 | MySQL调优之索引:索引的失效与优化
36 | 记一次线上SQL死锁事故:如何避免死锁?
37 | 什么时候需要分表分库?
38 | 电商系统表设计优化案例分析
39 | 数据库参数设置优化,失之毫厘差之千里
40 | 答疑课堂:MySQL中InnoDB的知识点串讲
模块七 · 实战演练场 (4讲)
41 | 如何设计更优的分布式锁?
42 | 电商系统的分布式事务调优
43 | 如何使用缓存优化系统性能?
44 | 记一次双十一抢购性能瓶颈调优
结束语 (1讲)
结束语 | 栉风沐雨,砥砺前行!
Java性能调优实战
登录|注册

37 | 什么时候需要分表分库?

刘超 2019-08-15
你好,我是刘超。
在当今互联网时代,海量数据基本上是每一个成熟产品的共性,特别是在移动互联网产品中,几乎每天都在产生数据,例如,商城的订单表、支付系统的交易明细以及游戏中的战报等等。
对于一个日活用户在百万数量级的商城来说,每天产生的订单数量可能在百万级,特别在一些活动促销期间,甚至上千万。
假设我们基于单表来实现,每天产生上百万的数据量,不到一个月的时间就要承受上亿的数据,这时单表的性能将会严重下降。因为 MySQL 在 InnoDB 存储引擎下创建的索引都是基于 B+ 树实现的,所以查询时的 I/O 次数很大程度取决于树的高度,随着 B+ 树的树高增高,I/O 次数增加,查询性能也就越差。
当我们面对一张海量数据的表时,通常有分区、NoSQL 存储、分表分库等优化方案。
分区的底层虽然也是基于分表的原理实现的,即有多个底层表实现,但分区依然是在单库下进行的,在一些需要提高并发的场景中的优化空间非常有限,且一个表最多只能支持 1024 个分区。面对日益增长的海量数据,优化存储能力有限。不过在一些非海量数据的大表中,我们可以考虑使用分区来优化表性能。
分区表是由多个相关的底层表实现的,这些底层表也是由句柄对象表示,所以我们也可以直接访问各个分区,存储引擎管理分区的各个底层表和管理普通表一样(所有的底层表都必须使用相同的存储引擎),分区表的索引只是在各个底层表上各自加上一个相同的索引,从存储引擎的角度来看,底层表和一个普通表没有任何不同,存储引擎也无须知道这是一个普通表,还是一个分区表的一部分。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Java性能调优实战》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(19)

  • QQ怪
    没有什么大厂经验,看了老师的分享的确对大厂数据库分库分表设计有一定的理解和提高
    2019-08-15
    8
  • QQ怪
    现在Fescar已经改名为Seata

    作者回复: 看来成长比较迅速呀。这个开源中间件比较新,去年刚开源的时候了解下源码,顺便实践了基本功能。

    2019-08-15
    7
  • mmilan
    老师说"我们在最开始设计表数据量时,尽量使用 2 的倍数来设置表数量。当我们需要扩容时,也同样按照 2 的倍数来扩容,这种方式可以减少数据的迁移量",不是很理解为什么按2的倍数,就能减少数据的迁移量?

    作者回复: 我们的分表一般是根据[字段的hash值%表数量]或来进行分配的。

    假设某分表字段的哈希值4、8、12,原来的表数量为4,所以这几个数据都会在一个表中。当扩容到8时,只有12会迁移到第五张表中。

    如果扩容到6张表的话,此时哈希值为4的数据会迁移到第五张表,哈希值为8的需要迁移到第三张表,只有哈希值为12的不需要迁移。

    2019-08-28
    3
  • 咬尖月牙儿
    老师,可以用tidb这种newsql取代分库分表的方案吗

    作者回复: 可以的,TiDB是一种集中式的数据存放解决方案,可以节省开发人员很多工作量。

    2019-08-15
    3
  • 明天更美好
    个人感觉单表超过500w就要分表,不然对于性能有要求的业务来说性能太差了。单库数据超2T,就得分库。这样的话可能更合理些
    2019-08-15
    3
    2
  • Demon.Lee
    泪奔,之前用微服务开发产品遇到的难点全中,要是早点看到专栏就好了,人生啊~~~
    2019-09-18
    1
  • godtrue
    我使用过公司基础架构部自研的数据库中间件,对于分库分表的的数据查询可以动态路由,不过也就是动态路由,对于join的支持有限,另外分布式事务保证的也一般般。不知开源产品中有哪些佼佼者,功能多性能高?

    作者回复: sharding-jdbc\mycat在行业内使用比较多,各有优势

    2019-09-15
    1
  • Jxin
    1.中间件应该就mycat,sharding jdbc应该属于基础框架来使用。
    2.提个问题,公司禁用分区,不知为何,但结果就是相关知识忘光光。本章刚好也有提到,顺带麻烦老师介绍下分区,这块反而成薄弱点了。

    作者回复: MySQL的表分区存在一些限制,常见的有:分区字段不能为NULL,避免建立和分区列不匹配的索引。

    除此之外,底层实现的表分区,对MySQL来说其实是一个性能消耗的过程,特别是范围分区,服务器需要扫描所有的分区定义的列表来确定具体的分区。

    表分区在操作数据过滤之前,是需要打开并锁住所有底层表的,这个过程是在分区过滤之前发生的,所有是一个非常消耗性能的过程。

    分区表的维护成本也是很高的,特别是重组分区。

    总之,MySQL的表分区实现偏底层,定制不灵活且性能不是很好,维护成本高。所以很多DBA不建议使用。

    2019-08-22
    1
  • 一眼万年
    老师,mysql单表最大储存性能分析能详细点,而不是简单一句性能能B+树深度有关
    2019-08-19
    1
  • 许童童
    我们的系统前期没设计好,现在想分库分表很难,大量join查询,很难处理。
    想用阿里云的分页式rdbms,不知道可行性。

    作者回复: 前期没有做好分表的准备,后面做表升级工作量就大很多,而风险更高。

    例如一个表如果是自增主键ID,而主键ID又跟其他业务表做了耦合,当我们要做表升级时,需要用另外一个字段做分表字段,这时候就存在主键ID在分表后可能存在冲突的问题。 所以一开始我们就要想到这张表有可能需要做表升级,在做表关联时用另外一个非自增主键ID做关联,或者使用全局自增ID或雪花算法统一获取全局主键ID。

    阿里云的数据库暂时没有用过,多了解支持的一些功能,匹配下是否更适合自己的业务。

    2019-08-15
    1
  • 皮卡皮卡
    GitHub上搜snowflake已经淘汰了

    作者回复: 可以自我实现一个snowflake工具类,理解雪花算法的原理即可

    2019-09-26
  • 儿戏
    老师,请问下 订单表用 用户ID 做hash 分库分表后,订单的item表会成倍增长,造成的数据倾斜,怎么解决?做2次分表吗?

    作者回复: 一般我们都是采用hash求余的方法来实现分库分表,如果在生产环境中出现数据倾斜比较严重,我们需要考虑使用一致性hash算法实现分库分表,也是二次分表的一种实现,只不过可以对局部倾斜数据进行二次分表,实现起来方便,且只影响部分表数据。

    2019-09-05
  • 再续啸傲
    mycat。但是低版本的mycat存在一些聚合函数无法使用的问题
    2019-08-30
  • 小橙橙
    老师,您好。我没有分库分表的经验。有些实践经验向您请教一下。分库分表的数量有上限吗,比如拆分了多少个库之后,查询性能也没有办法再提高了。

    作者回复: 理论上来说,不跨表垮库查询,是没有数量上限,因为路由是不会存在数量越多性能越慢的情况。

    2019-08-16
  • 梦醒时分
    自己调研过Mycat,个人感觉挺好用的。生产上没用过,不知道稳定性怎么样

    作者回复: mycat是一个中间代理层,存在中间相互通信的性能损耗,其他方面挺好的。

    2019-08-16
    1
  • 明天更美好
    有个问题请教下,对于分库分表来说主键需要严格递增,不然数据会发生倾斜的,造成部分库数据过多。雪花算法虽然好,但是只是趋势递增的,那怎么才能做到严格递增呢?并且对性能上有一定要求。

    作者回复: 正如文中提到的,可以通过数据库或缓存来实现严格的递增,但会有一定的性能消耗。鱼和熊掌两者不可兼得,目前雪花算法是一种折中解决方案。

    2019-08-15
  • 门窗小二
    用了sharding jdbc ,但实际实现的时候尽量还是考虑单库
    2019-08-15
  • 失火的夏天
    用过阿里的DRDS,它只支持一个字段作为分库分表键,不能多个字段同时分库分表,而且不支持分布式事务,如果要修改分库键的值,就要先插入再删除,或者先删除再插入。插入,更新,查询的时候都要带上分库键。不过好像有个参数可以控制是不是一定要带分库键,大概就了解这么些。
    2019-08-15
  • 胡峣
    用了段时间shardingjdbc,最后还是回归了单服务单库
    2019-08-15
    2
收起评论
19
返回
顶部