玩转MongoDB
一、主从复制
1)首先主从服务器在启动的时候,分别要设置master、slave选项,对于slave可以启动中设置源,也可以在启动后设置源。
如:主:mongod --dbpath=/data/mongo/master/ --port=2900 --master
从:mongod --dbpath=/data/mongo/slave2 --port=2920 --slave --source=localhost:2900 命令行中指定源
mongod --dbpath=/data/mongo/slave3 --port=2930 --slave 命令行中不指定源
2)主从的管理,进入local数据库,然后查看sources集合
{ "_id" : ObjectId("529d4547f10708cc62960013"), "host" : "localhost:3000", "source" : "main", "syncedTo" : { "t" : 1386039340000, "i" : 1 } } --表示到主的同步已经完成
3)可以在sources中增加记录,来添加一个新的源,删除记录来删除一个源
db.sources.insert({"host":"localhost:2900"}) ---增加一个源,当同步好了之后,该记录会有source和syncdTo字段 db.sources.remove({"host":"localhost:2900"}) --移除一个源
注意:若只有一个源,删除后又会自动被加上,也就是最后一个源无法删除。若两个源有相同的集合那么会被合并到一起。
同步需要一定时间,需要等待一会才看得到效果。
若在命令行指定sources运行,此时的若local数据库的sources表有记录并且没有指定的host则会报错,启动失败。若没有sources没有记录则会添加到其中。(在mac上采用sources的insert,remove方式没法成功)。
二、副本集
虽然主从复制模式中,从数据库默认就可以作为读扩展数据库,但是当主数据库宕机后,该主从模式无法自动恢复,也就是不能写入数据,而变成一个只读的数据库。
相对来说,副本集,具备自动恢复的功能。假若副本集中的primary宕机,那么剩下的几个secondy将进行投票重新产生一个primary,从而达到自动恢复服务的能力。
1、初始化副本集
--在三个端口上驱动三个mongod实例,使用--replSet指定副本集名称为zcs mongod --dbpath=/data/mongo/node1 --port=2901 --replSet=zcs mongod --dbpath=/data/mongo/node2 --port=2902 --replSet=zcs mongod --dbpath=/data/mongo/node3 --port=2903 --replSet=zcs --连接任意一个mongod实例,例如这里2903,默认情况下执行初始化的mongod实例会被变成主节点。 mongo --port 2903 --选择admin数据库 use admin --执行副本集的初始化命令,其中的host表示为,hostname:port, hostname可通过 cat /etc/hostname 查看
db.runCommand({"replSetInitiate":{"_id":"zcs","members":[{"_id":1,"host":"localhost:2901"},{"_id":2,"host":"localhost:2902"},{"_id" : 3,"host" : "localhost:2903" }]}})
配置好之后,
2、查询副本集的备用节点
默认情况下,副本集中的SECONDARY不允许查询,这时候可以通过如下命令设置为可查询(但是要注意,数据写入到主节点,异步同步到从节点会有一个时间差)。
--连接到从节点执行如下任意一个命令
rs.slaveOk();
db.getMongo().setSlaveOk();
3、一些问题
1)识别当前哪个是主那个是从,可以通过命令行连接到服务器查看,若命令行显示为PRIMARY则为主,SECONDARY则为从
2)关于节点类型:standard(包括PRIMARY、SECONDARY),passive(存储数据副本,参与投票,不能成为活跃节点),arbiter(仲裁节点,只参与投票)。
3)当配置好了之后,
如果PRIMARY宕机,这时候有权利参与投票的节点,将进行投票,根据优先级与数据新旧重新选出PRIMARY。
如果SECONDARY宕机,则不影响使用,当其重新启动后,将再次成为SECONDARY。
由于至少两台机器才能进行投票,因此若为一个主,一个从,当主宕机后,将无法进行投票,也就无法恢复,这时候可以考虑加入一个arbiter节点,用于参加投票。
副本集的配置信息,可以在主服务器的local数据库 db.system.replset 集合之中查看。
4)关于副本集命令 rs
rs.add()
rs.addArb()
rs.conf()
rs.freeze()
rs.help()
rs.initiate()
rs.reconfig()
rs.remove()
rs.slaveOk()
rs.status()
rs.stepDown()
rs.syncFrom()
参考:http://docs.mongodb.org/manual/reference/method/js-replication/
三、自动分片
如果说主从与副本集可以缓解读压力,那么分片可以缓解写压力。
关于片键的选择:1)顺序递增类型,时间戳作为键就是这种类型,新的数据时间戳总是递增,那么这些数据总是会被写入到一个片之中,此时就无法达到分散写压力,但是在读取数据时就较快,因此只要读取一个片。2)散列型,比如使用时间戳的哈希值,此时新增的数据由于执行了哈希大体上会被均匀的分散在不同片之中,此时达到了缓解写压力的目的,但是由于需要读取所有片,因此较慢。
比如使用user_id作为片键,通常新注册的用户user_id是递增的,因此新用户的写压力会到同一个shard上。而旧用户的写则会分散到多个shard之上,同时由于读取时只要查询一个shard,因此读取效率较高。
1、配置
--启动配置服务器,其中保存分片等信息 mongod --dbpath=/data/mongo/config/ --port=3000 --启动mongos,在命令行提供配置服务器 mongos --port 3001 --configdb localhost:3000 --连接mongos实例,执行如下的分片命令 db.runCommand({addshard: "localhost:3002",allowLocal: true}) --设置分片数据库为zcs db.runCommand({"enablesharding":"zcs"}) --设置分片的集合,需要有数据库前缀如,zcs.names db.runCommand({"shardcollection":"zcs.names","key":{"name":1}}) --还可以使用removeshard命令删除一个分片 db.runCommand({addshard: "localhost:3002",allowLocal: true})
2、查看配置
使用mongo连接config实例,进入到config数据库,可以查看各种数据
chunks --集合分片的chunk位置 collections --分片的集合 databases --分片的数据库 mongos --链接的mongos shards --分片信息
当removeshard命令执行删除一个片的时候,该片上的数据会被拷贝到其他片上。
四、查看内存使用情况
1、使用db.stats()来查看该数据库作占用的资源:
参考文档:http://docs.mongodb.org/manual/reference/method/db.stats/
PRIMARY> db.stats(); { "db" : "test", "collections" : 4, "objects" : 19929004, "avgObjSize" : 3915.250832605583, --每个文档的平均大小,由datasize/docnum "dataSize" : 78027049504, --数据库持有的数据大小为78GB,该值包括padding factor(调整每次数据多分配因子)的影响 "storageSize" : 82040499664, --分配用作文档存储的空间82GB "numExtents" : 68, "indexes" : 4, --索引个数 "indexSize" : 1606297840, --索引大小为160MB "fileSize" : 87937777664, "nsSizeMB" : 16, --命名空间的文件大小为16MB,该值可以修改 "dataFileVersion" : { "major" : 4, "minor" : 5 }, "ok" : 1 }
2、使用mongostat来查看占用资源及各项指标
参考文档:http://docs.mongodb.org/manual/reference/program/mongostat/
[root@db13 ~]# mongostat --port 27017 connected to: 127.0.0.1:27017 insert query update delete getmore command flushes mapped vsize res faults locked % idx miss % qr|qw ar|aw netIn netOut conn set repl time *0 *0 162 16 0 184|0 1 82g 165g 8.04g 123 0 0 7|0 0|1 160k 42k 76 shard1 M 10:24:07 *0 *0 1000 97 0 1107|0 0 82g 165g 8.04g 740 0.5 0 0|0 0|0 980k 211k 76 shard1 M 10:24:08
mapped 执行了mapped的数据大小
vsize 占用的虚拟内存大小(该值为mapped数值的两倍,是由于默认打开了jounal)
res 实际占用的物理内存
3、使用pmap
[root@db13 ~]# pmap 12565 0000000000400000 17392K r-x-- /mnt/ssd/wuchao/mongodb/bin/mongod 00000000016fc000 480K rw--- /mnt/ssd/wuchao/mongodb/bin/mongod 0000000001774000 4100K rw--- [ anon ] 00007fd5a5424000 2096128K rw--- /mnt/ssd/wuchao/mongodb/data/shard1/test.43 00007fd625324000 2096128K rw-s- /mnt/ssd/wuchao/mongodb/data/shard1/test.43 00007fd6a5224000 2096128K rw--- /mnt/ssd/wuchao/mongodb/data/shard1/test.42 00007fd725124000 2096128K rw-s- /mnt/ssd/wuchao/mongodb/data/shard1/test.42 00007fd7a5024000 2096128K rw--- /mnt/ssd/wuchao/mongodb/data/shard1/test.41
这些test.41文件实际上就是数据库test的文件,整个被mmap到虚拟内存之中了,把这些test文件加起来就是虚拟内存大小了。
参考:http://blog.nosqlfan.com/html/2865.html
http://www.csdn.net/article/2012-11-15/2811920-mongodb-quan-gong-lue