前言
本文主要介绍了关于MongoDB存储数据的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍:
想要深入了解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
- 磁盘上的文件是有extent构成,分配集合空间的时候也是以extent为单位进行分配的
- 一个集合有一个或者多个etent
- ns文件里面命名空间记录指向那个集合的第一个extent
数据文件与空间分配
当创建数据库时(其实MongoDB没有显式创建数据库的方法,在向数据库中的集合写入数据时会自动创建该数据库),MongoDB会在磁盘上分配一组数据文件,所有集合,索引和数据库的其他元数据都保存在这些文件里。数据文件被放在启动时指定的dbpath里,默认放入/data/db下面。典型的一个文件组织结构如下:
$ cat /data/db $ ls -al -rw------- 1 root root 16777216 09-18 00:54 local.ns -rw------- 1 root root 67108864 09-18 00:54 local.0 -rw------- 1 root root 2146435072 09-18 00:55 local.1 -rw------- 1 root root 2146435072 09-18 00:56 local.2 -rw------- 1 root root 2146435072 09-18 00:57 local.3 -rw------- 1 root root 2146435072 09-18 00:58 local.4 -rw------- 1 root root 2146435072 09-18 00:59 local.5 -rw------- 1 root root 2146435072 09-18 01:01 local.6 -rw------- 1 root root 2146435072 09-18 01:02 local.7 -rw------- 1 root root 2146435072 09-18 01:03 local.8 -rw------- 1 root root 2146435072 09-18 01:04 local.9 -rw------- 1 root root 2146435072 09-18 01:05 local.10 -rw------- 1 root root 16777216 09-18 01:06 test.ns -rw------- 1 root root 67108864 09-18 01:06 test.0 -rw------- 1 root root 134217728 09-18 01:06 test.1 -rw------- 1 root root 268435456 09-18 01:06 test.2 -rw------- 1 root root 536870912 09-18 01:06 test.3 -rw------- 1 root root 1073741824 09-18 01:07 test.4 -rw------- 1 root root 2146435072 09-18 01:07 test.5 -rw------- 1 root root 2146435072 09-18 01:09 test.6 -rw------- 1 root root 2146435072 09-18 01:11 test.7 -rw------- 1 root root 2146435072 09-18 01:13 test.8 ... -rwxr-xr-x 1 root root 6 09-18 13:54 mongod.lock drwxr-xr-x 2 root root 4096 11-13 18:39 journal drwxr-xr-x 2 root root 4096 11-13 19:02 _tmp
- 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 }
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]