(项目随笔)关于订单系统的思考

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yueluoqianjiang/article/details/84951735

订单系统几个特点:

1、历史信息多(每一条订单完成后,生成一条历史信息,并且一般情况下,久远的订单信息不回被经常查看)

2、并发量高(特别是秒杀系统生成的订单,每秒会有成百上千条订单)

3、订单id必须全局唯一

一、分库分表

随着订单量的增加,数据库发展如下:

  • 单一的数据库
  • 一主一从
  • 双主多从,读写分离
  • 分表分库,提高并发

已知Mysql单表性能超过千万级别会严重下降,按照千万级别来计算,假设订单系统分为16个库,每个库64个表进行存储,共1024个表,那么,Mysql最高可以存储百亿级别的订单。随着储存问题的解决,复杂度也会随之增加,例如一下问题:

  • 多库多表,如何保证订单编号唯一
  • 查询复杂度增加,怎么解决(不知道数据具体在哪个表中)
  • 买家查看订单在哪里查,卖家查看订单在哪里查
  • 再大的储存量,随着数据的增长,总会遇到瓶颈,应该怎么扩容

下面依次解决上面的问题:

1、生成全局唯一的订单编号

这里采用了:机器ID+时间戳+自增序列(+userid后两位); 

这里的机器id是因为集群部署的时候,不同机器上的订单系统的机器id是不一样的,生成的订单id也就不一样了。

时间戳可以精确到毫秒,但是如果每毫秒任然有并发,单纯使用时间戳并不能完全生成唯一订单id

自增序列每个表自己的自增序列,保证单表的订单id唯一

userid后两位,给订单id赋予一定含义。

详情可见:分布式系统唯一ID生成方案汇总

2、查询复杂度的降低-----mycat数据库中间件

中间价可以使用阿里的mycat连接,具体使用查看mycat文档。优点:代码实现简单,跟分库前差不多。

而直接使用jdbc链接,需要自己计算哪条订单存入哪个库,优点是:直接链接数据库性能更好,缺点是代码复杂度高。

3、买家卖家订单设计

由于买家与卖家有不同的查询特性,买家(用户)只会查询自己的订单,而卖家(商家)会查询自己店铺的订单,还有管理者,他可以查询所有的订单并且统计。

订单的查询特性是:一般三个月之前的订单是很少被查询的。

所以我这里设计了两个订单表,一个是针对用户的,一个是针对商家和管理者的。

用户订单表UOrderId根据订单的后两位(也就是生成订单id时的用户id后两位),进行分库分表,这样分得的订单表中,同一个用户的订单一定是在一个表中的,使用mycat查询的时候,减少了mycat的计算等的操作。

商家订单表OOrderId根据订单产生的时间进行分库分表,我们按照一个月一个月分表,分为12个表,商家和管理者查询这个表,由于经常查看的表只有几个,所以,只会查询特定的几个表,减少查询的复杂度。

4、扩容问题

由于订单系统不仅会通过订单号查找订单,还有可能会通过用户id查找,通过商家id查找,查找所有订单等,但是无论是哪种身份的用户查询都有一个特性,就是很少会查询三个月之前的数据,所以我们可以考虑吧三个月之前的数据迁移到历史数据库中,给新的数据腾空间,从而解决容量增长的问题。

例如:我们可以在3,6,9,12月份的月底进行数据迁移,在6月底,将3月之前的数据都迁移到历史数据库中,历史数据库不要求有多高的性能,只要空间足够就可以,节约成本。

二、使用MQ,起缓冲作用,缓解并发问题

这里我们在生成订单的时候,不直接调用生成订单的接口,而是将订单信息发送到MQ中,利用Mq队列先进先出的特性,一个是使用MQ系统做缓冲作用,还有就是作为MQ的消费者,一定是一个一个处理订单,所以,减少了订单系统的压力,也减少了并发。

三、订单系统流程

猜你喜欢

转载自blog.csdn.net/yueluoqianjiang/article/details/84951735