mongodb的优势,相较于mysql?
- 二进制json数据
- 文档存储,同一集合内的每个文档,可以包含不同的字段和嵌套结构,不需要像mysql一样,单个表内字段都是一致的(动态字段)
- 可以通过
自动分片
进行水平拓展,比mysql更方便
分片键:可以选择高频查询字段如
用户id
作为分片依据,常用的还有以时间字段
来分片(主要有两种分片键:范围分片,哈希分片,复合分片)
MongoDB 分片需先搭建含
分片节点
、配置服务器
和路由节点
的集群,为目标数据库启用分片
,选择合适字段(如高基数字段)创建分片键索引
,再为集合指定
该分片键开启分片
,数据将按分片键规则(范围或哈希)自动
分布到各分片,应用通过路由节点
透明访问
。
- 内存存储,性能强于mysql
- 查询能力丰富,聚合、地理查询、全文索引
- 自动故障转移,数据备份
追问自动故障转移和备份细节?
先分析架构,可以是一主多从,主节点宕机,通过raft协议在从节点选举
通过多数投票,(>50%节点同意)选举,
备份:使用 oplog 支持精确到秒的数据回滚,写操作由主节点处理,然后数据通过opog(操作日志)同步到从节点
- mysql主要是
存储+基础查询
,而mongo计算功能强大,可以实现边存储边分析
,避免了原来从数据库获取大量元数据到业务层进行计算,而直接交由mongo进行计算,减少大量网络开销
总的来说,mongo是牺牲了部分事务功能,获取更强的读写速度,和数据处理能力
讲一下mongodb的索引使用,优化
常用索引类型
- 单字段索引:最常用
- 复合索引:多个字段组合。
遵循最左前缀原则
- 唯一索引:保证字段唯一性。
- TTL 索引:数据过期自动删除(常用于日志/缓存)。
- 稀疏索引:只给部分文档建索引,节省空间。
所谓稀疏索引:仅包含具有索引字段的文档,跳过缺少该字段的文档。(字段为nil跳过)
- 全文索引:支持文本搜索。
- 地理空间索引:支持位置查询。
优化原则
高选择性字段优先建索引
- 选择性 = 唯一值 / 总行数,选择性越高,索引效果越好。
- 比如
userId
(选择性高)适合建索引,而gender
(选择性低,只有男女)就不适合单独建索引。
复合索引遵循最左前缀原则
{ city: 1, age: 1 }
可以支持:- 查询
city
- 查询
city + age
- 查询
但 不能直接支持 只查
age
。
覆盖索引(Covering Index)
- 查询只涉及索引中的字段,不用回表,性能更高。
- 示例:索引
{ name: 1, age: 1 }
,查询db.users.find({ name: "Tom" }, { name: 1, age: 1, _id: 0 })
就是覆盖查询。
排序与索引
- 索引字段顺序会影响排序性能。
- 如果有
{ city: 1, age: -1 }
索引,按city 升序、age 降序
查询就能走索引排序,否则可能触发内存排序。
-
- 使用
explain()
查看查询计划,确认是否走索引。
- 使用
explain三阶段解读:【MongoDB】查询计划解析,各字段理解
- 频繁更新/删除文档会导致
索引碎片化
,定期重建碎片化索引
MongoDB的事务是如何实现的?如何实现ACID?
- 4.0 之前只支持单文档事务, 4.0 开始支持多文档事务(Replica Set),4.2 开始支持 分片集群事务。
4.0 – 4.2:只支持单副本集(单分片)的多文档事务,即:(事务不能跨越多个分片(shard);只能在单个replica set内部执行)
4.2 之后支持多分片多文档事务
- 事务保证 ACID(原子性、一致性、隔离性、持久性)。
- 开启事务:
session.startTransaction()
- 提交事务:
session.commitTransaction()
- 回滚事务:
session.abortTransaction()
MongoDB 事务如何保证 ACID
1. 原子性(Atomicity)
含义:事务中的操作要么 全部成功,要么 全部失败。
实现:
- 单文档操作天然原子性(更新/替换/插入一个文档时,MongoDB 保证原子性)。
- 多文档事务依赖 oplog 记录,如果中途失败,通过 回滚 保证要么全成,要么全撤销。
2. 一致性(Consistency)
含义:就是数据的一致性,具体来说,a,b都有500元,那么总钱数1000,a向b转300,总钱数应该保持不变,而不是1300或者700
实现:
- 写入过程中如果事务失败,回滚前置操作,保持数据逻辑不被破坏。
- 可结合 写关注(Write Concern) 设置,保证数据在足够多节点确认后才算成功,从而防止数据丢失。
3. 隔离性(Isolation)
含义:并发事务之间互不干扰,就像事务是串行执行的。
实现:
- MongoDB 默认采用 快照隔离 (Snapshot Isolation) 的读关注机制:每个事务在开始时看到一个数据快照。
- 读写冲突时,事务会重试,确保最终效果等同于串行执行。
4. 持久性(Durability)
含义:事务一旦提交,数据必须 永久保存,不会因为宕机丢失。
实现:
- 提交事务时,操作会写入 oplog(复制日志) 和 WiredTiger 日志(实际上就是mysql的WAL预写入日志)。
所谓预写入日志:当写操作发生时,MongoDB 会先把变更写入 日志文件,再应用到磁盘数据文件。
万一系统宕机,可以通过 日志重放(replay) 恢复未写入的数据,保证 持久性(Durability)- 结合 写关注 + 副本集复制,保证提交的数据持久化到磁盘,并同步到多个节点。
所谓“写关注 + 副本集复制”,即:
写操作需要多少节点确认成功
+Secondary(从) 节点通过读取 Primary(主) 的 oplog 来 同步数据
MongoDB的数据复制机制是如何工作的?如何保证数据的一致性?
MongoDB使用副本集(Replica Set)来保证数据的
高可用性
和一致性
1. 副本集架构
- Primary(主节点):接受所有写请求和大部分读请求,并记录
oplog
供 Secondary 同步。 - Secondary(从节点):从 Primary 同步数据,可配置为读请求节点,但可能存在延迟。
- Arbiter(仲裁节点):不存储数据,只参与选举,避免因节点数过少导致选举失败。
2. 数据同步
- Primary 接收到写操作后,会记录到本地
oplog
(操作日志)。 - Secondary 节点会轮询 Primary 的
oplog
,将新操作应用到自身数据,实现复制。
3. 选举机制
- 当 Primary 故障时,副本集会在 十几秒内自动发起 选举。
- 通过多数投票选出新的 Primary,保证故障恢复和数据可用性。
4. 写关注级别(Write Concern)
写操作需要多少节点确认才算成功
w:1
:主节点确认写入即返回,最快,一致性最弱。w:"majority"
:大多数节点确认,性能与一致性平衡。w:"all"
:所有节点确认,一致性最强,最慢。
5. 读关注级别(Read Concern)
读操作能看到什么级别的数据。
local
:读本地已提交数据,性能最好,但一致性最弱。majority
:读取大多数节点确认的数据,保证不会读到未持久化的数据。snapshot
(事务中常用):- 在事务开始时生成一致性快照,事务内所有读都基于这个快照。
- 保证事务内部看到的数据是一致的,避免“读到一半被别人修改”。
linearizable
:保证读取的都是最新已提交数据,一致性最强。
写关注解决“写了数据,到底多少节点确认才算安全”。
读关注解决“读数据,到底读到的有多新、多可靠”。
两者就是在 性能、可用性、一致性 之间的平衡选择。
MongoDB 副本集通过 主从架构 + oplog 复制 + 自动选举 实现高可用。结合 写关注级别 (w) 和 读关注级别,在性能和一致性之间做灵活权衡。
讲一下聚合查询
- 聚合aggregate,是一种数据处理管道,通过对管道
分多阶段
(过滤,分组,排序,统计等)来进行,数据的操作
- 常见操作符:
$match
:过滤(类似 WHERE)$group
:分组 & 聚合(类似 GROUP BY + 聚合函数)$sort
:排序$project
:字段投影(选择要返回的字段,可做计算/重命名)$limit , $skip
:分页$lookup
:表关联(类似 JOIN)$unwind
:数组拆分
- 聚合管道让 MongoDB 不只是存储,还能承担计算任务。
MongoDB 副本集 Raft 风格选举机制
1. 核心目标
- 保证副本集 只有一个 Primary。
- 当 Primary 宕机或不可用时,快速选出新的 Primary,保证系统 高可用和一致性。
2. 触发条件
- Primary 节点宕机。
- 网络隔离导致 Primary 无法与大多数节点通信。
- 心跳超时(默认 10 秒未收到 Primary 心跳)。
所谓心跳超时,就是用来判断,什么条件下主节点宕机的
3. 选举流程
Secondary 发现 Primary 不可用 → 进入候选状态(Candidate)。
发起投票:
- 每个节点只投一次票给候选节点。
- 需要 多数节点(Majority) 同意才能当选。
胜出节点成为 Primary:
- 新 Primary 开始接受写请求。
- 其它 Secondary 节点继续同步数据。
选举超时机制:
- 每个节点随机一个选举超时,避免多个节点同时发起选举导致冲突。