32位下操作mongodb心得
本文出处: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 {
- @Id
- private 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 block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- } catch (FileNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
就这样运行程序,密码库中的数据就开始向MongoDB中传送了。
由于我启动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\csdn
- 2012-02-06 14:59 <DIR> .
- 2012-02-06 14:59 <DIR> ..
- 2012-02-06 14:40 16,777,216 csdn.0
- 2012-02-06 14:40 33,554,432 csdn.1
- 2012-02-06 14:41 67,108,864 csdn.2
- 2012-02-06 14:42 134,217,728 csdn.3
- 2012-02-06 14:45 268,435,456 csdn.4
- 2012-02-06 14:49 536,608,768 csdn.5
- 2012-02-06 14:59 536,608,768 csdn.6
- 2012-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 free
- C:\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,文档序列:5790004
- Exception in thread "main" com.mongodb.MongoException: can't map file memory - mongo requires 64 bit build for larger datasets
根据异常信息我们也可以知道:无法映射内存文件,MongoDB为大数据集需要使用64位构建。
32位下操作mongodb心得的更多相关文章
- 32位Windows7上8G内存使用感受+xp 32位下使用8G内存 (转)
32位Windows7上8G内存使用感受+xp 32位下使用8G内存 博客分类: Windows XPWindowsIE企业应用软件测试 我推荐做开发的朋友:赶快加入8G的行列吧....呵呵..超爽 ...
- VS2015配置内核WDK7600环境,32位下.
VS2015配置内核WDK7600环境,32位下. 学习内核驱动的编写,就要会配置环境.不然总是用记事本编写.比较不方便. 环境配置如下. 1.首先下载WDK7600, 课堂资料代码中已经上传.链接: ...
- Ubuntu 12.04(32位)下PHP环境的搭建(LAMP)
Ubuntu 12.04 32位 下默认安装为5.3.10 不是以下图文中的5.4 1.首先打开命令行,切换到root身份,获得最新的软件包 su root sudo apt-get install ...
- 【转】如何在Ubuntu11.10(32位)下编译Android4.0源码(图文)
原文网址:http://blog.csdn.net/flydream0/article/details/7046612 关于如何下载Android4.0的源码请参考我的另一篇文章: http://bl ...
- 迁移32位下的旧代码到64位sever遇到过的两个很诡异的问题
一个是GetHashCode,这个方法是返回一个int值,在32位系统里,都是正值,但在64位系统里会返回负值. 另一个问题是DataTable的Sort属性,在没有显示写明升序或降序的情况下,在32 ...
- Win7 32位下cocos2dx android开发调试环境
1.使用环境 win7 32位 + vs2010 2.软件准备(下方绿色文字带链接) cocos2dx-v2.2.2 jdk7 android sdk android ndk adt bundle a ...
- windows7 64,32位下scrapy爬虫框架的环境搭建
适用于python 2.7 64位安装 一.操作系统:WIN7 64位 二.python版本:2.7 64位(scrapy目前不支持3.x) 不确定位数的,看图 三.安装相关软件:(可以从我的百度网盘 ...
- windows32位下安装mongodb
下载mongodb:http://downloads.mongodb.org/win32/mongodb-win32-i386-2.4.5.zip 给mongodb指定一个数据存放路径:这里我们放在m ...
- qt5.4.0在windows,32位下的编译, vs2010平台
假设源代码入在D:\3DFrame\qt-everywhere-opensource-src-5.4.0\qt-everywhere-opensource-src-5.4.0 1:首先从官方网站下载源 ...
随机推荐
- pycharm设置用滑轮改变字体大小
在电脑第一次安装pycharm之后,发现每次调整代码界面的字体,总是需要到setting里面调整,这样非常不方便,特别是对于代码量很多的时候,我们有时候需要把目光聚焦到某一句代码,这个时候就需要放大, ...
- css样式水平居中和垂直居中的方法
水平居中(包含块中居中) 1. 定宽,左右margin为auto.(常规流块盒.弹性项目[不用定宽]) 例子:在box1盒子上设置宽,再设置margin:auto: <style> .bo ...
- Slimvoice快速而小巧
这可行吗?绝对没问题.完全加载的最大页面只有230 KB.因为所有内容都被缓存和压缩,所以随后查看的每个页面只有大约6 KB,这比我见过的具有相同功能的SPA要小得多. Slimvoice快速而小巧, ...
- 利用druid sql parser搞一些事情
在最近的项目开发中,有这样一个需求,就是给定一个查询的sql,在where语句中添加几个条件语句.刚开始想的是,是否能用正则去做这个事情呢?其实不用语法树还是有一点困难的. 经过一系列google,看 ...
- 内存不足导致mysql关闭,CentOS6.5增加swap分区
某日发现mysql自动关闭了,查找错误日志发现以下错误 2017-07-14 13:07:30 5494 [Note] InnoDB: Initializing buffer pool, size = ...
- Linux centos :root密码忘记怎么办?
1 重启系统后出现GRUB界面在引导装载程序菜单上,用上下方向键选择你忘记密码的那个系统键入“e” 来进入编辑模式. 2 接下来你可以看到如下图所示的画面,然后你再用上下键选择最新的内核(这里是第二行 ...
- [牛客] [#1108 J] [树形结构] 买一送一
2019牛客国庆集训派对day3 链接:https://ac.nowcoder.com/acm/contest/1108/J来源:牛客网 题意 ICPCCamp 有 n 个商店,用 $1,2,..., ...
- php自定义json_encode()和json_decode()函数
json数据大家应该遇到过,json_encode()和json_decode()是php5.0以后加上的内置函数,如果低版本要使用,需加扩展,很多时候我们无权改变服务器的配置,我们只能通过自定义函数 ...
- 【AGC006 C】Rabbit Exercise
题意 有 \(n\) 只兔子在数轴上,第 \(i\) 只兔子的初始坐标为整数 \(x_i\). 现在这些兔子会按照下面的规则做体操.每一轮体操都由 \(m\) 次跳跃组成:在第 \(j\) 次跳跃时, ...
- spark源码本地调试
1.前提条件: 1)安装jdk 版本: 2)安装scala 版本: 3)安装sbt 版本: 4)安装maven 5)安装git 版本: 6)安装idea,并配置好sbt.git.maven 2.从gi ...