浅谈MongoDB的认识
MongoDB是可灵活扩展的数据存储方式。它是面向文档的数据库,不是关系型数据库。基本思想是将原来的row的概念换成更加灵活的document模式,它扩展了关系型数据库的众多功能,如辅助索引、范围查询和排序
? 键值(Key-Value)存储型– Memcached、 Tokyo Cabinet、 Redis
? 列存储型– Cassadra、 HBase
? 图形(Graph)数据库– Neo4J、 InfoGrid、 Infinite Graph
? 文档型– MongoDB、 CouchDB
MongoDB关键特性都有哪些
– MongoDB关键特性
? Document-Oriented Storage 面向文档存储的数据类型
? Full Index Support 多种索引的支持
? Replication & High Availability
? Auto-Sharding 自动分片
? Rich Querying 丰富的查询
? Updates
? Map/Reduce
? GridFS 大文件存储
MongoDB关键特性
? Full Index Support
– 类似于RDBMS
– _id 一个集合的_id不能重复,但是多个集合的_id是不受限制的,可以重复。唯一标示一条文档。
– B-Tree:Btree索引,允许使用多个索引,每个集合最多能创建64个index(可建唯一索引、联合索引、升序、降序索引)
– 地理空间索引:为坐标平面查询提供的查询索引
MongoDB关键特性
? Replication & High Availability
– Master-Slave 主从复制模式:备份、故障恢复、负载作用(类似mysql的主从)
– Replica Set 副本集复制模式:自动故障恢复的主从模式(类似oracle的DG)
Auto-Sharding
– 数据迁移
– 应用程序升级
MongoDB关键特性
? Rich Querying
? Updates
Map/Reduce :mongodb可使用map/reduce并行统计。作为后台执行,再查下结果集
– Map
– Reduce
– 举例
GridFS:存储大型二进制文件——将大型文件分成许多块,将每个块作为单独的文件进行存放,它使用两张表来存放:fs.files、s.chunks
– 16MB
– fs.files:存储文件元数据信息,包含文件类型总的字节数,_id,时间戳、md5校验和等
– fs.chunks:存储文件内容,存储了大文件的具体分块的二进制数据。
MongoDB适用场景
? Web应用程序:表量少(关系型db多表,在mongodb上只需要一张表)、丰富查询支持、多种索引
? 敏捷开发:free schema
? 分析和日志:目标原子更新、固定集合(固定大小,循环链表的写,可设置定时过期:Time To Live (TTL) 集合)
? 缓存:高效性、持久化、数据一致性
? 可变Schema:不知晓的数据结构的存储使用mongodb很好
一.RDBMS,MongoDB的优缺点?
1.RDBMS与MongoDB相比MongoDB的优点:
(1)弱一致性(最终一致),更能保证用户的访问速度
(2)文档结构的存储方式,能够更便捷的获取数据
(3)内置GridFS,支持大容量的存储
(4)内置Sharding
(5)第三方支持丰富(10gen)
(6)性能优越
2.RDBMS与MongoDB相比MongoDB的缺点:
(1)mongodb不支持事务操作
(2)mongodb占用空间过大
(3)应用经验缺乏,没有相关NoSQL 产品的使用经验
(4)项目相对来说还比较新
二.MongoDB集群部署方式?
Mongodb集群搭建的三种方式:
1.Replica Set 副本集(类似MySQL的MHA)
1.1Replica Set 副本集介绍:
MongoDB Replica Set是MongoDB官方推荐的主从复制和高可用方案,用于替代原有的Master-Slave主从复制方案。Replicat Set具有自动切换功能,当Primary挂掉之后,可以自动由Replica Set中的某一个Secondary来切换到Primary,以实现高可用的目的。
1.2MongoDB Replica Set的原理
复制主要用于备份、灾难恢复和读写分离。一个Replica Set就是一组mongod实例。Replica Set中的Primary接收所有的写操作,Secondaries从Primary复制操作然后应用到自己的data set。
一个Replica Set中的成员角色有三种:Primary,Secondary和Arbiter。
Primary 接收来自客户端的所有的写操作,一个Replica Set中有且只有一个Primary。Primary如果宕掉,Replica Set会自动选举一个Secondary成为Primary。Primary将它data sets的所有操作都记录到oplog中。
Secondary Secondary从Primary复制oplog,然后将oplog中的操作应用到自己的data sets。Secondary和Primary之间是异步复制,也就是Secondary中的数据可能不是最新的。默认情况下,Secondary不可读不可写,但是可以通过设置运行客户端从Secondary读。
Arbiter Arbiter不需要维护自己的data sets,只是当Primary挂掉之后参与投票选择哪个Secondary可以升级为Primary。当Replica Set中的成员个数为偶数个时,就需要添加一个Arbiter用于投票选举哪个可以升级为Primary。Arbiter对硬件的要求很低。不能在Primary或者Secondary主机上运行Arbiter。
一个Replica Set可以最多拥有12个成员,但是只有7个成员可以同时参与投票选举成为Primary,如果成员数量超过12,就需要使用Master-Slave主从复制方式。
部署一个Replica Set至少需要三个成员,一个Arbiter,一个Secondary和一个Primary或者一个Primary,两个Secondary。
可以将Secondary配置为以下几种特殊用途:
A.在选举中阻止其成为Primary,只用作备份数据。通过设置优先级priority为0来实现。
B.阻止应用程序从它读,通过设置优先级priority为0和设置hidden为true来实现。
一个隐藏的成员同样复制Primary的数据,但是对于客户端应用程序来讲,它不可见。
C.保留历史镜像数据用于数据回档,比如如果误删除数据,可以使用Delayed Replica Set成员中的数据恢复。
Delayed members即延时成员会延时从Primary复制oplog
1.3MongoDB Replica Set部署架构
Replica Set Elections 复制集选举
Replica Set通过投票选举的方式来决定哪个成员可以升级为Primary。初始化一个Replica Set后就会产生选举出现,或者任何时候当Primary不可用时也会有选举出现。需要注意的是,投票选举Primary会花费一定的时间来完成,在这段时间内,整个Replica Set无法进行写操作,所以尽量避免重新投票选举的情况出现。
影响选举的因素和条件有:
Heartbeats 心跳检测
Replica Set中成员每2秒向其他成员发送心跳,如果在10秒内无回应,这个成员就被其他成员标记为不可用。
Priortiy Comparisons 对比优先级
设定成员的优先级priority会影响投票选举,优先级越高,越容易被选举成为Primary。如果优先级设置为0,那么这个成员不会永远不会被选举成为Primary,它也不需要其他成员为它投票。
Optime
Optime是Replica Set的成员上一次从oplog中将操作应用到data sets的时间戳。一个成员不会成为Primary,除非它比其他可见的成员拥有最新的时间戳。
Connections
一个Replica Set中的成员如果想要成为Primary,它必须能够连接这个Replica Set中具有投票权利的大部分成员。
Network Partitions
为了避免当Primary宕掉后,整个Replica Set无法选举出新的Primary,Replica Set变成只读,需要在一个数据中心放置大部分Replica Set中的成员实例。
1.4MongoDB Replica Set部署步骤
Replica Set使用的是n个mongod节点,构建具备自动的容错功能(auto-failover),自动恢复的(auto-recovery)的高可用方案。
使用Replica Set来实现读写分离。通过在连接时指定或者在主库指定slaveOk,由Secondary来分担读的压力,Primary只承担写操作。
对于Replica Set中的secondary 节点默认是不可读的。
192.168.10.163 |
PRIMARY |
192.168.10.164 |
SECONDARY |
192.168.10.165 |
ARBITER |
[root@slave63 ~]# mkdir -p /data/mongodb [root@slave63 ~]# tar -zxvf mongodb-linux-x86_64-2.6.5.tgz -C /data/mongodb/ [root@slave63 ~]# cd /data/mongodb/ [root@slave63 mongodb]# mv mongodb-linux-x86_64-2.6.5/ mongodb/ [root@slave63 mongodb]# mkdir -p /data/mongodb/data [root@slave63 mongodb]# mkdir -p /data/mongodb/log [root@slave63 bin]# pwd /data/mongodb/mongodb/bin [root@slave63 bin]# ./mongod --replSet replsettest --dbpath /data/mongodb/data --oplogSize 100 --logpath /data/mongodb/log/mongodb.log --logappend --fork [root@slave63 bin]# ps -ef |grep mongo root 623 1 0 18:00 ? 00:00:00 ./mongod --replSet replsettest --dbpath /data/mongodb/data --oplogSize 100 --logpath /data/mongodb/log/mongodb.log --logappend --fork root 692 356 0 18:01 pts/1 00:00:00 grep mongo [root@slave63 bin]#
config={_id:"replsettest",members:[ {_id:0,host:"192.168.10.163:27017"}, {_id:1,host:"192.168.10.164:27017"}, {_id:2,host:"192.168.10.165:27017",arbiterOnly:true}]}
[root@slave63 bin]# ./mongo MongoDB shell version: 2.6.5 connecting to: test > config={_id:"replsettest",members:[ ... {_id:0,host:"192.168.10.163:27017"}, ... {_id:1,host:"192.168.10.164:27017"}, ... {_id:2,host:"192.168.10.165:27017",arbiterOnly:true}]} { "_id" : "replsettest", "members" : [ { "_id" : 0, "host" : "192.168.10.163:27017" }, { "_id" : 1, "host" : "192.168.10.164:27017" }, { "_id" : 2, "host" : "192.168.10.165:27017", "arbiterOnly" : true } ] } > rs.initiate(config) //初始化 { "info" : "Config now saved locally. Should come online in about a minute.", "ok" : 1 } > > rs.conf() //查看配置内容 { "_id" : "replsettest", "version" : 1, "members" : [ { "_id" : 0, "host" : "192.168.10.163:27017" }, { "_id" : 1, "host" : "192.168.10.164:27017" }, { "_id" : 2, "host" : "192.168.10.165:27017", "arbiterOnly" : true } ] } replsettest:PRIMARY>
rs.status() //查看状态信息 replsettest:PRIMARY> rs.status() { "set" : "replsettest", "date" : ISODate("2015-06-30T10:54:05Z"), "myState" : 1, "members" : [ { "_id" : 0, "name" : "192.168.10.163:27017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 3204, "optime" : Timestamp(1435661535, 1), "optimeDate" : ISODate("2015-06-30T10:52:15Z"), "electionTime" : Timestamp(1435661546, 1), "electionDate" : ISODate("2015-06-30T10:52:26Z"), "self" : true }, { "_id" : 1, "name" : "192.168.10.164:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 109, "optime" : Timestamp(1435661535, 1), "optimeDate" : ISODate("2015-06-30T10:52:15Z"), "lastHeartbeat" : ISODate("2015-06-30T10:54:04Z"), "lastHeartbeatRecv" : ISODate("2015-06-30T10:54:04Z"), "pingMs" : 0, "syncingTo" : "192.168.10.163:27017" }, { "_id" : 2, "name" : "192.168.10.165:27017", "health" : 1, "state" : 7, "stateStr" : "ARBITER", "uptime" : 107, "lastHeartbeat" : ISODate("2015-06-30T10:54:04Z"), "lastHeartbeatRecv" : ISODate("2015-06-30T10:54:04Z"), "pingMs" : 0 } ], "ok" : 1 } replsettest:PRIMARY> 验证: replsettest:PRIMARY> db.test.insert({"name":"cathy","age":24}) WriteResult({ "nInserted" : 1 }) replsettest:PRIMARY> db.test.find() { "_id" : ObjectId("559275cbd3a606958046b031"), "name" : "cathy", "age" : 24 } 从库查看 164: [root@164 bin]# ./mongo MongoDB shell version: 2.6.5 connecting to: test replsettest:SECONDARY> db.test.find() error: { "$err" : "not master and slaveOk=false", "code" : 13435 } replsettest:SECONDARY> db.getMongo().setSlaveOk() replsettest:SECONDARY> db.test.find() { "_id" : ObjectId("559275cbd3a606958046b031"), "name" : "cathy", "age" : 24 }
165: [root@165 bin]# ./mongo MongoDB shell version: 2.6.5 connecting to: test replsettest:ARBITER> db.test.find() error: { "$err" : "not master and slaveOk=false", "code" : 13435 } replsettest:ARBITER> db.getMongo().setSlaveOk() replsettest:ARBITER> db.test.find() error: { "$err" : "not master or secondary; cannot currently read from this replSet member", |
原文:http://blog.itpub.net/26373260/viewspace-1724412/