http://blog.csdn.net/daizhj/article/details/5868360

注:本文是研究Mongodb分布式数据存储的副产品,通过本文的相关步骤可以将一个大表中的数据分布到几个mongo服务器上。

MongoDB的1.6版本中auto-sharding功能基本稳定并可以尝试放到生产环境下使用。因为其是auto-sharding,即mongodb通过mongos(一个集群环境配置工具)自动建立一个水平扩展的数据库集群系统,将数据库分表存储在sharding的各个节点上。
       一个mongodb集群包括一些shards(包括一些mongod进程),mongos路由进程,一个或多个config服务器

(注:本文的测试用例需求64位的mongo程序,因为我在32位的mongo没成功过)。

下面是一些相关词汇说明:
       Shards : 每一个shard包括一个或多个服务和存储数据的mongod进程(mongod是MongoDB数据的核心进程)典型的每个shard开启多个服务来提高服务的可用性。这些服务/mongod进程在shard中组成一个复制集

Chunks: Chunk是一个来自特殊集合中的一个数据范围,(collection,minKey,maxKey)描叙一个chunk,它介于minKey和maxKey范围之间。例如chunks 的maxsize大小是100M,如果一个文件达到或超过这个范围时,会被切分到2个新的chunks中。当一个shard的数据过量时,chunks将会被迁移到其他的shards上。同样,chunks也可以迁移到其他的shards上

Config Servers : Config服务器存储着集群的metadata信息,包括每个服务器,每个shard的基本信息和chunk信息Config服务器主要存储的是chunk信息。每一个config服务器都复制了完整的chunk信息。

接着看一下要配置的测试环境信息:

模拟2个shard服务和一个config服务, 均运行在10.0.4.85机器上,只是端口不同
       Shard1:27020
       Shard2:27021
       Config:27022
       Mongos启动时默认使用的27017端口

在C,D,E磁盘下分别建立如下文件夹:

mongodb/bin

mongodb/db

然后用CMD命令行依次打开相应文件夹下的mongd文件:

c:/mongodb/bin/mongod --dbpath c:/mongodb/db/ --port 27020

d:/mongodb/bin/mongod --dbpath d:/mongodb/db/ --port 27021

e:/mongodb/bin/mongod --configsvr --dbpath e:/mongodb/db/ --port 27022          (注:config配置服务器)

启动mongos时,默认开启了27017端口

e:/mongodb/bin/mongos --configdb 10.0.4.85:27022

然后打下mongo:

E:/mongodb/bin>mongo   回车  (有时加端口会造成下面的addshard命令出问题)

> use admin
          switched to db admin
      > db.runCommand( { addshard : "10.0.4.85:27020", allowLocal : 1, maxSize:2 , minKey:1, maxKey:10} )

--添加sharding,maxsize单位是M,此处设置比较小的数值只为演示sharding效果

{ "shardAdded" : "shard0000", "ok" : 1 }
      > db.runCommand( { addshard : "10.0.4.85:27021", allowLocal : 1, minKey:1000} )
         { "shardAdded" : "shard0001", "ok" : 1 }

注:如果要移除sharding,可用下面写法

db.runCommand( { removeshard : "localhost:10000" } );

> db.runCommand({listshards:1});   查看shard节点列表

      {
        "shards" : [
                {
                        "_id" : "shard0000",
                        "host" : "10.0.4.85:27020"
                },
                {
                        "_id" : "shard0001",
                        "host" : "10.0.4.85:27021"
                }
        ],
        "ok" : 1
      }

接下来创建相应数据库并设置其"可以sharding",新建自动切片的库user001:

       > config = connect("10.0.4.85:27022")
       > config = config.getSisterDB("config")
       > dnt_mongodb=db.getSisterDB("dnt_mongodb");
           dnt_mongodb
       > db.runCommand({enablesharding:"dnt_mongodb"})
          { "ok" : 1 }
 
       注:一旦enable了个数据库,mongos将会把数据库里的不同数据集放在不同的分片上。除非数据集被分片(下面会设置),否则一个数据集的所有数据将放在一个分片上。

> db.printShardingStatus();

   --- Sharding Status ---
  sharding version: { "_id" : 1, "version" : 3 }
  shards:
      { "_id" : "shard0000", "host" : "10.0.4.85:27020" }
      { "_id" : "shard0001", "host" : "10.0.4.85:27021" }
  databases:
        { "_id" : "admin", "partitioned" : false, "primary" : "config" }
        { "_id" : "dnt_mongodb", "partitioned" : true, "primary" : "shard0000" }
       > db.runCommand( { shardcollection : "dnt_mongodb.posts1", key : {_id : 1}, unique: true } )  
          { "collectionsharded" : "dnt_mongodb.posts1", "ok" : 1 } 
    
        --使用shardcollection 命令分隔数据集,key自动生成。 

        如果要进行GridFS sharding,则需进行如下设置:
            db.runCommand( { shardcollection : "test.fs.chunks", key : { _id : 1 } } )
            {"ok" : 1} ,更多内容参见http://eshilin.blog.163.com/blog/static/13288033020106215227346/
      
       > db.printShardingStatus()
   --- Sharding Status ---
  sharding version: { "_id" : 1, "version" : 3 }
  shards:
      { "_id" : "shard0000", "host" : "localhost:27020" }
      { "_id" : "shard0001", "host" : "localhost:27021" }
  databases:
        { "_id" : "admin", "partitioned" : false, "primary" : "config" }
        { "_id" : "user001", "partitioned" : true, "primary" : "shard0000" }
                dnt_mongodb.posts1e chunks:
                        { "name" : { $minKey : 1 } } -->> { "name" : { $maxKey :
 1 } } on : shard0000 { "t" : 1000, "i" : 0 
                 
       下面我用一个工具来批量向dnt_mongodb数据库的 posts1表中导入数据,大约是16万条数据。导入过程中mongos会显示类似如下信息:
      Tue Sep 07 12:13:15 [conn14] autosplitting dnt_mongodb.posts1 size: 47273960 shard: ns:dnt_mongodb.posts1 at: shard0000:10.0.4.85:27020 lastmod: 1|0 min: { _id: MinKey } max: { _id: MaxKey } on: { _id: 19 }(splitThreshold 47185920)
Tue Sep 07 12:13:15 [conn14] config change: { _id: "4_85-2010-09-07T04:13:15-0", server: "4_85", time: new Date(1283832795994), what: "split", ns: "dnt_mongodb.posts1", details: { before: { min: { _id: MinKey }, max: { _id: MaxKey } }, left: { min: { _id: MinKey }, max: { _id: 19 } }, right: { min: { _id: 19 }, max: {_id: MaxKey } } } }
      Tue Sep 07 12:13:16 [conn14] moving chunk (auto): ns:dnt_mongodb.posts1 at: shard0000:10.0.4.85:27020 lastmod: 1|1 min: { _id: MinKey } max: { _id: 19 } to: shard0001:10.0.4.85:27021 #objects: 0
      Tue Sep 07 12:13:16 [conn14] moving chunk ns: dnt_mongodb.posts1 moving ( ns:dnt_mongodb.posts1 at: shard0000:10.0.4.85:27020 lastmod: 1|1 min: { _id: MinKey }max: { _id: 19 }) shard0000:10.0.4.85:27020 -> shard0001:10.0.4.85:27021
       Tue Sep 07 12:13:23 [WriteBackListener] ~ScopedDBConnection: _conn != null
       Tue Sep 07 12:13:23 [WriteBackListener] ERROR: splitIfShould failed: ns: dnt_mongodb.posts1 findOne has stale config
       Tue Sep 07 12:13:28 [WriteBackListener] autosplitting dnt_mongodb.posts1 size: 54106804 shard: ns:dnt_mongodb.posts1 at: shard0000:10.0.4.85:27020 lastmod: 2|1min: { _id: 19 } max: { _id: MaxKey } on: { _id: 71452 }(splitThreshold 47185920)
       Tue Sep 07 12:13:28 [WriteBackListener] config change: { _id: "4_85-2010-09-07T04:13:28-1", server: "4_85", time: new Date(1283832808738), what: "split", ns: "dnt_mongodb.posts1", details: { before: { min: { _id: 19 }, max: { _id: MaxKey }}, left: { min: { _id: 19 }, max: { _id: 71452 } }, right: { min: { _id: 71452 }, max: { _id: MaxKey } } } }
      在完成自动sharding之后,可以使用mongo看一下结果:
       > use dnt_mongodb
          switched to db dnt_mongodb
       > show collections
          posts1
          system.indexes
       > db.posts1.stats()

{
        "sharded" : true,
        "ns" : "dnt_mongodb.posts1",
        "count" : 161531,
        "size" : 195882316,
        "avgObjSize" : 1212.6608267143768,
        "storageSize" : 231467776,
        "nindexes" : 1,
        "nchunks" : 5,
        "shards" : {
                "shard0000" : {
                        "ns" : "dnt_mongodb.posts1",
                        "count" : 62434,
                        "size" : 54525632,
                        "avgObjSize" : 873.3323509626165,
                        "storageSize" : 65217024,
                        "numExtents" : 10,
                        "nindexes" : 1,
                        "lastExtentSize" : 17394176,
                        "paddingFactor" : 1,
                        "flags" : 1,
                        "totalIndexSize" : 2179072,
                        "indexSizes" : {
                                "_id_" : 2179072
                        },
                        "ok" : 1
                },
                "shard0001" : {
                        "ns" : "dnt_mongodb.posts1",
                        "count" : 99097,
                        "size" : 141356684,
                        "avgObjSize" : 1426.4476623913943,
                        "storageSize" : 166250752,
                        "numExtents" : 12,
                        "nindexes" : 1,
                        "lastExtentSize" : 37473024,
                        "paddingFactor" : 1,
                        "flags" : 1,
                        "totalIndexSize" : 3424256,
                        "indexSizes" : {
                                "_id_" : 3424256
                        },
                        "ok" : 1
                }
        },
        "ok" : 1
      } 

通过上面的结果,可以出现16万条记录均分在了两个sharding上,其中shard0000中有62434条,shard0001中有99097条。下面看一下这两个sharding-chunk的分布情况(图中的错误提示‘输入字符串格式不正确’主要因为运行环境与编译程序使用的环境不同,一个是64,一个是32位系统):

可以看到数据被按区间自动分割开了,有点像sqlserver的数据分区表,只不过这是自动完成的(目前我没找到可以手工指定区间上下限的方式,如有知道的TX可以跟我说一下)。当然在本文中的测试中,共有5个chunk,其中4个位于shard0001,这种情况可以在每次测试过程中会发生变化,包括两个sharding被分配的记录数。另外就是在mongodb移动过程前后会在shard0000上生成一个文件夹,里面包括一些bson文件,名字形如(表格+日期等信息):

post-cleanup.2010-09-07T04-13-31.1.bson

该文件主要包括一些数据库,表结构及相关记录等信息,我想应该是用于数据恢复备份啥的。

好的,今天的内容就先到这里了。

基于Mongodb进行分布式数据存储的更多相关文章

  1. tornado 基于MongoDB存储 session组件开发

    1.开发伊始 根据源码中RequestHandler类中发现__init__函数中会调用自身initialize函数,此函数中为pass,即可以围绕initialize开发一系列的组件 2.开发实现 ...

  2. 适用于app.config与web.config的ConfigUtil读写工具类 基于MongoDb官方C#驱动封装MongoDbCsharpHelper类(CRUD类) 基于ASP.NET WEB API实现分布式数据访问中间层(提供对数据库的CRUD) C# 实现AOP 的几种常见方式

    适用于app.config与web.config的ConfigUtil读写工具类   之前文章:<两种读写配置文件的方案(app.config与web.config通用)>,现在重新整理一 ...

  3. [CoreOS 转载] CoreOS实践指南(五):分布式数据存储Etcd(上)

    转载:http://www.csdn.net/article/2015-01-22/2823659 摘要:在“漫步云端:CoreOS实践指南”系列的前几篇,分别介绍了如何架设CoreOS集群,系统服务 ...

  4. MongoDb gridfs-ngnix文件存储方案

          在各类系统应用服务端开发中,我们经常会遇到文件存储的问题. 常见的磁盘文件系统,DBMS传统文件流存储.今天我们看一下基于NoSQL数据库MongoDb的存储方案.笔者环境 以CentOS ...

  5. MongoDb gridfs-ngnix文件存储方案 - 图片

    http://www.cnblogs.com/wintersun/p/4622205.html 在各类系统应用服务端开发中,我们经常会遇到文件存储的问题. 常见的磁盘文件系统,DBMS传统文件流存储. ...

  6. 基于Mongodb的轻量级领域驱动框架(序)

    混园子也有些年头了,从各个大牛那儿学了很多东西.技术这东西和中国的料理一样,其中技巧和经验,代代相传(这不是舌尖上的中国广告).转身回头一望,几年来自己也积累了一些东西,五花八门涉猎到各种方向,今日开 ...

  7. 基于MongoDB分布式存储进行MapReduce并行查询

    中介绍了如何基于Mongodb进行关系型数据的分布式存储,有了存储就会牵扯到查询.虽然用普通的方式也可以进行查询,但今天要介绍的是如何使用MONGODB中提供的MapReduce功能进行查询.     ...

  8. MongoDB 搭建文件存储的方案

    用云的话,节省你开发成本,快速上线,数据比较安全.缺点是一旦用了他们的,形成习惯以后,数据想迁移就会比较麻烦,你会越来越依赖,而且规模上去以后价格并不低.早年自己做的话,你需要实现分布式文件系统,这个 ...

  9. 【WP8.1开发】基于应用的联系人存储

    上一篇文章所吹的牛是访问系统(手机)上的联系人,当然那只是读不能改,这是自然的,要是让你能随便修改用户的联系人信息的话,那后果很严重,有些恶意开发者就有可能把”你的户口改成猪“. 但是,API也允许应 ...

随机推荐

  1. kali下利用weeman进行网页钓鱼

    工具下载链接:https://files.cnblogs.com/files/wh4am1/weeman-master.zip 利用wget命令下载zip压缩包 利用unzip命令解压 接着直接cd进 ...

  2. [CodeChef-QUERY]Observing the Tree

    题目大意: 给你一棵树,一开始每个点的权值都是0,要求支持一下三种操作: 1.路径加等差数列. 2.路径求和. 3.回到以前的某次操作. 强制在线. 思路: 树链剖分+主席树. 最坏情况下,n个点的树 ...

  3. hdu 4858 水题

    题意:我们建造了一个大项目!这个项目有n个节点,用很多边连接起来,并且这个项目是连通的!两个节点间可能有多条边,不过一条边的两端必然是不同的节点.每个节点都有一个能量值.现在我们要编写一个项目管理软件 ...

  4. Codeforces Round #358 (Div. 2) D. Alyona and Strings dp

    D. Alyona and Strings 题目连接: http://www.codeforces.com/contest/682/problem/D Description After return ...

  5. poj 1062 昂贵的聘礼 最短路 dijkstra

    #include <cstdio> #include <cmath> #include <cstring> #include <ctime> #incl ...

  6. elasticsearch中文分词+全文搜索demo

    本文假设你已经搭建好elasticsearch服务器,并在上面装了kibana和IK中文分词组件 elasticsearch+kibana+ik的安装,之前的文章有介绍,可参考. mapping介绍: ...

  7. 匹配<a href="url">content</a>

    grep -Po '<a href="(.*.rmvb")>(.*)</a>' te.txt | sed -n 's/<a href=\(.*\)&g ...

  8. Geeks 一般二叉树的LCA

    不是BST,那么搜索两节点的LCA就复杂点了,由于节点是无序的. 以下是两种方法,都写进一个类里面了. 当然须要反复搜索的时候.能够使用多种方法加速搜索. #include <iostream& ...

  9. IIS 未能从程序集“System.ServiceModel, Version=3.0.0.0, Culture=neutral,

    在Windows Server 2008中的IIS服务器中部署WCF服务程序时,通过浏览器访问报出如下错误: 未能从程序集“System.ServiceModel, Version=3.0.0.0, ...

  10. python性能优化建议

    参考: https://segmentfault.com/a/1190000000666603 http://blog.csdn.net/zhoudaxia/article/details/23853 ...