项目背景

在开发运维平台时,需要实现日志分析功能。最初采用 MongoDB 直接查询的方式,但随着数据量增长,性能问题逐渐显现。本文记录了使用 Redis 缓存优化查询性能的实践经验。

性能问题分析

MongoDB 查询瓶颈

  1. 跨日期查询耗时长(几十秒)
  2. 日志数据量达到千万级
  3. lookup 联表查询性能差
  4. 索引优化效果有限

优化思路

  1. 使用 Redis 缓存热点数据
  2. 优化 MongoDB 查询方式
  3. 合理设置数据过期策略

实现方案

Redis 缓存实现

1
2
3
4
5
6
7
8
9
10
// Redis 扫描实现
let uuidList = [];
var stream = RedisStore.redis.scanStream({
match: `*${currentDay}:${this.radioValue}`,
count: 1000
});

for await (const resultKeys of stream) {
// 处理扫描结果
}

MongoDB 查询优化

1
2
3
4
5
const allTask = [];
await cursor.eachAsync((actionInfo) => {
allTask.push(this.processAction(actionInfo));
});
await Promise.all(allTask);

后续优化方向

  1. MongoDB 聚合优化

    • 研究数组数据处理方法
    • 优化聚合管道性能
    • 合理使用索引
  2. 数据分层存储

    • 热数据存入 Redis
    • 温数据存入 MongoDB
    • 冷数据考虑归档
  3. 备选方案

    • ELK 日志分析
    • ClickHouse 等列式存储
    • 时序数据库

经验总结

  1. Redis 缓存能显著提升查询性能
  2. 需要权衡数据一致性和查询性能
  3. 合理的数据分层存储很重要
  4. 监控和告警机制不可或缺

参考资料