背景

昨天一个同事,在修改代码时不小心把cursor batch size的配置去了。导致线上请求时间增加,请求处理不过来,部分请求超时。

默认行为分析

// 不设置 cursorBatchSize 时,MongoDB 使用默认值
Query query = new Query()
    .with(Sort.by(Direction.DESC, "gtime"))
    .limit(1000);
// 等效于 cursorBatchSize = 0(使用驱动默认值,通常是101或1000)

// MongoDB 驱动的默认行为:
// 1. 首次批量:返回 limit 或 101 条中的较小值
// 2. 后续批量:返回 4MB 数据量能容纳的文档数
# 默认 cursorBatchSize 的影响:

情况一:limit <= 101
  - 首次返回所有数据
  - 没有问题

情况二:limit > 101(例如 limit=1000)
  - 首次返回101条
  - 需要9次 getMore 操作获取剩余数据
  - 每个 getMore 都是一次网络往返

情况三:分片环境(你的情况)
  - 每个分片首次返回101条
  - mongos 聚合后返回客户端101条
  - 客户端需要更多数据时发送 getMore
  - getMore 可能到不同的分片节点
  - 部分分片响应慢 → 游标超时

结论

设置合适的 cursorBatchSize

  • 减少网络往返次数

  • 降低游标超时概率

  • 提高查询性能