Redis和MongoDB是国内后端开发中使用频率最高的两个NoSQL产品,面试里也经常被放在一起提问。但不少人对它们的理解停留在“一个快、一个能存复杂结构”的层面,实际选型时容易犯迷糊:到底该用哪个?能不能一起用?本文从底层设计到应用场景,把两者的差异一次性讲清楚。

一、先看本质:两者的定位就不同
Redis诞生于2009年,作者是Salvatore Sanfilippo,最初的目标就是解决高并发场景下的访问延迟问题。它是一个基于内存的键值存储,所有数据默认放在内存中,磁盘只是用来做持久化备份,因此单机读写性能可以达到每秒十万次以上。
MongoDB则是面向文档的数据库,数据以BSON格式存储在磁盘上,通过内存映射文件来加速访问。它的核心目标是解决关系型数据库表结构僵硬的问题,让开发者可以用类似JSON的文档灵活地存储数据,同时保留较为完整的查询能力。
简单说,Redis解决的是“快”的问题,MongoDB解决的是“灵活”的问题。拿它们直接比谁更好,就像拿跑车和货车比谁更强,用途不同,结论自然不同。
二、数据模型与查询能力的差异
Redis的数据模型是key-value结构,value可以是字符串、哈希、列表、集合、有序集合等类型。每种类型都对应一组原子操作命令,比如对列表执行LPUSH、RPOP,对有序集合执行ZADD、ZRANGE。但Redis没有查询语言,你不能像SQL那样写条件查询,只能通过key去定位数据。
MongoDB存储的是文档,一条记录就是一个JSON风格的文档,支持嵌套对象和数组。它提供了功能强大的查询语言,支持条件过滤、排序、分页、聚合管道(Aggregation Pipeline),还支持创建二级索引,包括单字段索引、复合索引、全文索引和地理位置索引。
举个例子,同样是存储一篇文章数据,MongoDB可以这样查询:
// MongoDB:查找某个作者在指定时间后发布的、浏览量最高的5篇文章
db.articles.find({
author: "张三",
createTime: { $gt: ISODate("2024-01-01") }
}).sort({ views: -1 }).limit(5)
而Redis要实现同样的效果,你需要自己设计数据结构,比如用有序集合维护浏览量排名,再用哈希存储文章详情,代码复杂度和维护成本明显更高。反过来看,如果只是判断一个key是否存在、给计数器加一、获取排行榜前十名,Redis一条命令就能搞定,延迟在亚毫秒级别,这是MongoDB比不了的。
三、持久化机制与数据可靠性对比
Redis提供两种持久化方式:RDB和AOF。RDB是定时生成内存快照,文件紧凑、恢复快,但两次快照之间的数据可能丢失;AOF记录每条写命令,可以配置成每秒刷盘,数据安全性更好,但文件更大、恢复更慢。实际生产中通常两者结合使用,即便如此,Redis在极端宕机情况下仍可能丢失最后一秒左右的数据。
MongoDB的数据主要落在磁盘上,默认使用WiredTiger存储引擎,写操作先写日志再刷盘,支持副本集实现主从自动切换。只要副本集配置合理并开启了写关注(Write Concern),数据可靠性是有保障的,金融级别的业务也可以接受。
所以在数据可靠性维度,MongoDB更适合做“主存储”,Redis更适合做“缓存或临时数据”。把订单、交易等核心数据只存在Redis里,是一种风险很高的做法。
四、适用场景与选型建议
结合上面的差异,两者的典型场景可以这样划分:
- Redis擅长的场景:热点数据缓存、会话存储(Session共享)、分布式锁、计数器、排行榜、消息队列(List或Stream)、限流接口。
- MongoDB擅长的场景:商品信息、日志记录、用户画像、内容管理系统、IoT数据存储、字段结构多变的业务数据。
实际项目中,两者配合使用是最常见的方案。以一个电商商品详情页为例,整体的读写流程如下:
public Product getProduct(String id) {
// 1. 先查Redis缓存
String key = "product:" + id;
String cached = redis.get(key);
if (cached != null) {
return JSON.parseObject(cached, Product.class);
}
// 2. 缓存未命中,查MongoDB
Product product = mongoTemplate.findById(id, Product.class);
if (product != null) {
// 3. 写回缓存,设置过期时间防止数据长期不一致
redis.setex(key, 3600, JSON.toJSONString(product));
}
return product;
}
这套“Redis做缓存、MongoDB做主库”的组合,既保证了高并发下的响应速度,又兼顾了数据的可靠性和查询灵活性。需要注意的是,更新数据时要处理好缓存一致性问题,常用策略是先更新MongoDB再删除缓存,而不是直接更新缓存。
五、总结
MongoDB和Redis不存在谁替代谁的关系。如果你的系统需要存储结构复杂、需要灵活查询的业务数据,选MongoDB;如果需要极致的读写速度来做缓存、计数或排行榜,选Redis。数据量上来之后,绝大多数中大型系统都会同时使用两者,让它们各自发挥所长。理解了“内存键值存储”和“磁盘文档数据库”这两个本质定位,选型问题也就迎刃而解了。