1、下载
wget http://fastdl.mongodb.org/linux/mongodb-linux-i686-1.6.5.tgz tar -xzvf mongodb-linux-i686-1.6.5.tgz
2、测试单机环境
下载回来的MongoDB是已经编译好的,直接使用即可。
#首先建立数据库位置 mkdir ~/soft/mongodb/data cd mongodb-linux-i686-1.6.5 cd bin #启动mongodb服务器端,注意指定额外的数据库存放位置 ./mongod --dbpath=/home/liheyuan/soft/mongodb/data #启动mongodb客户端 ./mongo #查看当前选定的数据库 > db test #保存一个obj > db.test.save({a:1}) #查看结果 > db.test.find() { "_id" : ObjectId("4d6e27081e960da4f8a23518"), "a" : 1 }
3、使用dbshell深入单机环境
mongo提供的dbshell是一个初步学习MongoDB数据库类型的好工具。
#选择其他数据库 > use mydb switched to db mydb > db mydb #显示所有数据库 > show dbs admin local test thing things #创建对象后再插入,可以注意到每个插入的对象会被自动附一个id(_id字段) #同时,我们之前并没有定义任何数据表的结构(甚至连数据表的名字我们都没有指定),因此说MongoDB是一个schema-free的。 > j = {name:"mongodb"} { "name" : "mongodb" } > i = {b:3} { "b" : 3 } > db.thing.save(j) > db.thing.save(i) > db.thing.find() { "_id" : ObjectId("4d6e28911e960da4f8a2351a"), "name" : "mongodb" } { "_id" : ObjectId("4d6e28961e960da4f8a2351b"), "b" : 3 } #如果插入的超过20条,会被自动截屏,我们可以用it命令迭带看下20条。find返回的是一个iterator(cursor)对象 > it #另外一种方法,我们显示的使用cursor > var cur = db.thing.find() > while (cur.hasNext()) printjson(cur.next()) { "_id" : ObjectId("4d6e28911e960da4f8a2351a"), "name" : "mongodb" } { "_id" : ObjectId("4d6e28961e960da4f8a2351b"), "b" : 3 } #第三中方法,使用foreach db.things.find().forEach(printjson); #对于数据: #{ "_id" : ObjectId("4d6e2c3a0cc156c6903a40fe"), "a" : 1, "b" : 2 } #{ "_id" : ObjectId("4d6e2c3f0cc156c6903a40ff"), "a" : 2, "b" : 3 } #{ "_id" : ObjectId("4d6e2c420cc156c6903a4100"), "a" : 3, "b" : 3 } #查询 SELECT * FROM thing WHERE b=2 (select*) > db.thing.find({b:2}) { "_id" : ObjectId("4d6e2c3a0cc156c6903a40fe"), "a" : 1, "b" : 2 } #查询 SELECT j FROM things WHERE b=2 (只选择b列) > db.thing.find({b:2},{b:true}) { "_id" : ObjectId("4d6e2c3a0cc156c6903a40fe"), "b" : 2 } { "_id" : ObjectId("4d6e2dec4811e5c557f8fa43"), "b" : 2 } #使用findOne(),只显示第一行(较为高效) > db.thing.findOne({b:2}) { "_id" : ObjectId("4d6e2c3a0cc156c6903a40fe"), "a" : 1, "b" : 2 } #使用limit,限制返回几行 > db.thing.find({b:2},{b:true}).limit(1) { "_id" : ObjectId("4d6e2c3a0cc156c6903a40fe"), "b" : 2 } #删除 > db.thing.remove({a:3})
4、MongoDB的update
#语法 db.collection.update( criteria, objNew, upsert, multi ) criteria : update的查询条件,类似sql update查询内where后面的 objNew : update的对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询内set后面的 upsert : 这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。 multi : mongodb默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。 例: db.test0.update( { "count" : { $gt : 1 } } , { $set : { "test2" : "OK"} } ); 只更新了第一条记录 db.test0.update( { "count" : { $gt : 3 } } , { $set : { "test2" : "OK"} },false,true ); 全更新了 db.test0.update( { "count" : { $gt : 4 } } , { $set : { "test5" : "OK"} },true,false ); 只加进去了第一条 db.test0.update( { "count" : { $gt : 5 } } , { $set : { "test5" : "OK"} },true,true ); 全加进去了 db.test0.update( { "count" : { $gt : 15 } } , { $inc : { "count" : 1} },false,true );全更新了 db.test0.update( { "count" : { $gt : 10 } } , { $inc : { "count" : 1} },false,false );只更新了第一条 此外,save()相当于自动判断_id字段的更新(如果没有_id相同的则自动插入新的) update中第2个参数使用$inc可以给数值类型加一 update中第2个参数使用$set可以添加字段 update中第2个参数使用$unset可以删除字段,如:db.test0.update( { "_id" : 15 } , { $unset : { "test3":"test" } } );
5、MongoDB的分布式配置
参考资料:
http://hi.baidu.com/lzpsky/blog/item/d59af4276c73c50f908f9d5d.html
http://blog.jokry.me/2010/07/mongodb-distributable-slice/
http://www.cnblogs.com/daizhj/archive/2010/09/07/1820528.html
http://www.iwanna.cn/archives/2010/09/17/5313/
http://www.iwanna.cn/archives/2010/09/17/5310/
结点类型及数据:
Shard:Node,存储了若干Chunks(默认大小100MB)
Config Server:Meta Server,存了Shard信息和Chunk信息。
Router(mongos):暂时解释不清楚,它和Config Server放在一个服务器上就可以了。
#在一台机器上模拟2个Shard和1个Config Server cp -rf mongodb mongodb_1 cp -rf mongodb mongodb_2 cp -rf mongodb mongodb_3 #启动Shard1(注意添加参数) cd mongodb_1 ./bin/mongod --shardsvr --dbpath /home/liheyuan/soft/mongodb_1/data/ --port 20001 #启动Shard2 cd mongodb_2 ./bin/mongod --shardsvr --dbpath /home/liheyuan/soft/mongodb_2/data/ --port 20002 #启动Config Server(注意添加参数--configsvr) cd mongodb_3 ./bin/mongod --configsvr --dbpath /home/liheyuan/soft/mongodb_3/data/ --port 20003 #启动mongos(一个Router),这个是所有其他连接的入口,指定config的ip:port,而mogos的启动port是27017 bin/mongos --configdb localhost:20003 #客户端连接Config Server cd ../mongodb_3 bin/mongo > use admin #添加Shard > use admin switched to db admin > db.runCommand({addshard:"localhost:20001"}) { "shardAdded" : "shard0000", "ok" : 1 } > db.runCommand({addshard:"localhost:20002"}) { "shardAdded" : "shard0001", "ok" : 1 } #查看已经添加的Shard > db.runCommand({listshards:1}) { "shards" : [ { "_id" : "shard0000", "host" : "localhost:20001" }, { "_id" : "shard0001", "host" : "localhost:20002" } ], "ok" : 1 } #在指定的数据库上开启Sharding > db.printShardingStatus() --- Sharding Status --- sharding version: { "_id" : 1, "version" : 3 } shards: { "_id" : "shard0000", "host" : "localhost:20001" } { "_id" : "shard0001", "host" : "localhost:20002" } databases: { "_id" : "admin", "partitioned" : false, "primary" : "config" } > db.runCommand({enablesharding:"test"}) > db.printShardingStatus() --- Sharding Status --- sharding version: { "_id" : 1, "version" : 3 } shards: { "_id" : "shard0000", "host" : "localhost:20001" } { "_id" : "shard0001", "host" : "localhost:20002" } databases: { "_id" : "admin", "partitioned" : false, "primary" : "config" } { "_id" : "test", "partitioned" : true, "primary" : "shard0000" } 注:一旦enable了个数据库,mongos将会把数据库里的不同数据集放在不同的分片上。除非数据集被分片(下面会设置),否则一个数据集的所有数据将放在一个分片上。 #在Mongodb中,一个服务器可以又多个数据库,一个数据库可以又多个Collection(相当于表),Collection中存放多个文档 #开启数据集分片(test数据库的post Collection) db.runCommand({shardcollection:"test.post",key:{_id:1},unique:true}) #查看开启情况 > use test switched to db test > show collections post system.indexes > db.post.stats() { "sharded" : true, "ns" : "test.post", "count" : 0, "size" : 0, "avgObjSize" : NaN, "storageSize" : 8192, "nindexes" : 1, "nchunks" : 1, "shards" : { "shard0000" : { "ns" : "test.post", "count" : 0, "size" : 0, "avgObjSize" : NaN, "storageSize" : 8192, "numExtents" : 1, "nindexes" : 1, "lastExtentSize" : 8192, "paddingFactor" : 1, "flags" : 1, "totalIndexSize" : 8192, "indexSizes" : { "_id_" : 8192 }, "ok" : 1 } }, "ok" : 1 }
可以从上面的post的Collection看出,分片已经开启成功!
6、MongoDB的c客户端使用
上面为止,我们只是完成了对MongoDB的配置,使用的是dbshell,在日常场景中,显然要从c/c++/python/java等编程语言中直接存取MongoDB,下面使用c客户端完成这个工作。
#编译 sudo apt-get -y install git-core git clone git://github.com/mongodb/mongo-c-driver.git
你好,能简单说说为什么配它的分布式而不是它速度不如mysql呢?我自己测的速度不如mysql…当然安装等等确实方便了很多…简单交流下
@omar:
你的数据规模又多大?多少个字段,多少记录?
首先,有很多参数需要调优,这个我还没有做过。
MongoDB的Replication和Shard主要解决两个问题:
1、横向拓展问题,比如现在速度课接受,但数据大了后怎么办?一种选则是换更NB的机器,第二种就是两台机器一起跑。MongoDB就是第2种,可拓展行较好。
2、读密集写不密集情况。即单点写入,多点读出可大大缓解读取压力,提升系统性能。而很多系统中,确实写的很少。当然代价就是不同步。
你确定你的机器内存够么?
你不会是在vps上什么的跑吧?我自己测试,最慢每秒写都可达到10000/秒,比mysql好很多了。
@omar: 内存不够的时候,MongoDB性能会下降很快,毕竟他是内存数据库,性能的提升都是靠存在内存中(定期dump到硬盘持久化)获得的。Mongo很吃内存的,一般100w个记录(每个记录1k)就能搞到500MB了。
谢谢回复。
我是简单的测试,使用jdbc连mysql,然后用mongo的驱动连mongo,然后对几万条数据进行读取,简单比对了时间使用。
我通常是mysql负责存储,memcached负责缓存,数据过大之后将其分布式配置。
所以不太了解monogo的优势。