一、mongo存储结构、索引
1、mongo索引底层实现
mongo索引底层通过B+树实现,B+树是一种自平衡的二叉树,有两个特点:(1)所有数据都存在叶子节点(2)叶子节点通过指针相连组成单链表
由于树高稳定所以查询性能稳定,且更适合范围查找。mongo官方文档提到mongo索引时B树,其实是B+树。
2、mongo存储结构
3部分组成:文档(相当于记录行)、集合(相当于表)、数据库

二、mongo性能调优
1、通过pipeline实现批量更新(4.x引入的新特性)
2、通过findAndModify(原子操作)来替代传统的query+update的方式,并发场景更安全
3、通过设置读写篇好实现mongo读写分离,比如:
(1)设置读偏好:readPreference=secondary(表示读从节点,此时读请求会被分发到任意一个从节点)
(2)设置写篇好:writeConcern(表示写入几个节点才算确认写入成功)
4、字段整合替代(通过整合复杂字段,使用一个新的简单类型字段替换,来替代复杂的对象数据查询)
5、优化索引(比如通过mongostat、explain命令分析慢查询语句,进而优化查询sql)
三、mongo的副本集和分片集群
mongo的副本集和分片集群是两种不同的高性能架构方案。
副本集所有的节点存储相同的数据副本,而分片集群则是数据被分割成块,被分不到不同的分片上,每个分片只存储一部分数据。所以副本集适用于需要高可用性和数据保护的场景,例如对数据一致性要求较高的应用,分片集群适用于需要处理大规模数据和高并发访问的场景,例如大数据分析、实时数据处理等。
四、mongo支持事务吗?
3.6或更高版本的副本集或分片集群支持。
(1)事务隔离级别
与mysql的4大隔离级别不同,mongo只支持“可重复度”隔离级别(我们知道RR(ReadRepeat)隔离级别是快照读,也就是事务开启时会创建一个读视图,一直到事务提交的时间段内,读视图不变,这也就实现了可重复读)。而且mongo“可重复读”的事务隔离级别实现原理同mysql类似,也是通过mvcc机制实现。
(2) 实现方式不同
mysql是通过隐藏列+undoLog+读视图(readView)来维护版本信息。
mongo是通过事务系统+版本控制机制来实现,事务开始前创建快照,保证事务期间读数据的一致性
五、mongo存储引擎了解吗?
WiredTiger存储引擎。
1、WiredTiger的内存管理策略
WiredTiger通过内存中的缓存来提升读写性能,通过LRU-K算法保障缓存命中率。mongo的所有写操作都会预先写入到JournalLog(预写日志文件)中,然后再写入内存中的缓冲区(内存表MemTab),然后根据配置定期刷新到磁盘。
2、WiredTiger的故障恢复机制
通过checkPoint(检查点)+journalLog(预写日志)机制实现故障恢复。当系统故障时,可以通过检查点+预写日志实现故障恢复。
3、关于内存表MemTab
内存表通过SLM树(日志结构合并树)实现,SLM树底层通过跳表或平衡二叉树实现。内存表主要用于暂存写入的数据。mongo收到一个写请求,数据会先写入到Jounal日志为了做崩溃恢复,然后数据被写入到一个内存表,当内存表(MemTab)的大小超过阈值的时候,当前MemTab会被冻结同时启动一个新的MemTab接收写数据,mongo会定期把MemTab数据刷新到磁盘。
4、WiredTiger支持数据压缩
通过前缀压缩等方式减少磁盘占用和IO开销。
5、WiredTiger的并发控制机制
WiredTiger通过MVCC保证可重复读,同时通过锁机制(文档级锁+乐观锁相结合的方式)有效避免幻读问题。
(1)并发写入机制
多个线程写操作可以同时修改同一集合中的不同文档,互不干扰
(2)写冲突处理
当多个写操作同时修改同一文档时,必须串行执行,mongo采用冲突重试策略。