51开源社区 | 关注开源、Linux and Android

 找回密码
 我要注册

用新浪微博连接

一步搞定

搜索
查看: 1056|回复: 1

[MongoDB] MongoDB数据碎片整理   [复制链接]

Rank: 4

RedHat Lover CentOS Lover

发表于 2011-7-5 01:48:01 |显示全部楼层
本帖最后由 Rose 于 2011-7-5 01:49 编辑

为什么MongoDB需要进行数据碎片整理?MongoDB 采用了磁盘空间预分配的机制,本身磁盘碎片以及使用mmap后造成的近一步的内存碎片,另外为mongodb update一个document的时候,如果update后的document比原来的大,那么这个document会在尾巴放上去.这也是有时候用mogodump一个运行中的系统会出现数据不一致性的情况的原因.随着数据的增删除改操作,数据文件不可避免的会产生空洞,造成磁盘空间和内存的浪费。
什么时候MongoDB需要进行碎片整理?
在Linux下使用mongostat命令查看faults很高的情况下,MongoDB的性能会直接受到影响。
DB file size和内存比例比较大
查看Collection 及其Index Size
  1. > db.<collectionname>.validate();  
  2. > // these are faster:  
  3. > db.<collectionname>.dataSize(); // just data size for collection  
  4. > db.<collectionname>.storageSize(); // allocation size including unused space  
  5. > db.<collectionname>.totalSize(); // data + index  
  6. > db.<collectionname>.totalIndexSize(); // index data size  
复制代码
MongoDB如何进行碎片整理?

通过 db.repairDatabase()进行数据碎片整理
缺点:速度太慢,操作的时候对 DB 的读写操作会变得非常慢,甚至会出现写操作丢失的情况,因此这个时候最好直接停掉客户端的写操作。
repainDatabase()是MongoDB内置的一个方法,调用此方法,MongoDB 会扫描db中的所有数据,并将通过重新插入来重新整理数据集合。
可以创建 bar.js 文件,写入如下代码:
  1. // Get a the current collection size.
  2. var storage = db.foo.storageSize();
  3. var total = db.foo.totalSize();

  4. print('Storage Size: ' + tojson(storage));

  5. print('TotalSize: ' + tojson(total));

  6. print('-----------------------');
  7. print('Running db.repairDatabase()');
  8. print('-----------------------');

  9. // Run repair
  10. db.repairDatabase()

  11. // Get new collection sizes.
  12. var storage_a = db.foo.storageSize();
  13. var total_a = db.foo.totalSize();

  14. print('Storage Size: ' + tojson(storage_a));
  15. print('TotalSize: ' + tojson(total_a));
复制代码
运行:$ mongo foo bar.js运行结果:MongoDB shell version: 1.6.4
connecting to: fooStorage Size: 51351
TotalSize: 79152-----------------------
Running db.repairDatabase()-----------------------
Storage Size: 40960
TotalSize: 65153

通过primary stepDown,产生新的primary,删除原primary数据,再启用原primary来进行碎片整理假设现在有三个成员,A当前为primary,我们希望B来成为primary不想让C成为primary,从而freeze C,接着stepDown A
  1. $ mongo --host C
  2. > // first check that everyone is healthy and in the states we expect:
  3. > rs.status()
  4. > // C : not eligible to be primary for 120 seconds
  5. > rs.freeze(120)
  6. > exit

  7. $ mongo --host A
  8. > // A : step down as primary and ineligible to be primary for 120 seconds
  9. > rs.stepDown(120)
  10. > // B will now become primary. for this to work B must be up to date.
复制代码
freeze C让其在120内无法成为primary
stepDown primary,也就是A,这样新的primary就会出现,应该是B
kill 原primary Adelete原primary data启动原primary version1.9.0+,你可以设置成员的优先集


通过创建capped collection来减少碎片产生
capped collection 是 MongoDB 中的一种特殊collection,它的大小可以限定,数据在这个限定大小内循环写入,在数据集合达到上限后,新数据会覆盖老的数据。这样磁盘上的空洞在一段时间后会自动消除。当然需要capped collection适合您的环境。
官方文档:http://www.mongodb.org/display/DOCS/Capped+Collections
其他:http://bbs.51osos.com/thread-3757-1-1.html

http://bbs.51osos.com/thread-3758-1-1.html


通过replicatin sharding来实现碎片整理
这个比较麻烦,等待你来研究啦。





使用道具 举报

Rank: 7Rank: 7Rank: 7

赏茶闲客 试剑江湖

发表于 2011-7-5 01:56:56 |显示全部楼层
( # ̄▽ ̄#)你若不离不弃,我必生死相依。

使用道具 举报

您需要登录后才可以回帖 登录 | 我要注册

51开源社区 ( 皖ICP备10203526号 )

GMT+8, 2014-4-25 14:36 , Processed in 0.078910 second(s), 12 queries .

Powered by Discuz! X2

© 2001-2011 Comsenz Inc.

回顶部