mongodb——内存

sort操作内存溢出

报错

  exception: getMore runner error: Overflow sort stage buffered data 
  usage of 33638076 bytes exceeds internal limit of 33554432 bytes

这个异常出自mongodb的sort操作。当mongodb无法从索引获取排序顺序时,会在内存中执行排序(top-k排序)。而mongodb的排序内存默认只有32MB,如果排序的结果超过32MB会抛出异常。
解决这个问题有两种方式:

  1. 增大mongodb的排序内存,默认是32MB,可以视情况增大。
  2. 在排序的字段上增加索引。如果sort有索引,mongodb不会在内存中执行排序操作,而是直接通过索引进行排序。

mongodb内存管理

mongodb会把所有内存全部用光。
mongodb使用内存映射存储引擎,它会把磁盘IO转化为内存操作。读数据时,直接从内存读取数据;写数据时,将随机写转化为顺序写。mongodb不干涉内存管理,将内存管理工作交给操作系统去处理。在使用时必须随时监测内存使用情况,因为mongodb会把所有能用的内存都用完。

虚拟内存

操作系统把当前程序使用的部分内存保留在物理内存中,把其他没有使用的部分保留在磁盘中,并在使用时将这部分数据调入物理内存中。应用程序访问虚拟内存地址,由操作系统将虚拟内存映射到实际内存中。

Linux硬盘有一个swap区域,这是磁盘交换空间,当物理内存不足时,操作系统会在swap上保存数据。

内存映射

内存映射是一个文件到一块内存的映射,使应用程序可以通过内存指针对磁盘上的文件进行访问。其过程就像对加载了文件的内存访问。
在映射过程中,并没有实际的数据拷贝,文件并没有被放入内存,只是逻辑上放入了内存。具体到代码,就是建立并初始化了具体的数据结构。当要操作数据的时候,才会将文件数据从硬盘读入内存,如果物理内存不够用,则会使用swap空间。
内存映射比普通文件操作效率高,原因是普通文件读取执行了两次数据拷贝(硬盘-->内核空间-->用户空间),内存映射只进行了一次数据拷贝(硬盘-->用户空间)。而且普通IO操作从用户态转为内核态的不断切换十分耗时,内存映射省去了这个转换。

不推荐mongodb热数据超过物理内存大小。如果超过,操作系统会在物理内存和磁盘swap之间频繁交换数据,影响性能。

mongodb存储

mongodb将数据存放在磁盘文件上,一个数据文件有多个events组成,每个event可以保存集合数据或者索引数据(集合和索引数据不会区分保存)。每个events只保存一个集合的数据,不同集合的数据分散在不同的events中,一个集合的数据也被拆分在不同的events中。每个event保存的是单个文档数据。索引数据也是如此。collection的events信息被保存在命名空间文件中,只保存第一个event的信息,然后event之间通过双向链表组成events。event有额外的冗余空间padding,以便在数据更改的时候不用移动数据。
关于数据文件大小,从64M开始,每次新增数据文件,大小是上一个文件的两倍,直到2G为止。而且mongodb使用预分配,在当前数据文件快要用完时提前创建新的数据文件,并用0填充。这样可以使mongodb始终保持充足的空间,防止因为临时分配磁盘空间导致阻塞。
关于命名空间文件,后缀名为.ns,是数据库中最早生成的文件,负责保存数据库中的集合索引的元数据。默认情况下,.ns文件大小为16MB,可以存储24000个命名空间,也就是说数据库集合和索引的总数不超过24000。可以自行修改。

mongodb持久化

在传统数据库中,存在一个Redo Log的机制用来应对因为系统崩溃或掉电引发的数据丢失问题。原理是将操作写入日志,然后执行操作,然后操作完成后删除日志;如果发生系统崩溃,重启后首先会从Redo Log中重新执行操作。MongoDB 的journal就是实现这个目的的一种WAL日志。

不止传统数据库,Redo Log机制广泛存在于各种框架系统中。

mongodb的读写全部针对内存进行。如果没有journal,mongodb写入数据仅仅是到内存中,由操作系统决定什么时候将数据持久化到硬盘上,mongodb仅仅提供60s一次的强制写入硬盘。如果出现系统崩溃,那么从上一次刷盘到现在的数据就会丢失,一次丢失60s的数据。
从2.0开始,mongodb默认开启journal。数据写入首先会写入Journal Buffer,然后再写入内存,Journal Buffer每隔100ms写入磁盘,提交为单事务,全部成功或全部失败。这样就算系统崩溃,mongodb重启后会根据Journal文件恢复数据,最多丢失100ms数据。这个提交时间可以修改,从2ms到300ms之间。

如果journal开启,内存大小差不多翻番

如果不能忍受100ms的数据丢失,可以通过设定写关注来调整写入的可靠性。这里是通过放弃部分写入性能来提高写入的可靠性。

  1. {w: 0} Unacknowledged:对每个写入操作,mongodb不会返回一个是否成功的状态文档。通过放弃一切安全性换来了最好的性能。在这个级别下,向mongodb写入操作如果失败,客户端也不会有任何提示。很多使用mongodb保存日志文件使用这个级别,数据量大,就算丢失一两条数据也无所谓。
  2. {w: 1} Acknowledged:对每个写入操作,mongodb会确认数据写入主节点内存的情况。可以看重复主键, 网络错误,系统故障或者是无效数据等错误。从2.4开始,这个级别是默认级别。如果写入过程中发生了系统崩溃,只会损失内存中的100ms数据。
  3. {j:1} Journaled:对于每个写入操作,mongodb会确认数据通过journal落盘后才会返回。并不是每一次写操作都会刷新硬盘,mongodb在每次写操作后最多等待30ms,把30ms内的数据顺序写入硬盘。在这30ms内客户端处于等待状态。对于单个操作会有额外的延迟,但是对于高并发情况下,延迟和吞吐并不会有多大影响。如果存储系统针对顺序写进行优化,整个延迟会被降到最低。
    这里,如果mongodb是单机,那么以上级别已经足够安全。在集群情况下,可以使用下一个级别。
  4. {w: “majority”}:对于每个写入操作,写入到多数节点。mongodb的复制集一般为奇数节点。这个级别可以保障数据在集群环境中的一致性。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容