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

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

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

最新文章

  1. js Memoization 优化运行速度
  2. 某些版本的IIS可能有SessionID混淆的Bug
  3. discuz+ecmall+phpcms整合
  4. JS禁用和启用鼠标滚轮滚动事件
  5. Windows Server 2008 计划任务配置(任务计划程序)每分钟执行BAT
  6. 外部连VPN的方法
  7. Mycat 分片规则详解--范围分片
  8. win10激活(免费+永久)视频教程
  9. Odoo
  10. AOSP android 源码下载
  11. Eclipse 各版本号
  12. 【BZOJ2000】[HNOI2000]取石头游戏(贪心,博弈论)
  13. 技巧:Vim 的纵向编辑模式【转】
  14. 使用Git,如何忽略不需要上传的文件(配置文件)
  15. Laravel中服务提供者和门面模式
  16. HTML解析利器HtmlAgilityPack
  17. URL中#号的含义
  18. 工具软件 PYUV打开raw图片
  19. Python多线程运行带多个参数的函数
  20. (转)S5PV210 三个Camera Interface/CAMIF/FIMC的区别

热门文章

  1. [POI2015]Pustynia
  2. [POI2015]Wilcze doły
  3. 【洛谷】2474:[SCOI2008]天平【差分约束系统】
  4. [LeetCode] Pacific Atlantic Water Flow 题解
  5. http协议之 COOKIE
  6. PYQT控件使用
  7. UVA 11945 Financial Management 水题
  8. 【原】Java程序调用远程Shell脚本
  9. php Function split() is deprecated 的解决办法
  10. 字符串转换atof atoi atol gcvt strtod strtol strto ul toascii tolower toupper