写在前面
设计好一套面向用户的订单存储架构,是一个大型交易系统中必要且重要的一项工作。那么该如何设置一个健壮且功能全面的面向C端订单架构呢? 我们可以YY出一些场景去挑战我们的设计方案,让方案更加健壮。
试想下,如何设计一个面向C端场景的订单存储呢?如何实现用户无限下滑分页获取订单呢?
问题分析
这个需求表面上看是一个关于分页的需求,本质上是一个面向冷热数据查询的解决方案处理的需求。不管冷热数据,需要处理的都是搜索效率的问题。
为了我们系统设计的更加健壮,我们不能简单的面向一个场景去进行系统设计,是否有多个功能上可以挖掘出类似的需求?比如个人订单列表,商家订单列表,如果是个saas产品,是否存在多租户情况下的订单列表呢?
以产品角度考虑,可能需要提供月度订单,年度订单,限制条件查询订单等分页逻辑。同时考虑是否需要在效率,准确性等角度去和PM做PK。
做好了假设之后,我们反过来梳理我们需要处理的需求,并考虑方案设计。
解决方案
首先面对的是亿级订单场景,单量庞大。针对大数据量,采用的通用策略一般是进行水平拆分,分库分表等方式,这种方式主要解决的是热数据。 比如分库10个,每个服务1台物理机,这种方式的缺点是存在资源浪费的情况。随着单量增长不可能无限存储。
针对这种场景我们首先想到的是对冷热数据做拆分,可以对历史数据做归档(比如3年前的订单)进行归档,这样的话,我们可以将冷数据放入其他持久化存储进行处理,热数据可以采用关系数据库水平拆分做处理。
有人会说将YY场景想的更变态一些,如果冷数据依然需要被查询或者被写入修改,那么这部分冷数据就不会成为冷数据了,变成了“半热数据”,因此还是对查询效率有要求对,归档的数据不能满足这种需求了。
OK既然是个需求,我们看看业界对于这种场景是否有一定的支持和实现呢?
对比了业内同类产品:
- 京东只显示14年之后的单子(14年前的估计存到ES里了)
- 滴滴是按月查询(估计是按时间维度分表)
- 美团外卖只显示1年内订单(ES+tair)
- 淘宝可以无限查询(不需要额外的时间维度,可以一直下拉分页查询)
所以业界主流解决方案对于这种大数据量级存储,都是采取冷热数据区分的。当然淘宝还是比较特殊,我们继续讨论下用户使用角度是否有其他的约束。
- 不接受只显示近期订单(比如只显示2年内订单)
- 不接受用户复杂操作,比如滴滴那样需要按月查
- 不接受查询效率过慢
综上,淘宝那种是如何存储的呢?
淘宝订单存储方案
没有接触过淘宝的订单存储方案,但是之前和淘宝的同学聊过类似亿级在线数据的处理方案,可以YY下其习惯性设计方案。
无限存储可以采用分布式数据库解决,业界有TiDB,阿里有OceanBase,对于C端高并发场景来说可能存在一定时延问题。随着业务的高速发展,以前亿级订单可能很快就膨胀到十亿,百亿了。
我们还是以冷热数据处理这种问题,其实很多大数据量在线查询处理一般都是可以采用冷热数据区分处理的方式来解决的,冷数据还是需要借助于nosql,因为冷数据当热数据处理肯定是较小的需求场景,没有必要为一个较小的场景做过于复杂的设计。如果考虑冷数据在查询时的延迟问题,可以引入异步半热的处理方式,将所谓的冷数据热加载起来。
根据比较对于冷热数据采用不同存储介质带来的指标来看,热数据延迟在20ms左右,在涉及到深度分页场景,整个效率就直线下降。采用预加载方案,设计方案上需要一定的考量,这部分和业务场景挂钩。
预热处理方案的预热时机判断就是关键问题了。
如果还是避免不了去进行冷数据需要半热处理的需求时,可以考虑引入TiDB负责查询,其特点便于扩展和无限存储。
在写数据处理时,将多个分库分表数据统一写入一个合库。落地方案也比较简单。
当然冷数据还可以异构到tair,es中,简单查询场景应该不会太差,深度分页可以依赖于具体场景进行选择,比如es的scroll id去定位。
当然如果选择es进行冷数据处理,还需要考虑索引创建,如何做到无限存储需求等。
最后
文章整体以对话讨论的方式进行了面向亿级在线数据存储方案的设计,这种需求不只存在于订单场景,在线商品场景同样适用。可以进行知识的横向迁移。