您当前的位置:首页 > 电脑百科 > 数据库 > 百科

海量数据写入——万级并发的订单系统如何分库?

时间:2021-03-04 09:28:44  来源:  作者:

一定要分表分库吗?

当然不一定

虽然很多互联网公司的体量很大、用户非常多,但你千万不要被这些现象迷惑了。实际上,90% 以上的系统能够发展到上百万、上千万数据量已经很不错了。对于千万的数据量,开源的 MySQL 都可以很好地应对,更别说一些商业数据库了。

另外,当数据增长到一定量级后,可以在业务层面做一些处理。比如根据业务特点,对无效数据、软删除数据,以及业务上不会再查询的数据进行统一归档,这也是一个成本低、效果明显的方式了。

一定要分库吗?

说到分库,他当然能够解决存储的问题,假设原先单库只能最多存储2千万的数据量。采用分库之后,存储架构变成下图所示的分库架构,每个分库都可以存储2千万数据量,容量的上限一下提升了。

海量数据写入——万级并发的订单系统如何分库?

 

虽然容量提升了,但也带来了很多其他问题。

  • 分库数据间的数据无法再通过数据库直接查询了,比如跨多个分库的数据需要多次查询或借助其他存储进行聚合再查询。
  • 分库越多,出现问题的可能性越大,维护成本也变得更高。
  • 无法保障跨库间事务,只能借助其他中间件实现最终一致性。

所以在解决容量问题上,可以根据业务场景选择,不要一上来就要考虑分库,分表也是一种选择。

分表是指所有的数据均存在同一个数据库实例中,只是将原先的一张大表按一定规则,划分成多张行数较少的表。

它与分库的区别是,分表后的子表仍在原有库中,而分库则是子表移动到新的数据库实例里并在物理上单独部署。分表的拆分架构如下图所示:

海量数据写入——万级并发的订单系统如何分库?

 

不管是打车的订单、电商里的支付订单,还是外卖或团购的支付订单,都是后台服务中最重要的一环,关乎公司的营收。因此我将以订单业务作为案例进行分析。

假设订单只是单量多而每一单的数据量较小,这就适合采用分表。单条数据量小但行数多,会导致写入(因为要构建索引)和查询非常慢,但整体对于容量的占用是可控的。

采用分表后,大表变成小表,写入时构建索引的性能消耗会变小,其次小表的查询性能也更好。如果采用了分库,虽然解决了写入和查询的问题,但每张表所占有的磁盘空间很少,也会产生资源浪费。两种方案的对比如下图所示:

海量数据写入——万级并发的订单系统如何分库?

 

在实际场景里,因为要详细记录用户的提单信息,单个订单记录的数据量均较多,所以不存在行数多但单条数据量小的情况。但在其他写入服务里,经常会出现上述场景,你可以优先采用分表的方案。因为分表除了能解决容量问题,还能在一定程度上解决分库所带来的三个问题。

分表后可以通过 join 等完成一些富查询,相比分库简单得多。

分表的数据仍存储在一个数据库里,不会出现很多分库。无须引入一些分库中间件,因此维护成本和开发成本均较低。

因为在同一个数据库里,也可以很好地解决事务问题。

如何选择分库维度?

如果你确定要对数据库进行分库,究竟要如何实现呢?

首先要解决的问题便是如何选择分库维度。

不同的分库维度决定了部分查询是否能直接使用数据库,以及是否存在数据倾斜的问题。

介绍两种常见的不同维度的分库方式:

  1. 按直接满足最重要的业务场景划分
  2. 按最细粒度随机分

按直接满足最重要的业务场景划分

在业务上,所有的订单数据都是隶属于某一个用户的。可以按订单归属的用户这个字段进行分库,则同一个用户的订单都在某一个分库里。

分库后的场景如下图所示:

海量数据写入——万级并发的订单系统如何分库?

 

订单模块除了提供提交订单接口外,还会提供给售卖商家对自己店铺的订单进行查询及修改等功能。这些维度的查询和修改需求,在采用了按购买用户进行分库之后,均无法直接满足了。

这里请你思考一个问题,订单模块最重要的功能是什么?

答案是保证客户(即买家)的各项订单功能能够正常使用,比如下单、下单后立刻(无延迟)查看已购的订单信息、待支付、待发货、待配送的订单列表等。

相对来说,订单里的商品售卖方(即卖家)所使用的功能并不是优先级最高的。因为当我们要对卖家和买家的功能做取舍时,卖家是愿意降低优先级的,毕竟卖家是买卖的受益方。

按购买用户划分后,用户的使用场景都可以直接通过分库支持,而不需要通过异构数据(存在数据延迟)等手段解决,对用户来说体验较好。其次,在同一个分库中,便于修改同一用户的多条数据,因此也不存在分布式事务问题。

我们可以通过上述订单案例抽象出一个分库准则:在确定分库字段时应该以直接满足最重要的业务场景为准

很多其他的业务都参考了这一准则,比如——

  • 对于微博和知乎等用户生产内容(UGC)的业务,均会按用户进行分库。因为用户新发布文章后就会去查看列表。
  • 支付系统里,也会按用户的支付记录进行分库。
  • 在技术上,比如一个微服务下的监控数据,同样会按微服务进行划分。同一个微服务的监控数据均存储在一个分库里,你可以直接在一个分库里查看微服务下的所有监控数据。

上述划分方法虽然直接满足了最重要的场景,但可能会出现数据倾斜的问题,比如出现一个超级客户(如企业客户),购买的订单量非常大,导致某一个分库数据量巨多,就会重现分库前的场景。这属于最极端的情况之一。

最细粒度随机分

对于倾斜的问题,可以采用最细粒度的拆分,即按数据的唯一标示进行拆分

对于订单来说唯一标示即为订单号。采用订单号进行分库之后,用户的订单会按 Hash 随机均匀地分散到某一个分库里。这样就解决了某一个分库数据不均匀的问题。

比如:

  • 按用户的每一条微博随机分库;
  • 按用户的每一笔支付记录随机分库;
  • 同一个微服务里的每一个监控点的数据随机分库。

采用最细粒度分库后,虽然解决了数据均衡的问题,但又带来了其他问题。

  • 首先,除了对细粒度查询外,对其他任何维度的查询均不支持。这就需要通过异构等方式解决,但异构有延迟、对业务是有损的。
  • 其次,防重逻辑在数据库层面无法支持。比如用户对同一个订单在业务上只能支付一次这一诉求,在支付系统按支付号进行分库后便不能直接满足了。因为上述分库方式会导致不同支付单分散在不同的分库里,此时,期望在数据库中通过订单号的唯一索引进行支付防重就不可实施了。

总之,这两种分库的方式,在解决问题的同时又带来了一些新的问题。在架构中,没有一种方案是可以解决所有问题的,更多的是根据场景去选择更适合自己的方案。

作者:你勾哥还是你勾哥
链接:https://juejin.cn/post/6934678641204789285
来源:掘金



Tags:分库   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
数据库的数据量达到一定程度之后,为避免带来系统性能上的瓶颈。需要进行数据的处理,采用的手段是分区、分片、分库、分表。一些问题的解释:1.为什么要分表和分区?日常开发中我们...【详细内容】
2021-09-27  Tags: 分库  点击:(42)  评论:(0)  加入收藏
分库分表介绍:分库分表的目的是为了系统高并发、高可用。分库和年发表是两回事,两个概念,都是为了防止数据库服务因为同一时间内访问量过大导致宕机而设计的一种应对策略。一、...【详细内容】
2021-06-28  Tags: 分库  点击:(103)  评论:(0)  加入收藏
Sharding-JDBC背景:出于工作的需要,非常需要详细了解数据库分表分库的内容,这样便于选择版本,了解原理及性能,做出更好的选择。Sharding-JDBC是ShardingSphere的第一个产品,也是Sh...【详细内容】
2021-05-14  Tags: 分库  点击:(212)  评论:(0)  加入收藏
在文章开头先抛几个问题: 什么时候才需要分库分表呢?我们的评判标准是什么? 一张表存储了多少数据的时候,才需要考虑分库分表? 数据增长速度很快,每天产生多少数据,才需要考虑做分...【详细内容】
2021-04-07  Tags: 分库  点击:(200)  评论:(0)  加入收藏
一定要分表分库吗?当然不一定。虽然很多互联网公司的体量很大、用户非常多,但你千万不要被这些现象迷惑了。实际上,90% 以上的系统能够发展到上百万、上千万数据量已经很不错了...【详细内容】
2021-03-04  Tags: 分库  点击:(156)  评论:(0)  加入收藏
分库分表的文章网上非常多,但是大多内容比较零散,以讲解知识点为主,没有完整地说明一个大表的切分、新架构设计、上线的完整过程。因此,我结合去年做的一个大型分库分表项目,来复...【详细内容】
2020-11-19  Tags: 分库  点击:(176)  评论:(0)  加入收藏
1、场景描述例如订单库进行了分库分表,其实例如下图所示: 现在的需求是希望创建一个任务就将数据同步到MQ集群,而不是为每一个数据库实例单独创建一个任务,将其数据导入到MQ集...【详细内容】
2020-11-16  Tags: 分库  点击:(309)  评论:(0)  加入收藏
《sharding-jdbc 分库分表的 4种分片策略》 中我们介绍了 sharding-jdbc 4种分片策略的使用场景,可以满足基础的分片功能开发,这篇我们来看看分库分表后,应该如何为分片表生成...【详细内容】
2020-11-10  Tags: 分库  点击:(148)  评论:(0)  加入收藏
在之前写过一篇关于mysql分库分表的文章,那篇文章只是给大家提供了一个思路,但是回复下面有很多说是细节问题没有提到。所以咔咔就在出了这篇文章。...【详细内容】
2020-08-18  Tags: 分库  点击:(70)  评论:(0)  加入收藏
随着互联网的迅速发展,会导致产生海量的数据,在数据量还比较小的时候,传统的处理方式是将数据存储在关系或者非关系型数据库中,但是随着数据量逐渐增加,单个数据库的表已经很难容...【详细内容】
2020-06-12  Tags: 分库  点击:(72)  评论:(0)  加入收藏
▌简易百科推荐
1增1.1【插入单行】insert [into] <表名> (列名) values (列值)例:insert into Strdents (姓名,性别,出生日期) values (&#39;开心朋朋&#39;,&#39;男&#39;,&#39;1980/6/15&#3...【详细内容】
2021-12-27  快乐火车9d3    Tags:SQL   点击:(1)  评论:(0)  加入收藏
最近发现还有不少做开发的小伙伴,在写存储过程的时候,在参考已有的不同的写法时,往往很迷茫, 不知道各种写法孰优孰劣,该选用哪种写法,以及各种写法的优缺点,本文以一个简单的查询...【详细内容】
2021-12-23  linux上的码农    Tags:sql   点击:(9)  评论:(0)  加入收藏
《开源精选》是我们分享Github、Gitee等开源社区中优质项目的栏目,包括技术、学习、实用与各种有趣的内容。本期推荐的HasorDB 是一个全功能数据库访问工具,提供对象映射、丰...【详细内容】
2021-12-22  GitHub精选    Tags:HasorDB   点击:(5)  评论:(0)  加入收藏
作者丨Rafal Grzegorczyk译者丨陈骏策划丨孙淑娟【51CTO.com原创稿件】您是否还在手动对数据库执行各种脚本?您是否还在浪费时间去验证数据库脚本的正确性?您是否还需要将...【详细内容】
2021-12-22    51CTO  Tags:Liquibase   点击:(3)  评论:(0)  加入收藏
场景描述:由于生产环境的表比较复杂,字段很多。这里我们做下简化,只为说明今天要聊的问题。有两张表 tab1,tab2: tab1 数据如下: tab2 数据如下: 然后给你看下,我用来统计 name=&#3...【详细内容】
2021-12-20  Bald    Tags:SQL   点击:(5)  评论:(0)  加入收藏
前言知识无底,学海无涯,知识点虽然简单,但是比较多,所以将MySQL的基础写出来,方便自己以后查找,还有就是分享给大家。一、SQL简述1.SQL的概述Structure Query Language(结构化查...【详细内容】
2021-12-16  谣言止于独立思考    Tags:SQL基础   点击:(13)  评论:(0)  加入收藏
前言作为一名测试工程师,工作中在对测试结果进行数据比对的时候,或多或少要和数据库打交道的,要和数据库打交道,那么一些常用的 SQL 查询语法必须要掌握。最近有部分做测试小伙...【详细内容】
2021-12-14  柠檬班软件测试    Tags:SQL   点击:(15)  评论:(0)  加入收藏
话说C是面向内存的编程语言。数据要能存得进去,取得出来,且要考虑效率。不管是顺序存储还是链式存储,其寻址方式总是很重要。顺序存储是连续存储。同质结构的数组通过其索引表...【详细内容】
2021-12-08  小智雅汇    Tags:数据存储   点击:(17)  评论:(0)  加入收藏
概述DBConvert Studio 是一款强大的跨数据库迁移和同步软件,可在不同数据库格式之间转换数据库结构和数据。它将成熟、稳定、久经考验的 DBConvert 和 DBSync 核心与改进的现...【详细内容】
2021-11-17  雪竹聊运维    Tags:数据库   点击:(26)  评论:(0)  加入收藏
一、前言 大家好,我是小诚,《从0到1-全面深刻理解MySQL系列》已经来到第四章,这一章节的主要从一条SQL执行的开始,由浅入深的解析SQL语句由客户端到服务器的完整执行流程,最...【详细内容】
2021-11-09  woaker    Tags:SQL   点击:(35)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条