美文网首页
MongoDB如何存储数据

MongoDB如何存储数据

作者: 蕴重Liu | 来源:发表于2019-07-28 22:55 被阅读0次

Memeory-Mapped Files

  • 内存映射文件是OS通过mmap在内存中创建一个数据文件,这样就把文件映射到一个虚拟内存的区域。
  • 虚拟内存对于进程来说,是一个物理内存的抽象,寻址空间大小为2^64
    操作系统通过mmap来把进程所需的所有数据映射到这个地址空间(红线),然后再把当前需要处理的数据映射到物理内存(灰线)
  • 当进程访问某个数据时,如果数据不在虚拟内存里,触发page fault,然后OS从硬盘里把数据加载进虚拟内存和物理内存
  • 如果物理内存满了,触发swap-out操作,这时有些数据就需要写回磁盘,如果是纯粹的内存数据,写回swap分区,如果不是就写回磁盘。
展示数据库是如何跟底层系统打交道
image.png

存储模型

image.png
  • 有了内存映射文件,要访问的数据就好像都在内存里面,简单化了MongoDB访问和修改数据的逻辑
  • MongoDB读写都只是和虚拟内存打交道,剩下都交给OS打理
  • 虚拟内存大小=所有文件大小+其他一些开销(连接,堆栈)
  • 如果journal开启,虚拟内存大小差不多翻番
  • 使用MMF的好处1:不用自己管理内存和磁盘调度2:LRU策略3:重启过程中,Cache依然在。
  • 使用MMF的坏处1:RAM使用会受磁盘碎片的影响,高预读也会影响2:无法自己优化调度算法,只能使用LRU
image.png image.png image.png
  • 磁盘上的文件是有extent构成,分配集合空间的时候也是以extent为单位进行分配的
  • 一个集合有一个或者多个etent
  • ns文件里面命名空间记录指向那个集合的第一个extent

数据文件与空间分配
当创建数据库时(其实MongoDB没有显式创建数据库的方法,在向数据库中的集合写入数据时会自动创建该数据库),MongoDB会在磁盘上分配一组数据文件,所有集合,索引和数据库的其他元数据都保存在这些文件里。数据文件被放在启动时指定的dbpath里,默认放入/data/db下面。典型的一个文件组织结构如下:

mongod.lock中存储了服务器的进程ID,是一个进程锁定文件。数据文件是依据所属的数据库命名的。

test.ns是第一个生成的文件(ns扩展名就是namespace的意思),
数据库中的每个集合和索引都有自己的命名空间,
每个命名空间的元数据都存放在这个文件里。

默认情况下,.ns文件大小固定在16MB,大约可以存储24000个命名空间。
也就是说数据库中的索引和集合总数不能超过24000,该值可以通过mongod的--nssize选项进行定制。

像test.0这样以0开始的整数结尾的文件就是集合和索引数据文件。刚开始的时候,
即使只有一条数据,MongoDB也会预分配几个文件,这种预分配的做法,能让数据尽可能连续存储,减少磁盘碎片。
在像数据库添加数据时,MongoDB会分配更多的数据文件。
每个新数据文件的大小都是上一个已分配文件的两倍(64M->128M->256M),直到预分配文件大小的上限2G。
此处基于一个假设,如果总数据大小呈恒定速率增长,
应该逐渐增加数据文件分配的空间。
当然这个预分配策略也是可以通过--noprealloc关掉,但是不建议在production环境下使用。

默认的local数据库,该数据库不参与replication。
当mongod是一个副本集的成员时,在local数据库中就有一个叫做oplog.rs的预分配的capped集合,预分配的大小为磁盘空间的5%。
这个大小可以通过--oplogSize进行调整。
oplog主要用于副本集Primary和Secondary成员见的replication,它的大小限制了两个副本集之间,
在重新完全同步之前,允许多长时间不同步。
journal目录,journal功能2.4版本默认是开启的。

可以使用db.stats()来确认已使用空间和已分配空间。

{
    "db" : "test",
    "collections" : 37,
    "objects" : 317894523,  #文档总个数
    "avgObjSize" : 232.3416429039893,  #单位是字节
    "dataSize" : 73860135744, #集合中所有数据实际大小(包括padding factor为每个文档分配的额外空间以允许文档增长)。该值在文档size变小的时候,这个值不会减少,除非文档被删除,或者执行compact或者repairDatabase操作
    "storageSize" : 97834319392, #分配给集合的空间大小(包括为集合增长预留的额外空间和未分配的已删除空间,即不会因为文档size变小或者删除而减小),实际上从数据文件中分配给集合的空间是以块为单位,也称之为extents,即分配的extents的大小
    "numExtents" : 385,
    "indexes" : 86,
    "indexSize" : 58687466992,
    "fileSize" : 182380920832, #所有数据文件大小之和,不包括命名空间文件(ns文件)
    "nsSizeMB" : 16,
    "dataFileVersion" : {
        "major" : 4,
        "minor" : 5
    },
    "ok" : 1
}

使用db.accesslog.stats()确认某个集合的使用量


{
    "ns" : "test.accesslog",
    "count" : 145352932,
    "size" : 37060264352, #实际数据大小,不包括索引
    "avgObjSize" : 254.967435758365,
    "storageSize" : 45794676448, #预分配的数据存储空间
    "numExtents" : 42,
    "nindexes" : 4,
    "lastExtentSize" : 2146426864,
    "paddingFactor" : 1, #当文档因更新size增长时事先padding可以提速,减少碎片的产生
    "systemFlags" : 1,
    "userFlags" : 0,
    "totalIndexSize" : 31897944512,
    "indexSizes" : {
        "_id_" : 6722168208,
        "action_1_time_1" : 8606482752,
        "gz_id_1_action_1_time_1" : 10753778336,
        "time_1" : 5815515216
    },
    "ok" : 1
}

相关文章

  • MongoDB地理数据模型 (地理位置信息) --- 2022-

    本章介绍MongoDB地理空间数据如何存储,我们要想使用MongoDB地理信息查询功能,首先得了解如何存储地理空间...

  • MongoDB

    MongoDB简介 MongoDB 是一个基于分布式文件存储的数据库。 MongoDB存储模式 数据库存储集合,集...

  • MongoDB如何存储数据

    Memeory-Mapped Files 内存映射文件是OS通过mmap在内存中创建一个数据文件,这样就把文件映射...

  • mongodb学习笔记

    1、MongoDB特点 面向集合存储:MongoDB 是面向集合的,数据以 collection 分组存储。每个 ...

  • MongoDB 基础浅谈

    1 MongoDB 特点 面向集合存储:MongoDB 是面向集合的,数据以 collection 分组存储。每个...

  • MongoDB初识及启动

    mongoDB的存储结构 数据库->集合->子集合->文档 文档:是mongoDB存储数据的最小集合,就是js的一...

  • 0405-MongoDB

    MongoDB旨在为web应用提供可扩展的高性能数据存储方案MongoDB将数据存储为一个文档,数据结构由键值对(...

  • (十二)学习笔记:MongoDB数据库总结

    MongoDB数据库 MongoDB将数据存储为文档 数据结构由键值对组成的,MongoDB的文档类似于json对...

  • 搭建个人Leanote云笔记

    1. 下载启动MongoDB Leanote依赖MongoDB作为数据存储,下面开始安装MongoDB 下载Mon...

  • Ansible Role 数据库 之【mongodb】

    Ansible Role: Mongodb 安装Mongodb 介绍 MongoDB是一个基于分布式文件存储的数据...

网友评论

      本文标题:MongoDB如何存储数据

      本文链接:https://www.haomeiwen.com/subject/ykymrctx.html