在32位系统下使用MongoDB的一点心得
来源:互联网 发布:python 读入整个文件 编辑:程序博客网 时间:2024/05/01 17:11
本文出处:http://blog.csdn.net/chaijunkun/article/details/7236911,转载请注明。由于本人不定期会整理相关博文,会对相应内容作出完善。因此强烈建议在原始出处查看此文。
随着互联网的变革,互联网的内容生成方式也逐渐地从网站生成转为用户生成。这种变化不仅仅是内容生成对象的转变那样简单的问题,随之带来的就是互联网数据的大爆炸(big bang)。社交网络的兴起也给互联网相关技术提出了挑战。
MongoDB应用广泛,作为一款无关系型数据库产品,它具有伸缩性、高性能、开源、模式开放和基于文档等特性。因此很值得研究。
通过本文,我将与你分享:
1. MongoDB如何申请磁盘空间,采用何种策略申请
2. 印证网上流传的32位平台下MongoDB数据库不能大于2GB的说法
既然MongoDB擅长的是海量数据处理,对它进行研究避免不了使用庞大的数据来做测试。好了,问题来了——上哪找庞大的数据呢?
公司里当然有那么多数据了,可是由于保密方面的要求,不能拿来做测试,更不能写出来。因此我想到了一个好东西——CSDN密码库。
这个200+M的小家伙在年前闹得沸沸扬扬,弄得人人自危,掀起了一场改密码风暴,反正也被公布出来了,拿它来做测试不是很好么?
至于从哪里得到的这个密码库,我就不说了,身为ITer的你一定有办法搞到手的。我的这个版本一共有6428632条数据,每条数据的结构都很简单:
用户名 # 密码 # 邮箱
分析的时候只需要一行行地读出来,然后按照“#”分割,最后对每一个字段都trim一下就可以了。
我做本次实验使用的平台如下:
Windows XP SP3(当然是32位版啦)
奔腾E5300 CPU
2G内存
首先按照上一篇文章建立了本地的MongoDB服务(文章链接:http://blog.csdn.net/chaijunkun/article/details/7227967)
然后使用MongoDB-Driver操作MongoDB,使用Morphia做ORM。
下面是我写的数据迁移代码(从密码库txt文件存储至MongoDB)
CSDNData.java
package net.csdn.blog.chaijunkun.entities;import org.bson.types.ObjectId;import com.google.code.morphia.annotations.Entity;import com.google.code.morphia.annotations.Id;@Entity(value="users", noClassnameStored=true)public class CSDNData {@Idprivate ObjectId id;private Integer idx;private String userName;private String password;private String email;public ObjectId getId() {return id;}public void setId(ObjectId id) {this.id = id;}public Integer getIdx() {return idx;}public void setIdx(Integer idx) {this.idx = idx;}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}}
在实体中我增加了用于标识文档序号的idx字段。
接下来就是数据转储代码了:
TransformData.java
package net.csdn.blog.chaijunkun;import java.net.UnknownHostException;import net.csdn.blog.chaijunkun.entities.CSDNData;import com.google.code.morphia.Datastore;import com.google.code.morphia.Key;import com.google.code.morphia.Morphia;import com.mongodb.Mongo;import com.mongodb.MongoException;import java.io.BufferedReader;import java.io.File;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.IOException;import java.io.UnsupportedEncodingException;public class TransformData {public static void main(String[] args) throws UnknownHostException, MongoException{Mongo connection= new Mongo("localhost", 27017);Morphia morphia= new Morphia();Datastore ds= morphia.createDatastore(connection, "csdn");File dataFile= new File("D:\\www.csdn.net.txt");FileReader fr;Integer idx=1; try {fr = new FileReader(dataFile);BufferedReader br=new BufferedReader(fr);String currentLine= null;try {while((currentLine= br.readLine())!=null){//读取操作if (currentLine.trim().equals("")){continue;}String[] record= currentLine.split("#");if (record.length>=3){CSDNData csdnData= new CSDNData();csdnData.setIdx(idx);csdnData.setUserName(record[0].trim());csdnData.setPassword(record[1].trim());csdnData.setEmail(record[2].trim());Key<CSDNData> key= ds.save(csdnData);System.out.println("已存入:"+ key.getId() + ",文档序列:"+ idx);}else{System.out.println("文档序列"+ idx+ "发生错误:"+currentLine);break;}idx++;}} catch (UnsupportedEncodingException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
由于我启动MongoDB服务时使用了参数--directoryperdb,因此会在数据目录下建立csdn目录。
随着数据越来越多,MongoDB中的自动分片算法开始起作用:
C:\MongoDB\csdn>dir Volume in drive C has no label. Volume Serial Number is F474-EC39 Directory of C:\MongoDB\csdn2012-02-06 14:59 <DIR> .2012-02-06 14:59 <DIR> ..2012-02-06 14:40 16,777,216 csdn.02012-02-06 14:40 33,554,432 csdn.12012-02-06 14:41 67,108,864 csdn.22012-02-06 14:42 134,217,728 csdn.32012-02-06 14:45 268,435,456 csdn.42012-02-06 14:49 536,608,768 csdn.52012-02-06 14:59 536,608,768 csdn.62012-02-06 14:40 16,777,216 csdn.ns 8 File(s) 1,610,088,448 bytes 2 Dir(s) 20,669,665,280 bytes freeC:\MongoDB\csdn>最早生成的文件分别是csdn.0和csdn.ns,当0分片存储满后建立1分片(csdn.1文件),可以仔细观察其文件大小
csdn.ns==> 16MB
csdn.0 ==> 16MB
csdn.1 ==> 32MB
csdn.2 ==> 64MB
csdn.3 ==>128MB
csdn.4 ==>256MB
csdn.5 ==>512MB
但是在第7个分片(csdn.6)时发生了问题,第7分片目前大小是512MB,和第6分片大小一致。这如何解释呢?
其实MongoDB在存储时并不是按照实际数据量来严格申请磁盘空间。它会随着当前数据量的多少(说白了就是判断当前到第几个分片了)来动态申请空间,一次申请多少完全取决于前一分片的大小。
例如csdn.0文件默认是16MB,当csdn.1刚出现时,它的大小也是16MB,也就是第一次申请磁盘空间16MB,随后16MB装满了,而该分片就会再次申请16MB空间。
总而言之就是当前分片所占的最大空间将由2次申请磁盘空间来实现的(第一分片除外,固定16MB),而每一次申请的大小都是前一分片的最大尺寸。
为什么在第7分片发生了问题呢?这个就是我要说的下一个问题了:
在MongoDB的README中有如下一段话:
MongoDB uses memory mapped files. If built as a 32 bit executable, you will not be able to work with large (multi-gigabyte) databases. However, 32 bit builds work fine with small development databases.翻译如下:
MongoDB使用内存映射文件,如果构建成32位可执行程序,您将不能使其工作在大数据库(若干GB)方式下
我们来计算一下:
csdn.ns(16MB)+csdn.0(16MB)+csdn.1(32MB)+csdn.2(64MB)+csdn.3(128MB)+csdn.4(256MB)+csdn.5(512MB)+csdn.6(512MB)=1536MB,
也就是说在发生问题之前数据库的总大小已经到达了1536MB。这时候由于存储的需求,按照算法,将再次申请512MB空间(csdn.5的大小)给csdn.6。
试想一下,如果申请成功了,数据库的文件将达到多少?1536MB+512MB=2048,正好等于2GB。这与网上的”32位平台下,MongoDB最大不能超过2GB“的说法一致。
那么我是怎么知道出问题了呢?
很简单,代码在传送了5790004条记录后当要写入第5790005条记录时抛出了异常:
已存入:4f2f7a4e5a2768e3dced269b,文档序列:5790001已存入:4f2f7a4e5a2768e3dced269c,文档序列:5790002已存入:4f2f7a4e5a2768e3dced269d,文档序列:5790003已存入:4f2f7a4e5a2768e3dced269e,文档序列:5790004Exception in thread "main" com.mongodb.MongoException: can't map file memory - mongo requires 64 bit build for larger datasets根据异常信息我们也可以知道:无法映射内存文件,MongoDB为大数据集需要使用64位构建。
- 在32位系统下使用MongoDB的一点心得
- 在32位系统下使用MongoDB的一点心得
- 在32位系统下使用MongoDB的一点心得
- 在32位系统下使用MongoDB的一点心得
- 32位汇编学习的一点心得
- 32位汇编学习的一点心得
- 关于在32位系统下使用VMware安装64位系统的问题
- 32位linux系统下mongodb安装出现的问题
- 在win7 32位下使用mongoDB遇到的问题及解决
- 32位系统使用mongodb需要注意的几点
- Window7的64位系统下配置32位的汇编环境的心得
- 使用函数GetProcAddress( )在纯C环境下调用动态链接库的一点心得...
- 关于Vmware下安装Linux系统的一点心得
- MySql在64位系统下的使用
- WinIO3.0在win7 64位系统下的使用
- js在ie和ff下兼容的一点心得
- 在FLEX的DATAGIRD中使用itemRenderer的一点心得
- 关于mysql下索引使用的一点心得
- Android开发小经验
- VC++/MFC COMBOBOX使用
- 观察analyze table compute statistics 都对什么对象统计了信息+user_tab_histograms中的endpoint_value
- js将控件隐藏及display属性
- 让女人年轻十岁的小处方
- 在32位系统下使用MongoDB的一点心得
- QTP 1-5 QTP基础1 Object repository & DataTables & Actions
- android 通讯录跳转
- Building Coder(Revit 二次开发) - 改变元素颜色
- 802.1X认证+DHCP+ACS Server+Windows XP
- QT学习笔记(八):嵌入式Linux下的QT程序的运行及相应的参数
- QTP 6-9 QTP基础2 Environment Variables &Utility Objects & Checkpoints& Library Files
- linux简单字符设备驱动
- 什么是Service