[转]MongoDB数据库文档说明
MongoDB数据库简单介绍MongoDB是一个高性能 ,开源 ,无模式的文档型数据库,它在许多场景下可用于替代传统的关系型数据库或键/值存储模式。MongoDB是用C++开发, 提供了以下功能:
[*]面向集合的存储:适合存储对象及JSON形式的数据。
[*]动态查询:Mongo支持丰富的查询表达式。查询指令使用JSON形式的 标记,可轻易查询文档中内嵌的对象及数组。
[*]完整的索引支持:包括文档内嵌对象及数组。Mongo的查询优化 器会分析查询表达式,并生成一个高效的查询计划。
[*]查 询监视:Mongo包含一个监视工具 用于分析数据库操作的性能。
[*]复制 及自动故障转移:Mongo数据库支持服务器 之间的数据复制,支持主-从模式及服务 器之间的相互复制。复制的主要目标是提供冗余及自 动故障转移。
[*]高效的传统存储方式:支持二进制数据及大型对象(如照片或图片)。
[*]自动分片以支持云级别的伸缩性(处于 早期alpha阶段):自动分片功能支持水平的数据库集群 ,可动态添加额外的机器。
MongoDB的主要目标是在键/值存储方式(提供了高性能和高度伸缩性)以及传统的RDBMS系统 (丰富的功能)架起一座桥梁,集两者的优势于一 身。根据官方网站的描述,Mongo 适合用于以下场景:
[*]网站数据:Mongo非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。
[*]缓存 :由于性能很高,Mongo也适合作为信息基础设施的缓存层。在系统重启之后,由Mongo搭建的持久化缓存层可以避免下层的数据源 过载。
[*]大尺寸,低价值的数据:使用传统的关系型数据库存储一些数据时可能会比较昂贵,在此之前,很 多时候程序员往往会选择传统的文件 进行存储。
[*]高伸缩性的场景:Mongo非常适合由数十或数百台服务器组成的数据库。Mongo的路线图中已经包含对MapReduce引擎的内置支 持。
[*]用于 对象及JSON数据的存储:Mongo的BSON数据格式非常适合文档化格式的存储 及查询。
自然,MongoDB的使用也会有一些限制,例如它不适合:
[*]高度事务性的系统:例如银行或会计系统。传统的关系型数据库目前还是更适用于需要大量原子性复杂事务的应用 程序。
[*]传统的商业智能应用:针对特定问题的BI数据库会对产生高度优化的查询方式。对于此类应用,数据仓库可能是更合适的选择。
[*]需要SQL的问题
MongoDB支持OS X、Linux及Windows等操作系统 ,并提供了Python,PHP,Ruby,Java,C,C#,Javascript,Perl及C++语言的驱动程序,社区中也提供了对Erlang 及.NET等平台的驱动程序
MongoDB下载:
http://www.mongodb.org/display/DOCS/Downloads
http://downloads.mongodb.org/lin ... 686-v1.2-latest.tgz
MongoDB安装:
[*]$tar xvzf mongodb-linux -i686-v1.2-latest.tgz
[*]$mv mongodb-linux-i686-v1.2-latest mongodb
[*]$cd mongodb
[*]$ ls
[*]mongo mongodump mongofiles mongorestoremongosniff
[*]mongodmongoexportmongoimportmongos
只需要解压到相关目录即可,不需要编译安装
MongoDB启动与关闭:
mongoDB的服务器端程序为mongod
[*]$ bin/mongod --help
[*]
[*]** NOTE: when using MongoDB 32 bit, you are limited to about 2 gigabytes of data
[*]** see http://blog.mongodb.org/post/137788967/32-bit-limitations for more
[*]
[*]Allowed options:
[*]
[*]General options:
[*]-h [ --help ] show this usage information
[*]--version show version information
[*]-f [ --config ] arg configuration file specifying additional options
[*]--port arg specify port number
[*]--bind _ip arg local ip address to bind listener - all local ips
[*] bound by default
[*]-v [ --verbose ] be more verbose (include multiple times for more
[*] verbosity e.g. -vvvvv)
[*]--dbpath arg (=/data/db/) directory for datafiles 指定数据存放目录
[*]--quiet quieter output 静默模式
[*]--logpath arg file to send all output to instead of stdout 指定日志 存放目录
[*]--logappend appnd to logpath instead of over-writing指定日志是以追加还是以覆盖的方式写入日志文件
[*]--fork fork server process 以创建子进程 的方式运行
[*]--cpu periodically show cpu and iowait utilization周期性的显示cpu和io的使用情况
[*]--noauth run without security无认证模式运行
[*]--auth run with security认证模式运行
[*]--objcheck inspect client data for validity on receipt检查客户端输入数据的有效性检查
[*]--quota enable db quota management 开始数据库配额的管理
[*]--quotaFiles arg number of files allower per db, requires --quota规定每个数据库允许的文件数
[*]--appsrvpath arg root directory for the babble app server
[*]--nocursors diagnostic/debugging option调试诊断选项
[*]--nohints ignore query hints忽略查询命中率
[*]--nohttpinterface disable http interface关闭http接口,默认是28017
[*]--noscripting disable scripting engine关闭脚本 引擎
[*]--noprealloc disable data file preallocation关闭数据库文件大小预分配
[*]--smallfiles use a smaller default file size使用较小的默认文件大小
[*]--nssize arg (=16) .ns file size (in MB) for new databases 新数据库ns文件的默认大小
[*]--diaglog arg 0=off 1=W 2=R 3=both 7=W+some reads 提供的方式,是只读,只写,还是读写都行,还是主要写+部分的读模式
[*]--sysinfo print some diagnostic system information 打印系统诊断信息
[*]--upgrade upgrade db if needed如果需要就更新数据库
[*]--repair run repair on all dbs修复所有的数据库
[*]--notablescan do not allow table scans不运行表扫描
[*]--syncdelay arg (=60) seconds between disk syncs (0 for never)系统同步刷新磁盘 的时间,默认是60s
[*]
[*]Replication options:
[*]--master master mod e 主复制模式
[*]--slave slave mode从复制模式
[*]--source arg when slave: specify master as当为从时,指定主的地址和端口
[*]--only arg when slave: specify a single database to replicate 当为从时,指定需要从主复制的单一库
[*]--pairwith arg address of server to pair with
[*]--arbiter arg address of arbiter server仲裁服务器,在主主中和pair中用到
[*]--autoresync automatically resync if slave data is stale 自动同步从的数据
[*]--oplogSize arg size limit (in MB) for op log 指定操作日志的大小
[*]--opIdMem arg size limit (in bytes) for in memory storage of op ids指定存储操作日志的内存 大小
[*]
[*]Sharding options:
[*]--configsvr declare this is a config db of a cluster 指定shard中的配置服务器
[*]--shardsvr declare this is a shard db of a cluster 指定shard服务器
在 启动mongoDB之前,我们必须新建一个存放mongoDB数据和日志的目录
[*]$ mkdir m_data m_log
到此mongodb启动的准备工作做完了,现在我们 启动mongodb
[*]$ bin/mongod --dbpath=/home/falcon/m_data --logpath=/home/falcon/m_log --logappend &
现在mongodb启动了,检查是否启动的方法:
[*]$ ps -ef|grep mongod
[*]falcon 253322710 08:21 pts/0 00:00:00 bin/mongod --dbpath=/home/falcon/m_data --logpath=/home/falcon/m_log --logappend
[*]falcon 254122710 08:22 pts/0 00:00:00 grep mongod
查看mongodb的端口是否启动,默认是 28017,在启动服务器时,可以通过--port来指定
[*]$ netstat -an -t|grep 28017
[*]tcp 0 0 0.0.0.0:28017 0.0.0.0:* LISTEN
到此,证明mongoDB已经启动完成
关闭的方法很简单:
Killall mongod 或者是kill
使用方法:
利用客户端程序mongo登录mongoDB
[*]$ bin/mongo
[*]MongoDB shell version: 1.2.4-
[*]url: test
[*]connecting to: test
[*]type "help" for help
[*]> help
[*]HELP
[*] Showdbs 显示数据库名
[*] showcollections 显示当前数据库中的集合集
[*] showusers 显示当前数据库的用户
[*] showprofile 显示最后系统用时大于1ms的系统概要
[*] use 切换到数据库
[*] db.help() help on DB methods
[*] db.foo.help() help on collection methods
[*] db.foo.find() list objects in collection foo
[*] db.foo.find( { a : 1 } ) list objects in foo where a == 1
[*] it result of the last line evaluated; use to further iterate
[*]> show dbs 默认情况下有2数据库
[*]admin
[*]local
[*]> use admin 切换到admin数据库
[*]switched to db admin
[*]> show collections 显示admin数据库下面的集合集
[*]system.indexes
下面我们来简单的新建集合集,插入、更新、查询数据, 体验mongodb带给我们不一样的生活
新建数据库的方法是在
新建集合集:
[*]> db.createCollection("user");
[*]{ "ok" : 1 }
[*]> show collections
[*]system.indexes
[*]user
[*]>
插入数据:
[*]> db.user.insert({uid:1,username:"Falcon.C",age:25});
[*]> db.user.insert({uid:2,username:"aabc",age:24});
查询数据:
[*]> db.user.find();
[*]{ "_id" : ObjectId("4b81e74c1f0fd3b9545cba43"), "uid" : 1, "username" : "Falcon.C", "age" : 25 }
[*]{ "_id" : ObjectId("4b81e74d1f0fd3b9545cba44"), "uid" : 2, "username" : "aabc", "age" : 24 }
查询数据的方式很丰富,有类似于SQL的条件查询,将 会在以后的文档中详细介绍
如:我想查询uid为1的用户信息
[*]> db.user.find({uid:1});
[*]{ "_id" : ObjectId("4b81e74c1f0fd3b9545cba43"), "uid" : 1, "username" : "Falcon.C", "age" : 25 }
等等,丰富的查询还有limit ,sort ,findOne,distinct等
更新数据:
[*]> db.user.update({uid:1},{$set:{age:26}})
[*]> db.user.find();
[*]{ "_id" : ObjectId("4b81e76f1f0fd3b9545cba45"), "uid" : 1, "username" : "Falcon.C", "age" : 26 }
[*]{ "_id" : ObjectId("4b81e7701f0fd3b9545cba46"), "uid" : 2, "username" : "aabc", "age" : 24 }
[*]> db.user.update({uid:1},{$inc:{age:-1}})
[*]> db.user.find();
[*]{ "_id" : ObjectId("4b81e76f1f0fd3b9545cba45"), "uid" : 1, "username" : "Falcon.C", "age" : 25 }
[*]{ "_id" : ObjectId("4b81e7701f0fd3b9545cba46"), "uid" : 2, "username" : "aabc", "age" : 24 }
[*]>
出 了以上的2种用法,更新的条件还有$unset、$push 、$pushAll 、$pop 、$pull 、$pullAll
以上就是MongoDB简单的使用介绍,在以后的文档中将会详细的介绍mongoDB非常酷的CURD方法,mongoDB的Replication及分 布式
开发文档:http://www.mongodb.org/display/DOCS/Developer+Zone
管理文档:http://www.mongodb.org/display/DOCS/Admin+Zone
下载地址:http://www.mongodb.org/display/DOCS/Downloads
MongoDB主从复制介绍
MongoDB的主从复制其实很简单,就是在运行 主的服务器 上开启mongod进程 时,加入参数--master即可,在运行从的服务 器上开启mongod进程时,加入--slave 和 --source 指定主即可,这样,在主数据 库更新时,数据被复制到从数据库 中
(这里日志文件和访问数据时授权用户暂时不考虑 )
下面我在单台服务器上开启2deamon来模拟2台服务器进行主从复制:
[*]$ mkdir m_master m_slave
[*]$mongodb/bin/mongod--port28018 --dbpath ~/m_master--master&
[*]$mongodb/bin/mongod--port28019 --dbpath ~/m_slave--slave--source localhost:28018&
这样主从服务器都已经启动了,可以利用 netstat -an -t 查看28018、28019端口 是否开放
登录主服务器:
[*]$ mongodb/bin/mongo --port 28018
[*]MongoDB shell version: 1.2.4-
[*]url: test
[*]connecting to: 127.0.0.1:28018/test
[*]type "help" for help
[*]> show dbs
[*]admin
[*]local
[*]test
[*]> use test
[*]switched to db test
[*]> show collections
这里主上的test数据什么表都没有,为空,查看从服 务器同样也是这样
[*]$ mongodb/bin/mongo --port 28019
[*]MongoDB shell version: 1.2.4-
[*]url: test
[*]connecting to: 127.0.0.1:28019/test
[*]type "help" for help
[*]> show dbs
[*]admin
[*]local
[*]test
[*]> use test
[*]switched to db test
[*]> show collections
那么现在我们来验证主从数据是否会像想象的那样同步 呢?
我们在主上新建表user
[*]> db
[*]test
[*]>db.createCollection("user");
[*]> show collections
[*]system.indexes
[*]user
[*]>
表 user已经存在了,而且test库中还多了一个system.indexes用来存放索引的表
到从服务器上查看test库:
[*]> db
[*]test
[*]> show collections
[*]system.indexes
[*]User
[*]> db.user.find();
[*]>
从服务器的test库中user表已经存在,同时我还查了一下user表为空
现在我们再来测试一下,向主服务器test库的user表中插入一条数据
[*]> show collections
[*]system.indexes
[*]user
[*]> db.user.insert({uid:1,name:"Falcon.C",age:25});
[*]> db.user.find();
[*]{ "_id" : ObjectId("4b8226a997521a578b7aea38"), "uid" : 1, "name" : "Falcon.C", "age" : 25 }
[*]>
这 时我们查看从服务器的test库user表时会多出一条记录来:
[*]> db.user.find();
[*]{ "_id" : ObjectId("4b8226a997521a578b7aea38"), "uid" : 1, "name" : "Falcon.C", "age" : 25 }
[*]>
MongoDB 还有 Replica Pairs 和 Master - Master
参考地址:http://www.mongodb.org/display/DOCS/Master+Slave
MongoDB一般情况下都可以支持主主复制,但是在大部分情况下官方不推荐使用
运行 的master - master的准备工作是:
新建存放数据 库文件 的路径
[*]$mkdir mongodata/mm_28050 mongodata/mm_28051
运行mongodb数据库 ,一个端口 为:28050,一个为:28051
[*]$ mongodb/bin/mongod --port 28050 --dbpath ~/mongodata/mm_28050 --master --slave --source localhost:28051 > /dev/null &
[*]$ mongodb/bin/mongod --port 28051 --dbpath ~mongodata/mm_28051 --master --slave --source localhost:28050 > /dev/null &
可以通过ps -ef|grep mongod 或 netstat -an -t来检查是否运行功能
测试master - master模式 :
[*]$ mongodb/bin/mongo --port 28050
[*]MongoDB shell version: 1.2.4-
[*]url: test
[*]connecting to: 127.0.0.1:28050/test
[*]type "help" for help
[*]> show dbs
[*]admin
[*]local
[*]> db
[*]test
[*]> db.user.insert({_id:1,username:"Falcon.C",age:25,sex:"M"});
[*]> db.user.find();
[*]{ "_id" : 1, "username" : "Falcon.C", "age" : 25, "sex" : "M" }
[*]> db.user.find();//在28051端口插入数据后,再来查询,看数据是否同步
[*]{ "_id" : 1, "username" : "Falcon.C", "age" : 25, "sex" : "M" }
[*]{ "_id" : 2, "username" : "NetOne", "age" : 24, "sex" : "F" }
[*]>
[*]$ mongodb/bin/mongo --port 28051
[*]MongoDB shell version: 1.2.4-
[*]url: test
[*]connecting to: 127.0.0.1:28051/test
[*]type "help" for help
[*]> db
[*]test
[*]> show collections 端口28050已经新建了一个user表并插入了一条数据,这里多出2表
[*]system.indexes
[*]user
[*]> db.user.find(); //查询表user发现数据已经同步
[*]{ "_id" : 1, "username" : "Falcon.C", "age" : 25, "sex" : "M" }
[*]> db.user.insert({_id:2,username:"NetOne",age:24,sex:"F"});在此插入数据看数据是否双向同步
[*]> db.user.find();
[*]{ "_id" : 1, "username" : "Falcon.C", "age" : 25, "sex" : "M" }
[*]{ "_id" : 2, "username" : "NetOne", "age" : 24, "sex" : "F" }
[*]>
通 过以上开启两终端分别连接到28050、28051端口,分别插入测试数据发现,一切正常,正如我们所想的那样实现数据的双向同步
参考信息:http://www.mongodb.org/display/DOCS/Master+Master+Replication
MongoDB的使用技巧
如果想查看当前连接在哪个数据 库下面,可以直接输入db
[*]> db
[*]Admin
想切换到test数据库
[*]> use test
[*]switched to db test
[*]> db
[*]Test
想 查看test下有哪些表或者叫collection,可以输入
[*]> show collections
[*]system.indexes
[*]user
想 知道mongodb支持哪些命令 ,可以直接输入help
[*]> help
[*]HELP
[*] show dbs show database names
[*] show collections show collections in current database
[*] show users show users in current database
[*] show profile show most recent system.profile entries with time >= 1ms
[*] use set curent database to
[*] db.help() help on DB methods
[*] db.foo.help() help on collection methods
[*] db.foo.find() list objects in collection foo
[*] db.foo.find( { a : 1 } ) list objects in foo where a == 1
[*] it result of the last line evaluated; use to further iterate
如果想知道当前数据库支持哪些方法:
[*]> db.help();
[*]DB methods:
[*] db.addUser(username, password) 添加数据库授权用户
[*] db.auth(username, password) 访问 认证
[*] db.cloneDatabase(fromhost) 克隆数据库
[*] db.commandHelp(name) returns the help for the command
[*] db.copyDatabase(fromdb, todb, fromhost)复制数据库
[*] db.createCollection(name, { size : ..., capped : ..., max : ... } ) 创建表
[*] db.currentOp() displays the current operation in the db
[*] db.dropDatabase() 删除当前数据库
[*] db.eval(func, args) run code server-side
[*] db.getCollection(cname) same as db['cname'] or db.cname
[*] db.getCollectionNames() 获取当前数据库的表名
[*] db.getLastError() - just returns the err msg string
[*] db.getLastErrorObj() - return full status object
[*] db.getMongo() get the server connection object
[*] db.getMongo().setSlaveOk() allow this connection to read from the nonmaster member of a replica pair
[*] db.getName()
[*] db.getPrevError()
[*] db.getProfilingLevel()
[*] db.getReplicationInfo()
[*] db.getSisterDB(name) get the db at the same server as this onew
[*] db.killOp() kills the current operation in the db
[*] db.printCollectionStats() 打印各表的状态信息
[*] db.printReplicationInfo() 打印主数据库的复制状态信息
[*] db.printSlaveReplicationInfo() 打印从数据库的复制状态信息
[*] db.printShardingStatus() 打印分片状态信息
[*] db.removeUser(username) 删除数据库用户
[*] db.repairDatabase() 修复数据库
[*] db.resetError()
[*] db.runCommand(cmdObj) run a database command.if cmdObj is a string, turns it into { cmdObj : 1 }
[*] db.setProfilingLevel(level) 0=off 1=slow 2=all
[*] db.shutdownServer ()
[*] db.version() current version of the server
如果想知道当前数据库下的表或者表 collection支持哪些方法,可以使用一下命令如:
[*]> db.user.help();user为表名
[*]DBCollection help
[*] db.foo.count() 统计表的行数
[*] db.foo.dataSize() 统计表数据的大小
[*] db.foo.distinct( key ) - eg. db.foo.distinct( 'x' ) 按照给定的条件除重
[*] db.foo.drop() drop the collection 删除表
[*] db.foo.dropIndex(name)删除指定索引
[*] db.foo.dropIndexes() 删除所有索引
[*] db.foo.ensureIndex(keypattern,options) - options should be an object with these possible fields: name, unique, dropDups增加索引
[*] db.foo.find( , ) - first parameter is an optional query filter. second parameter is optional set of fields to return. 根据条件查找数据
[*] e.g. db.foo.find( { x : 77 } , { name : 1 , x : 1 } )
[*] db.foo.find(...).count()
[*] db.foo.find(...).limit(n) 根据条件查找数据并返回指定记录数
[*] db.foo.find(...).skip(n)
[*] db.foo.find(...).sort(...) 查找排序
[*] db.foo.findOne() 根据条件查询只查询一条数据
[*] db.foo.getDB() get DB object associated with collection返回表所属的库
[*] db.foo.getIndexes() 显示表的所有索引
[*] db.foo.group( { key : ..., initial: ..., reduce : ...[, cond: ...] } ) 根据条件分组
[*] db.foo.mapReduce( mapFunction , reduceFunction ,)
[*] db.foo.remove(query) 根据条件删除数据
[*] db.foo.renameCollection( newName ) renames the collection重命名表
[*] db.foo.save(obj) 保存数据
[*] db.foo.stats()查看表的状态
[*] db.foo.storageSize() - includes free space allocated to this collection 查询分配到表空间大小
[*] db.foo.totalIndexSize() - size in bytes of all the indexes 查询所有索引的大小
[*] db.foo.totalSize() - storage allocated for all data and indexes 查询表的总大小
[*] db.foo.update(query, object[, upsert_bool]) 根据条件更新数据
[*] db.foo.validate() - SLOW 验证表的详细信息
[*] db.foo.getShardVersion() - only for use with sharding
Mongodb的备份工具 mongodump
如果想备份数据库test 如:
[*]$ ./mongodump --help
[*]options:
[*]--help produce help message
[*]-h [ --host ] arg mongo host to connect to
[*]-d [ --db ] arg database to use
[*]-c [ --collection ] argcollection to use (some commands)
[*]-u [ --username ] arg username
[*]-p [ --password ] arg password
[*]--dbpath arg directly access mongod data files in this path,
[*] instead of connecting to a mongod instance
[*]-v [ --verbose ] be more verbose (include multiple times for more
[*] verbosity e.g. -vvvvv)
[*]-o [ --out ] arg (=dump) output directory
[*]$ ./mongodump -d test -o test/
[*]connected to: 127.0.0.1
[*]DATABASE: test to test/test
[*] test.user to test/test/user.bson
[*] 100000 objects
[*] test.system.indexes to test/test/system.indexes.bson
[*] 1 objects
[*]$ ls
[*]2 mongo mongodump mongofiles mongorestoremongosniff
[*]dumpmongodmongoexportmongoimportmongos test
MongoDB的数据恢复工具 mongorestore
查看test库中的表
[*]> show collections
[*]system.indexes
[*]User
删除user表
[*]> db.user.drop();
[*]True
[*]
[*]> show collections
[*]System.indexes
现在利用mongorestore表恢复刚才利用 mongodump备份的数据
[*]$ ./mongorestore --help
[*]usage: ./mongorestore
[*]options:
[*]--help produce help message
[*]-h [ --host ] arg mongo host to connect to
[*]-d [ --db ] arg database to use
[*]-c [ --collection ] arg collection to use (some commands)
[*]-u [ --username ] arg username
[*]-p [ --password ] arg password
[*]--dbpath arg directly access mongod data files in this path,
[*] instead of connecting to a mongod instance
[*]-v [ --verbose ] be more verbose (include multiple times for more
[*] verbosity e.g. -vvvvv)
[*]
[*]$ ./mongorestore -d test -c user test/test/user.bson
[*]connected to: 127.0.0.1
[*]test/test/user.bson
[*] going into namespace
[*]
[*] 100000 objects
User表中的10w条记录已经恢复
[*]> show collections
[*]system.indexes
[*]user
[*]> db.user.find();
[*]{ "_id" : ObjectId("4b9c8db08ead0e3347000000"), "uid" : 1, "username" : "Falcon.C-1" }
[*]{ "_id" : ObjectId("4b9c8db08ead0e3347010000"), "uid" : 2, "username" : "Falcon.C-2" }
[*]{ "_id" : ObjectId("4b9c8db08ead0e3347020000"), "uid" : 3, "username" : "Falcon.C-3" }
[*]{ "_id" : ObjectId("4b9c8db08ead0e3347030000"), "uid" : 4, "username" : "Falcon.C-4" }
[*]{ "_id" : ObjectId("4b9c8db08ead0e3347040000"), "uid" : 5, "username" : "Falcon.C-5" }
[*].................
[*]has more
mongodb还提供了HTTP查看运行 状态及restfull的接口
默认的访问端口 是28017
rest的访问接口
参考地址:http://www.mongodb.org/display/DOCS/Http+Interface
MongoDB的sharding功能
MongoDB的auto-sharding功能是指mongodb通过mongos自动建立一个水平扩展的数据 库集群 系统 ,将数据库 分表存储在sharding的各个节点上。
一个mongodb集群包括一些shards(包括一些mongod进程 ),mongos路由进程,一个或多个config服务器
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服务)
Shard1:27020
Shard2:27021
Config:27022
Mongos启动时默认使用的27017端口
新建存放数据的目录
[*]$ mkdir 27020 27021 27022
[*]$ ls
[*]270202702127022
[*]
[*]$ ./mongod --dbpath /home/falcon/mongodata/27020 --port 27020 > /home/falcon/mongodata/27020.log &
[*]$ ./mongod --dbpath /home/falcon/mongodata/27021 --port 27021> /home/falcon/mongodata/27021.log &
[*]$ ./mongod --dbpath /home/falcon/mongodata/27022 --port 27022> /home/falcon/mongodata/27022.log &
启动mongos时,默认开启了27017端口
[*]$ ./mongos --configdb localhost:27022 > /home/falcon/mongodata/config.log &
检查是否启动
[*]$ ps -ef|grep mongo
[*]falcon 2612 10 20:15 ? 00:00:00 ./mongod --dbpath /home/falcon/mongodata/27020 --port 27020
[*]falcon 2619 10 20:15 ? 00:00:00 ./mongod --dbpath /home/falcon/mongodata/27021 --port 27021
[*]falcon 2625 10 20:15 ? 00:00:00 ./mongod --dbpath /home/falcon/mongodata/27022 --port 27022
[*]falcon 2658 10 20:15 ? 00:00:00 ./mongos --configdb localhost:27022
[*]falcon 280427720 20:31 pts/0 00:00:00 bin/mongo
[*]falcon 284728120 20:55 pts/2 00:00:00 grep mongo
[*]$
[*]
[*]$ netstat -an-t
[*]Active Internet connections (servers and established)
[*]Proto Recv-Q Send-Q Local Address Foreign Address State
[*]tcp 0 0 0.0.0.0:10022 0.0.0.0:* LISTEN
[*]tcp 0 0 0.0.0.0:27017 0.0.0.0:* LISTEN
[*]tcp 0 0 0.0.0.0:587 0.0.0.0:* LISTEN
[*]tcp 0 0 0.0.0.0:27020 0.0.0.0:* LISTEN
[*]tcp 0 0 0.0.0.0:27021 0.0.0.0:* LISTEN
[*]tcp 0 0 0.0.0.0:27022 0.0.0.0:* LISTEN
[*]......
[*]tcp 0 0 0.0.0.0:28020 0.0.0.0:* LISTEN
[*]tcp 0 0 0.0.0.0:28021 0.0.0.0:* LISTEN
[*]tcp 0 0 0.0.0.0:28022 0.0.0.0:* LISTEN
[*]tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN
[*]........
看到以上信息证明mongodb启动完整,对于开启的28020、28021、28022是对于的http接口
[*]$ ./mongo 默认连接到mongos上
[*]MongoDB shell version: 1.2.4-
[*]url: test
[*]connecting to: test
[*]type "help" for help
[*]> show dbs
[*]admin
[*]config
[*]Local
加 入shard节点
[*]> use admin
[*]switched to db admin
[*]
[*]> db.runCommand( { addshard : "localhost:27020", allowLocal : true } )
[*]{"ok" : 1 , "added" : "localhost:27020"}
[*]
[*]> db.runCommand( { addshard : "localhost:27021", allowLocal : true } )
[*]{"ok" : 1 , "added" : "localhost:27021"}
[*]
[*]> db.runCommand({listshards:1}); 查看shard节点列表
[*]{
[*] "shards" : [
[*] {
[*] "_id" : ObjectId("4b9cd380c33000afad27718e"),
[*] "host" : "localhost:27020"
[*] },
[*] {
[*] "_id" : ObjectId("4b9cd381c33000afad27718f"),
[*] "host" : "localhost:27021"
[*] }
[*] ],
[*] "ok" : 1
[*]}
新 建自动切片的库user001:
[*]> config = connect("localhost:27022")
[*]> config = config.getSisterDB("config")
[*]> user001=db.getSisterDB("user001");
[*]user001
[*]> db.runCommand({enablesharding:"user001"})
[*]{ "ok" : 1 }
[*]
[*]> db.printShardingStatus();
[*]--- Sharding Status ---
[*]sharding version: { "_id" : ObjectId("4b9cd354c33000afad27718d"), "version" : 2 }
[*]shards:
[*] { "_id" : ObjectId("4b9cd380c33000afad27718e"), "host" : "localhost:27020" }
[*] { "_id" : ObjectId("4b9cd381c33000afad27718f"), "host" : "localhost:27021" }
[*]databases:
[*] { "name" : "admin", "partitioned" : false, "primary" : "localhost:27022", "_id" : ObjectId("4b9cd3776693dcfa468dec13") }
[*] { "name" : "user001", "partitioned" : true, "primary" : "localhost:27021", "_id" : ObjectId("4b9cde866693dcfa468dec17") }
[*] my chunks
我们来在user001中新建表,插入数据
[*]> use user001
[*]switched to db user001
[*]> db.createCollection("user_001")
[*]{ "ok" : 1 }
[*]> show collections
[*]system.indexes
[*]user_001
[*]> db.user_001.insert({uid:1,username:"Falcon.C",sex:"男",age:25});
[*]> db.user_001.find();
[*]{ "_id" : ObjectId("4b9ce1a6c84d7f20576c4df1"), "uid" : 1, "username" : "Falcon.C", "sex" : "男", "age" : 25 }
我们来看看user001库被分配到了哪个shard 上
[*]$ ls -R
[*].:
[*]270202702127022mongos.log
[*]
[*]./27020:
[*]27020.logmongod.locktest.0test.1test.ns_tmp
[*]
[*]./27020/_tmp:
[*]
[*]./27021:
[*]27021.logmongod.lock_tmpuser.0user001.0user001.1user001.nsuser.1user.ns
[*]
[*]./27021/_tmp:
[*]
[*]./27022:
[*]27022.logconfig.0config.nsmongod.lockmongos.log_tmp
[*]
[*]./27022/_tmp:
[*]$
从以上的文件可以看出,user001被分配到了 27021的shard上了,但是通过mongos路由,我们并感觉不到是数据存放在哪个shard的chunk上
Sharding的管理 命令
[*]> db.$cmd.findOne({isdbgrid:1});
[*]{ "isdbgrid" : 1, "hostname" : "www.fwphp.cn", "ok" : 1 }
[*]> db.$cmd.findOne({ismaster:1});
[*]{ "ismaster" : 1, "msg" : "isdbgrid", "ok" : 1 }
[*]> printShardingStatus(db.getSisterDB("config"))
[*]--- Sharding Status ---
[*]sharding version: { "_id" : ObjectId("4b9cd354c33000afad27718d"), "version" : 2 }
[*]shards:
[*] { "_id" : ObjectId("4b9cd380c33000afad27718e"), "host" : "localhost:27020" }
[*] { "_id" : ObjectId("4b9cd381c33000afad27718f"), "host" : "localhost:27021" }
[*]databases:
[*] { "name" : "admin", "partitioned" : false, "primary" : "localhost:27022", "_id" : ObjectId("4b9cd3776693dcfa468dec13") }
[*] my chunks
[*] { "name" : "user001", "partitioned" : true, "primary" : "localhost:27021", "_id" : ObjectId("4b9cde866693dcfa468dec17") }
[*] my chunks
[*]> use admin
[*]switched to db admin
[*]> db.runCommand({netstat:1})
[*]{ "configserver" : "localhost:27022", "isdbgrid" : 1, "ok" : 1 }
[*]>
参考信息:http://www.mongodb.org/display/DOCS/Sharding
MongoDB数据库的MapReduce简单操作
MongoDB也简单的实现了MapReduce的功能来提供分布式的数据查询服务 ,MapReduce的分布是功能主要用在Shard上
[*]db.runCommand(
[*]{ mapreduce : ,
[*] map : ,
[*] reduce :
[*] [, query : ]
[*] [, sort : ]
[*] [, limit : ]
[*] [, out : ]
[*] [, keeptemp: ]
[*] [, finalize : ]
[*] [, scope : ]
[*] [, verbose : true]
[*]}
[*]);
下面是对MapReduce的简单测试
此例子来源于:http://www.mongodb.org/display/DOCS/MapReduce
[*]> db.things.insert({_id:1,tags:['dog','cat']});
[*]> db.things.insert({_id:2,tags:['cat']});
[*]> db.things.insert({_id:3,tags:['mouse','cat','dog']});
[*]> db.things.insert({_id:4,tags:[]});
[*]> m = function(){
[*]this.tags.forEach(
[*] function(z){
[*] emit(z,{count:1});
[*] }
[*] );
[*]};
[*]function () {
[*] this.tags.forEach(function (z) {emit(z, {count:1});});
[*]}
[*]> r=function(key,values){
[*]... var total = 0;
[*]... for(var i=0;i res=db.things.mapReduce(m,r);
[*]{
[*] "result" : "tmp.mr.mapreduce_1268577545_1",
[*] "timeMillis" : 25,
[*] "counts" : {
[*] "input" : 4,
[*] "emit" : 6,
[*] "output" : 3
[*] },
[*] "ok" : 1,
[*] "ok" : 1,
[*]}
[*]> res
[*]{
[*] "result" : "tmp.mr.mapreduce_1268577545_1",
[*] "timeMillis" : 25,
[*] "counts" : {
[*] "input" : 4,
[*] "emit" : 6,
[*] "output" : 3
[*] },
[*] "ok" : 1,
[*] "ok" : 1,
[*]}
[*]
[*]> db.find()
[*]{ "_id" : "cat", "value" : { "count" : 3 } }
[*]{ "_id" : "dog", "value" : { "count" : 2 } }
[*]{ "_id" : "mouse", "value" : { "count" : 1 } }
[*]> db.drop()
[*]true
[*]> db.find()
[*]>
页:
[1]