爆款云主机2核4G限时秒杀,88元/年起!
查看详情

活动

天翼云最新优惠活动,涵盖免费试用,产品折扣等,助您降本增效!
热门活动
  • 618智算钜惠季 爆款云主机2核4G限时秒杀,88元/年起!
  • 免费体验DeepSeek,上天翼云息壤 NEW 新老用户均可免费体验2500万Tokens,限时两周
  • 云上钜惠 HOT 爆款云主机全场特惠,更有万元锦鲤券等你来领!
  • 算力套餐 HOT 让算力触手可及
  • 天翼云脑AOne NEW 连接、保护、办公,All-in-One!
  • 中小企业应用上云专场 产品组合下单即享折上9折起,助力企业快速上云
  • 息壤高校钜惠活动 NEW 天翼云息壤杯高校AI大赛,数款产品享受线上订购超值特惠
  • 天翼云电脑专场 HOT 移动办公新选择,爆款4核8G畅享1年3.5折起,快来抢购!
  • 天翼云奖励推广计划 加入成为云推官,推荐新用户注册下单得现金奖励
免费活动
  • 免费试用中心 HOT 多款云产品免费试用,快来开启云上之旅
  • 天翼云用户体验官 NEW 您的洞察,重塑科技边界

智算服务

打造统一的产品能力,实现算网调度、训练推理、技术架构、资源管理一体化智算服务
智算云(DeepSeek专区)
科研助手
  • 算力商城
  • 应用商城
  • 开发机
  • 并行计算
算力互联调度平台
  • 应用市场
  • 算力市场
  • 算力调度推荐
一站式智算服务平台
  • 模型广场
  • 体验中心
  • 服务接入
智算一体机
  • 智算一体机
大模型
  • DeepSeek-R1-昇腾版(671B)
  • DeepSeek-R1-英伟达版(671B)
  • DeepSeek-V3-昇腾版(671B)
  • DeepSeek-R1-Distill-Llama-70B
  • DeepSeek-R1-Distill-Qwen-32B
  • Qwen2-72B-Instruct
  • StableDiffusion-V2.1
  • TeleChat-12B

应用商城

天翼云精选行业优秀合作伙伴及千余款商品,提供一站式云上应用服务
进入甄选商城进入云市场创新解决方案
办公协同
  • WPS云文档
  • 安全邮箱
  • EMM手机管家
  • 智能商业平台
财务管理
  • 工资条
  • 税务风控云
企业应用
  • 翼信息化运维服务
  • 翼视频云归档解决方案
工业能源
  • 智慧工厂_生产流程管理解决方案
  • 智慧工地
建站工具
  • SSL证书
  • 新域名服务
网络工具
  • 翼云加速
灾备迁移
  • 云管家2.0
  • 翼备份
资源管理
  • 全栈混合云敏捷版(软件)
  • 全栈混合云敏捷版(一体机)
行业应用
  • 翼电子教室
  • 翼智慧显示一体化解决方案

合作伙伴

天翼云携手合作伙伴,共创云上生态,合作共赢
天翼云生态合作中心
  • 天翼云生态合作中心
天翼云渠道合作伙伴
  • 天翼云代理渠道合作伙伴
天翼云服务合作伙伴
  • 天翼云集成商交付能力认证
天翼云应用合作伙伴
  • 天翼云云市场合作伙伴
  • 天翼云甄选商城合作伙伴
天翼云技术合作伙伴
  • 天翼云OpenAPI中心
  • 天翼云EasyCoding平台
天翼云培训认证
  • 天翼云学堂
  • 天翼云市场商学院
天翼云合作计划
  • 云汇计划
天翼云东升计划
  • 适配中心
  • 东升计划
  • 适配互认证

开发者

开发者相关功能入口汇聚
技术社区
  • 专栏文章
  • 互动问答
  • 技术视频
资源与工具
  • OpenAPI中心
开放能力
  • EasyCoding敏捷开发平台
培训与认证
  • 天翼云学堂
  • 天翼云认证
魔乐社区
  • 魔乐社区

支持与服务

为您提供全方位支持与服务,全流程技术保障,助您轻松上云,安全无忧
文档与工具
  • 文档中心
  • 新手上云
  • 自助服务
  • OpenAPI中心
定价
  • 价格计算器
  • 定价策略
基础服务
  • 售前咨询
  • 在线支持
  • 在线支持
  • 工单服务
  • 建议与反馈
  • 用户体验官
  • 服务保障
  • 客户公告
  • 会员中心
增值服务
  • 红心服务
  • 首保服务
  • 客户支持计划
  • 专家技术服务
  • 备案管家

了解天翼云

天翼云秉承央企使命,致力于成为数字经济主力军,投身科技强国伟大事业,为用户提供安全、普惠云服务
品牌介绍
  • 关于天翼云
  • 智算云
  • 天翼云4.0
  • 新闻资讯
  • 天翼云APP
基础设施
  • 全球基础设施
  • 信任中心
最佳实践
  • 精选案例
  • 超级探访
  • 云杂志
  • 分析师和白皮书
  • 天翼云·创新直播间
市场活动
  • 2025智能云生态大会
  • 2024智算云生态大会
  • 2023云生态大会
  • 2022云生态大会
  • 天翼云中国行
天翼云
  • 活动
  • 智算服务
  • 产品
  • 解决方案
  • 应用商城
  • 合作伙伴
  • 开发者
  • 支持与服务
  • 了解天翼云
      • 文档
      • 控制中心
      • 备案
      • 管理中心

      表数据量大读写缓慢如何优化(4)【分库分表】

      首页 知识中心 大数据 文章详情页

      表数据量大读写缓慢如何优化(4)【分库分表】

      2024-04-26 08:39:47 阅读次数:44

      在第二篇文章中说到,查询分离中存在三大不足,其中一个不足就是:当主数据量越来越大,写操作缓慢,遇到这个问题我们该如何解决呢?

      为此,这篇文章我们主要围绕这个问题来讨论,拆分存储如何进行技术选型?分库分表的实现思路是什么?分库分表存在哪些不足?

      一、业务场景三

      为了便于理解,我们通过一个业务场景来入手。

      有一个电商系统架构优化工作,该系统中包含用户和订单2个主要实体,每个实体涵盖数据量如下表所示:

      实体 数据量 增长趋势
      用户 千万级 每日10万
      订单 亿级 每日百万级,后续可能千万级

      从上表中发现,目前订单数据量已达上亿,并且每日以百万级速度增长,之后还可能是千万级。

      面对如此大的数据量,此时存储订单的数据库竟然还是一个单库单表。对于单库单表而言,一旦数据量实现疯狂增长,无论是IO还是CPU都会扛不住。

      为了使系统抗住千万级数据量的压力,各种SQL优化都已经做完,最终确定下来的方式是将订单表拆分,再进行分布存储,这也就是本章我们要讨论的内容——分库分表。

      说到分库分表解决方案,我们首先需要做的就是搞定拆分存储的技术选型问题。

      二、拆分存储的技术选型

      关于拆分存储常用的技术解决方案,市面上目前主要分为4种:MySQL的分区技术、NoSql、NewSQL、基于MySQL的分库分表。

      1、MySQL的分区技术

      MySQL的分区主要在文件存储层做文章,它可以将一张表的不同存放在不同存储文件中,这对使用者来说比较透明。

      在以往的实战项目中,我们不使用它的原因主要有三点。

      1、MySQL的实例只有一个,它仅仅分摊了存储,无法分摊请求负载。

      2、正式因为MySQL的分区对用户透明,所以用户在实际操作时往往不太注意,使得跨分区操作严重影响系统性能。

      3、当然,MySQL还有一些其他限制,比如不支持query cache、位操作表达式等。感兴趣的朋友可以看看这个文章:https:///doc/refman/5.7/en/partitioning-limitations.html。

      2、NoSQL(如MongoDB)

      比较典型的NoSQL数据库就是MongoDB啦。MongoDB的分片功能从并发性和数据量这两个角度已经能满足一版大数据量的需求,但是需要注意这三大要点。

      1、约束考量:MongoDB不是关系型数据库而是文档型数据库,它的每一行记录都是一个结构灵活可变的JSON,比如存储非常重要的订单数据时,我们就不能使用MongoDB,因为订单数据必须使用强约束的关系型数据库进行存储。

      2、业务功能考量:多年来,事务、锁、SQL、表达式等千奇百怪的操作都在MySQL身上一一验证过,MySQL可以说是久经考验,因此在功能上MySQL能满足我们所有的业务需求,MongoDB却不能,且大部分的NoSQL也存在类似的问题。

      3、稳定性考量:我们对MySQL的运维已经很熟悉了,它的稳定性没有问题,然而MongoDB的稳定性我们没法保证,毕竟不熟悉,因此在之前的拆分存储技术选型中,我们没使用过NoSQL。

      3、NewSQL(如TiDB)

      NewSQL技术还比较新,我们曾今想在一些不重要的数据中使用NewSQL(比如TiDB),但从稳定性和功能扩展性两方面来考量后,最终没有使用,具体原因与MongoDB类似。

      4、基于MySQL的分库分表

      什么是分库分表?分表是将一份大的表数据拆分存放至多个结构一样的拆分表;分库就是将一个大的数据库拆分成多个结构一样的小库。

      前面介绍的三种拆分存储技术,在我们以往的项目中都没有使用过,而是选择了基于MySQL的分库分表,主要是有一个重要考量:分库分表对于第三方依赖较少,业务逻辑灵活可控,它本身并不需要非常复杂的底层处理,也不需要重新做数据库,只是根据不同的逻辑使用不同的SQL语句和数据源而已。

      如果使用分库分表方式,存在三个技术通用需求需要实现。

      1、SQL组合:因为我们关联的表名是动态的,所以我们需要根据逻辑组装动态的SQL。

      2、数据库路由:因为数据库名也是动态的,所以我们需要根据不同的逻辑使用不同的数据库。

      3、执行结果合并:有些需求需要通过多个分库执行,再合并归集使用。

      而市面上能解决以上问题的中间件分为2类:Proxy模式、Client模式。

      (1)Proxy模式:直接拿ShardingSphere官方文档里的图进行说明,我们重点看看中间Sharding-Proxy层,如下图所示:

      表数据量大读写缓慢如何优化(4)【分库分表】

      以上这种设计模式,把SQL组合、数据库路由、执行结果合并等功能全部存放在一个代理服务中,而与分库分表相关的处理逻辑全部存放在另外的服务中,这种设计模式的优点是对业务代码无侵入,业务只需要关注自身的业务逻辑即可。

      (2)Client模式:还是借用shardingSphere官方文档的图来说明,如下图所示:

      表数据量大读写缓慢如何优化(4)【分库分表】

      以上这种设计模式,把分库分表相关逻辑存放在客户端,一版客户端的应用会引用一个jar,然后再jar中处理SQL组合、数据库路由、执行结果合并等相关功能。

      市面上,关于这两种模式的中间件有如下选择:

      中间件技术 模式 厂家 语言
      MyCat Proxy   Java
      KingShard Proxy   Go
      Atlas Proxy 360 C
      zebra Client 美团 Java
      cobar Proxy 阿里 Java
      Sharding-JDBC Client Apache ShardingSphere Java
      TSharding Client 蘑菇街 Java

      看到这里,我们已经知道市面上开源中间件的设计模式,那么我们到底该选择哪种模式呢?简单对比下这2个模式的优缺点,你就知道答案了。

      模式 优点 缺点
      Proxy 1、多语言。2、资源消耗解耦,不需要消耗客户端的资源。3、升级方便。 1、多一层服务调用,debug线上问题调查难一些。2、多一层运维成本。
      Client 1、少一层服务调用,代码灵活可控。2、减少运维成本 1、单语言。2、升级不方便。

      因为看重代码灵活可控这个优势,所以我们选择了Client模式里的Sharding-JDBC来实现分库分表,如下图所示: 表数据量大读写缓慢如何优化(4)【分库分表】

      当然,关于拆分存储选择哪种技术,在实际工作中我们需要根据各自的实际情况来定。

      三、分库分表实现思路

      技术选型这一大难题解决后,具体如何落地分库分表解决方案成了我们亟待解决的问题。

      在落实分库分表解决方案时,我们需要考虑5个要点。

      1、使用什么字段作为分片键?

      我们先来回顾下业务场景中举例的数据库:

      实体 数据量 增长趋势
      用户 千万级 每日10万
      订单 亿级 每日百万级,后续可能千万级

      下面我们把上表中的数据拆分成一个订单表,表中主要数据结构如下:

      表名 字段 备注
      t_order User_id 客户id
        Order_id 订单id
        user_city_id 用户所在城市
        Order_time 下单时间
        ... 其他字段就不列了

      从上面表中可知,我们是使用user_id作为分片主键,为什么这样分呢,来聊聊当时的实现思路。

      在选择分片字段之前,我们首先了解了下目前存在的一些常见业务需求:

      • 用户需要查询所有订单,订单数据中肯定包含不同的merchant_id、order_time;
      • 后台需要根据城市查询当地订单;
      • 后台需要统计每个时间段的订单趋势;

      根据这些常见业务需求,我们判断了下优先级,用户操作也就是第一个需求必须优先满足。

      此时,如果我们使用user_id作为订单分片字段,就能保证每次用户查询数据时(第一个需求),在一个分库的一个分表里即可获取数据。

      因此,在我们的方案里,最终还是使用user_id作为分片主键,这样在分库分表查询时,首先会把user_id作为参数传过来。

      这里需要特殊说明下,选择字段作为分片键时,我们一般要考虑三个因素:数据尽量均匀分布在不同的库或表、跨库查询尽可能少、这个字段值会不会变(这点尤为重要)。

      2、分片的策略是什么?

      决定使用user_id作为订单分片字段后,我们就要开始考虑分片的策略问题了。

      目前,市面上通用的分片策略分为根据范围分片、根据hash值分片,根据hash值及范围混合分片这三种。

      • 根据范围分片:比如用户id是自增型数字,我们把用户id按照每100万份分为一个库,每10万份分为一个表的形式进行分片,如下表所示:
      用户id范围 数据库名 表名
      0-99999 Order_ t_order_00
      100000-199999 Order_ t_order_01
      200000-299999 Order_ t_order_02
      ... Order_ ...
      900000-999999 Order_ t_order_09
      1000000-1099999 Order_1 t_order_10

      特殊说明:这里我们只说分表,至于分库则是把分表分组存放在一个库即可,就不另行说明了。

      • 根据hash值分片:指的是根据用户id的hash值mod一个特定的数进行分片。(避免方便后续扩展,一版是2的几次方)
      • 根据hash值及范围混合分片:先按照范围分片,再根据hash值取模分片。比如:表名=order_#user_id%10#_#hash(user_id)%8,即被分成了10*8=80个表。为了方便理解,我们画个图来说明,如图所示:

      表数据量大读写缓慢如何优化(4)【分库分表】

      以上三大分片策略我们到底应该选择哪个?我们只需要考虑一点:假设之后数据量变大了,需要我们把表分的更细,此时保证迁移的数据量尽量少即可。

      因此,根据hash值分片时我们一般建议拆分成2的N次方表,比如分成8张表,数据迁移时把原来的每张表拆一半出来组成新表,这样数据迁移量就小了。

      当初的方案中,我们就是根据用户id的hash值取模32,把数据分成32个数据库,每个数据库再拆分成16张表。

      我们简单算了下,假设每天订单1000万,每个库日增1000万/16=31.25万,每个表日新增1000万/32/16=1.95万。而如果每天千万订单量,3年后每个表的数据量就是2000万左右,也还在可控范围内。

      因此,如果业务增长特别快,且运维还扛得住,为避免以后出现扩容问题,我们建议库分的越少越好。

      3、业务代码如何修改?

      分片策略定完以后,我们就要考虑业务代码如何修改了。因修改业务代码部分与业务强关联,所以我们的方案并不具备参考性。

      这里分享些个人观点。近年来,分库分表操作愈发简单,不过我们需要注意几个要点:

      • 我们已经习惯微服务了,对于特定表的分库分表,其影响面只在该表所在的服务中,如果是一个单体架构的应用做分库分表,那真是伤脑筋。
      • 在互联网架构中,我们基本不使用外键约束。
      • 随着查询分离的流行,后台系统中有很多操作需要跨库查询,导致系统性能非常差,这时分库分表一般会结合查询分离一起操作:先将所有的数据在ES中索引一份,再使用ES在后台直接查询数据。如果订单详情数据量很大,还有个常见的做法,即先在ES中存储索引字段(作为查询条件的字段),再将详情数据存在HBASE中(这个方案这里就不展开了)。

      一般来说,业务代码的修改不会很复杂,最麻烦的是历史数据的迁移。

      4、历史数据的迁移?

      历史数据的迁移非常耗时,有时迁移几天几夜都很正常。在互联网行业中,别说几天几夜了,就连停机几分钟业务都无法接受,这就要求我们给出一个无缝迁移的解决方案。

      还记得在聊查询分离时,讨论过的解决方案吗?我们来回顾下,如下图所示:感兴趣的朋友可以看看之前的文章:数据库表数据量大读写缓慢如何优化(2)【查询分离】

      表数据量大读写缓慢如何优化(4)【分库分表】

      历史数据迁移时,我们就是采用类似的方案进行历史数据迁移,如下图所示:

      表数据量大读写缓慢如何优化(4)【分库分表】

      此数据迁移方案的基本思路:存量数据直接迁移,增量数据监听binglog,然后通过canal通知迁移程序搬运数据,新的数据库拥有全量数据,且校验通过后逐步切换流量。

      数据迁移解决方案详细的步骤如下:

      • 上线canal,通过canal触发增量数据的迁移;
      • 迁移数据脚本测试通过后,将老数据迁移到新的分库分表中;
      • 注意迁移增量数据与迁移老数据的时间差,确保全部数据都被迁移过去,无遗漏;
      • 第二步、第三步都运行完后,新的分库分表中已经拥有了全量数据了,这时我们可以运行数据验证的程序,确保所有数据都存放在新数据库中;
      • 到这步数据迁移就算完成了,之后就是新版本代码上线了,至于是灰度上还是直接上,需要根据实际情况决定,回滚方案也是一样。

      5、未来的扩容方案是什么?

      随着业务的发展,如果原来的分片设计已经无法满足日益增长的数据需求,我们就需要考虑扩容了,扩容方案主要依赖以下两点:

      • 分片策略是否可以让新表数据的迁移源只是一个旧表,而不是多个旧表,这就是前面我们建议使用2的N次方分表的原因;
      • 数据迁移:我们需要把旧分片数据迁移到新的分片上,这个方案与上面提及的历史数据迁移一样,就不过多赘述了;

      四、分库分表的不足

      分库分表的解决方案聊完了,以上就是业界常用的一些做法,不过此方案仍存在不足之处。

      • ES+Hbase做数据查询分离的方案:前面我们说了单独使用ES做查询分离解决方案,这里就不再单独展开了。
      • 增量数据迁移:如何保证数据的一致性及高可用性?这个问题我们在后面的文章中会单独展开来说。
      • 短时订单量大爆发:分库分表仍然扛不住时解决方案是什么?这个在缓存和秒杀架构文章中我们再单独展开来说。
      版权声明:本文内容来自第三方投稿或授权转载,原文地址:https://blog.51cto.com/jiangyi/2647498,作者:我爱哇哈哈,版权归原作者所有。本网站转在其作品的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如因作品内容、版权等问题需要同本网站联系,请发邮件至ctyunbbs@chinatelecom.cn沟通。

      上一篇:剑指Offer(30)--最小的k个数

      下一篇:Scala数据类型

      相关文章

      2024-10-24 08:42:05

      Java后端微服务架构下的数据库分库分表:Sharding-Sphere

      随着微服务架构的广泛应用,数据库层面的扩展性问题逐渐凸显。Sharding-Sphere作为一个分布式数据库中间件,提供了数据库分库分表的能力,帮助开发者解决数据水平拆分的问题。

      2024-10-24 08:42:05
      2024-08-02 09:10:09

      MongoDB 单实例分表

      MongoDB 是一个非常流行的 NoSQL 数据库,特别适用于大规模应用程序的数据存储需求。在处理大量数据时,如何有效地管理数据成为一个关键问题。单实例分表是一种常见的 MongoDB 数据库设计方法,它能够提高数据库的性能和可扩展性。

      2024-08-02 09:10:09
      存储 , 数据
      2023-07-05 06:01:45

      数据库之分库分表

      经常会听

      2023-07-05 06:01:45
      数据库
      2023-05-31 08:42:48

      ShardingSphere分库分表查询

      在经过 ​​ShardingSphere分表与分库分表​​ 实现了分库分表之后紧接着本文博主将要测试的就是在这种环境下如果我们写查询语句 ShardingSphere 发送的 SQL 是怎样的是如何查询的,规则是什么,让我们拭目以待吧。全查

      2023-05-31 08:42:48
      查看更多
      推荐标签

      作者介绍

      天翼云小翼
      天翼云用户

      文章

      33561

      阅读量

      5233307

      查看更多

      热门标签

      算法 leetcode python 数据 java 数组 节点 大数据 i++ 链表 golang c++ 排序 django 数据类型
      查看更多

      相关产品

      弹性云主机

      随时自助获取、弹性伸缩的云服务器资源

      天翼云电脑(公众版)

      便捷、安全、高效的云电脑服务

      对象存储

      高品质、低成本的云上存储服务

      云硬盘

      为云上计算资源提供持久性块存储

      • 7*24小时售后
      • 无忧退款
      • 免费备案
      • 专家服务
      售前咨询热线
      400-810-9889转1
      关注天翼云
      • 旗舰店
      • 天翼云APP
      • 天翼云微信公众号
      服务与支持
      • 备案中心
      • 售前咨询
      • 智能客服
      • 自助服务
      • 工单管理
      • 客户公告
      • 涉诈举报
      账户管理
      • 管理中心
      • 订单管理
      • 余额管理
      • 发票管理
      • 充值汇款
      • 续费管理
      快速入口
      • 天翼云旗舰店
      • 文档中心
      • 最新活动
      • 免费试用
      • 信任中心
      • 天翼云学堂
      云网生态
      • 甄选商城
      • 渠道合作
      • 云市场合作
      了解天翼云
      • 关于天翼云
      • 天翼云APP
      • 服务案例
      • 新闻资讯
      • 联系我们
      热门产品
      • 云电脑
      • 弹性云主机
      • 云电脑政企版
      • 天翼云手机
      • 云数据库
      • 对象存储
      • 云硬盘
      • Web应用防火墙
      • 服务器安全卫士
      • CDN加速
      热门推荐
      • 云服务备份
      • 边缘安全加速平台
      • 全站加速
      • 安全加速
      • 云服务器
      • 云主机
      • 智能边缘云
      • 应用编排服务
      • 微服务引擎
      • 共享流量包
      更多推荐
      • web应用防火墙
      • 密钥管理
      • 等保咨询
      • 安全专区
      • 应用运维管理
      • 云日志服务
      • 文档数据库服务
      • 云搜索服务
      • 数据湖探索
      • 数据仓库服务
      友情链接
      • 中国电信集团
      • 189邮箱
      • 天翼企业云盘
      • 天翼云盘
      ©2025 天翼云科技有限公司版权所有 增值电信业务经营许可证A2.B1.B2-20090001
      公司地址:北京市东城区青龙胡同甲1号、3号2幢2层205-32室
      • 用户协议
      • 隐私政策
      • 个人信息保护
      • 法律声明
      备案 京公网安备11010802043424号 京ICP备 2021034386号