想要深入了解MongoDB如何存储数据之前,有一个概念必须清楚,那就是Memeory-Mapped Files。
Memeory-Mapped Files
下图展示了数据库是如何跟底层系统打交道的。
- 内存映射文件是OS通过mmap在内存中创建一个数据文件,这样就把文件映射到一个虚拟内存的区域;
- 虚拟内存对于进程来说,是一个物理内存的抽象,寻址空间大小为2^64;
- 操作系统通过mmap来把进程所需的所有数据映射到这个地址空间(红线),然后再把当前需要处理的数据映射到物理内存(灰线); (这可以理解成,在数据声明时数据是放在虚拟内存中的,数据声明的作用就是说明进程中用哪些数据,但并不需要指定用到什么样的数据,这时只说明它的地址并不涉及到具体的数值,即并不进行实例化,而如果对象实例化,则会在虚拟内存中映射到物理内存中)
- 当进程访问某个数据时,如果数据不在虚拟内存里,触发page fault,然后OS从硬盘里把数据加载进虚拟内存和物理内存;
- 如果物理内存满了,触发swap-out操作,这时有些数据就需要写回磁盘,如果是纯粹的内存数据,写回swap分区,如果不是就写回磁盘。
MongoDB的存储模型
- 有了内存映射文件,要访问的数据就好像都在内存里面,简单化了MongoDB访问和修改数据的逻辑
- MongoDB读写都只是和虚拟内存打交道,剩下都交给OS打理
- 虚拟内存大小=所有文件大小+其他一些开销(连接,堆栈)
- 如果journal开启,虚拟内存大小差不多翻番
- 使用MMF的好处:
- 1:不用自己管理内存和磁盘调度
- 2:LRU策略
- 3:重启过程中,Cache依然在
- 使用MMF的坏处:
- 1:RAM使用会受磁盘碎片的影响,高预读也会影响
- 2:无法自己优化调度算法,只能使用LRU