mongodb订单分片优化方案

——持续更新中

1. 背景说明

目前因业务量激增,系统已将订单存储从原有的mysql迁至新的mongo集群,在试运营过程中,主要遇到以下问题:

  • 单机磁盘资源瓶颈,目前单表已经占用20g
  • 单机读写能力瓶颈,读能力可以在复制集里加 secondary 节点来扩展,但CPU、内存或者网卡等资源遭遇瓶颈,导致读写能力无法扩展

我们目前已经是3主3从的mongocluster,因上线时间较短,订单表目前仅为副本集模式,还没来得及sharding模式,考虑年底500K/日的下单指标,推进订单的sharding操作刻不容缓。

2. 优化目标

sharding后对系统对读性能将有非常大的影响,这种场景和传统数据的sharding是相同的。目前我们主要以场景为维度来确定此次优化的预期目标:

  • c端用户查询我的订单列表:rtt<=100ms,tps>=2000
  • b端用户查询商户订单列表:rtt<=500ms,tps>=500
  • 其它条件范围查询:rtt<=500ms,tps>=1000
  • 其它条件单条查询:rtt<=100ms,tps>=2000

3. sharding方案

3.1 分片说明

mongo主要支持2种数据分布的策略,范围分片(Range based sharding)和hash分片(Hash based sharding)。

  1. 查询请求
  • 查询请求不包含shard key,则必须将查询分发到所有的shard,然后合并查询结果返回给客户端
  • 查询请求包含shard key,则直接根据shard key计算出需要查询的chunk,向对应的shard发送查询请求
  1. 写请求
  • 写操作必须包含shard key,mongos根据shard key算出文档应该存储到哪个chunk,然后将写请求发送到chunk所在的shard。
  1. 更新/删除请求
  • 必须包含shard key或者_id
  • 包含shard key,则直接路由到指定的chunk
  • 只包含_id,则需将请求发送至所有的shard
  1. 其它命令请求
  • 除增删改查外的其他命令请求处理方式都不尽相同,有各自的处理逻辑,比如listDatabases命令,会向每个Shard及Config Server转发listDatabases请求,然后将结果进行合并。

3.2 方案对比

在两种分片的基础上我们讨论以下几个方案的优劣:

  1. 按时间范围分片
  • 数据将按时间段连续的写入同一个shard上
  • 大跨度时间查询时,无论c端维度或b端维度均要全分片扫描 X
  • 单记录查询需要指定时间+订单id X
  • 实施成本:低

特点:适用于连续日志类型

  1. 按地域hash分片
  • 同一个地域的订单会落在同一个shard上
  • 同一商户只在同一地域方便查询
  • 同一商户在不同地域全shard扫描
  • 同一用户在不同地域充电的场景下需要全shard扫描
  • 实施成本:低

特点:适用于地域独立性强,不同地域无交集场景

  1. 按商户hash分片
  • 同一个商户的订单会落在同一个shard上
  • b端商户性能:优
  • c端客户查询:弱,客户深度分页时可能崩溃
  • 实施成本:低
  1. 按客户hash分片
  • 同一个用户的订单会落在同一个shard上
  • b端商户性能:弱,商户深度分页时可能崩溃
  • c端客户查询:优
  • 实施成本:低
  1. 商户和客户冗余分片
  • 此方案下需要同时准备两张相同的订单表,一张商户hash,另一张客户hash
  • 以商户维度查询时查商户订单表
  • 以客户维度查询时查客户订单表
  • 性能问题:优
  • 实施成本:极高

3.3 方案确认

目前mongo的主要场景即为客户查询和商户查询,

下方估计场景:

  • 客户查询频率约:90%,商户查询频率10%
  • 客户订单查询时长:约3个月,商户订单汇总时长:约1年
  • 客户订单3月数量:200记录/月,商户订单1年,数十万级别
  •  

 

方案

商户查询性能

客户查询性能

查询频率

写入性能

综合评估

商户hash

深度分页时级低,但客户数据量少,出现深度分页的机率非常低

非常高

影响小

待定

客户hash深度分页时极低极高

较低

影响小

待定

 

目前能确定的两个焦点:

 

#考虑到的简单的性能影响计算规则:
shard_count*0.9+order_count/10*0.1
#商户分片时,
#c端范围查询的劣势:全shard扫描,并且频率非常高,约90%
#性能影响度:因单个客户的订单列表量较小,不会引起深度分页
#计算:
3*0.9+200=200+
#客户分片时,
#b端范围查询的劣势:全shard扫描,但频繁低,约10%
#性能影响度:单个商户订单列表量极大,会引起深度分页
#计算:
3*0.1+100000/10*0.9=10000000+

 

4. 优化说明

在满足业务要求的前提下,灵活根据分片原理、索引以最达到大性价比

  • 分片范围查询时尽量加上shardkey,若以B端hash,此时可以加商户id,但以c端而不能加
  • 查询记录查询时尽量加shardkey,若不加则会全shard扫描,在一个shard找到即返回
  • 在数据深分页时,无论分不分片,页数较深时使用skip方式仍然影响性能。此时需要通过>lastelement方式实现
  • 在分片场景下,深分页压力较大时,应该在缩小范围的前提下再进行分页操作。如商户订单上百万,分页的话查询后面的页数系统压力非常大,可以先通过把时间段缩小,这样订单量缩小至10万级别,页数没那么多,此时问题即从产品方面解决了
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值