由网络副手--寻路人于2016.06.12 18:11:00发布在NoSql技术 MongoDB 架构搭建的四种形态 阅读6860 评论2 喜欢3 前言:MongoDB 安装路径以及配置路径 MongDB 安装位置 /usr/local/mongodb3.26/ bin conf dbs logs workspaces(独自新建) --mongo_01 (单个配置) --dbs 三个配置的数据库文件存储目录 --logs 日志目录 --mongodb.conf 每个配置下独立的配置文件 --mongo_02 --mongo_03 一、单点结构 结构简单,一台机器即可,搭建快速,适用小数据量,对数据安全性要求低的情况 ![1.jpg][1] 配置文件文件 vim /usr/local/mongodb3.26/conf/mongodb.conf dbpath = /usr/local/mongodb3.26/dbs logpath = /usr/local/mongodb3.26/logs/mongodb.log bind_ip = 127.0.0.1 port = 27017 fork = true nohttpinterface = true 启动: /usr/local/mongodb3.26/bin/mongod --config /usr/local/mongodb3.26/conf/mongodb.conf 二、主从复制结构 结构简单,搭建快速,有一定的容灾性,当主库数据遭破坏后,可快速恢复服务和数据,但无法做到自动切换 ![2.jpg][2] vim /usr/local/mongodb3.26/workspaces/mongo_01/mongodb_01.conf dbpath = /usr/local/mongodb3.26/workspaces/mongo_01/dbs logpath = /usr/local/mongodb3.26/workspaces/mongo_01/logs/mongodb.log bind_ip = 127.0.0.1 port = 27001 fork = true nohttpinterface = true master=true (主库) #启动 /usr/local/mongodb3.26/bin/mongod --config /usr/local/mongodb3.26/workspaces/mongo_01/mongodb_01.conf vim /usr/local/mongodb3.26/workspaces/mongo_02/mongodb_02.conf dbpath = /usr/local/mongodb3.26/workspaces/mongo_02/dbs logpath = /usr/local/mongodb3.26/workspaces/mongo_02/logs/mongodb.log bind_ip = 127.0.0.1 port = 27002 fork = true nohttpinterface = true slave=true (从库) source=127.0.0.1:27001 (接收主库数据) #启动 /usr/local/mongodb3.26/bin/mongod --config /usr/local/mongodb3.26/workspaces/mongo_02/mongodb_02.conf 启动后,在从库查询会暴错. [thread1] Error: listDatabases failed:{ "ok" : 0, "errmsg" : "not master and slaveOk=false", "code" : 13435 } 解决方案: rs.slaveOk(); 设置允许读写操作. 可以通过 mongo 127.0.0.1:27001 或者更换端口来切换库 如果后期想再拓展增加一个从库 vim workspaces/mongo_03/mongodb_03.conf dbpath = /usr/local/mongodb3.26/workspaces/mongo_03/dbs logpath = /usr/local/mongodb3.26/workspaces/mongo_03/logs/mongodb.log bind_ip = 127.0.0.1 port = 27003 fork = true nohttpinterface = true slave = true source = 127.0.0.1:27001 #启动 /usr/local/mongodb3.26/bin/mongod --config /usr/local/mongodb3.26/workspaces/mongo_03/mongodb_03.conf 数据启动后,会主动从主库复制一份数据,如果在从库执行操作会提示. WriteResult({ "writeError" : { "code" : 10107, "errmsg" : "not master" } }) 三、副本集结构 由数据结点,投票结点组成,需要配置集群信息,可自动检测集群中的结点健康状态,当有结点出故障时,自动下线和切换主从结点。适用于数据量较大,高可用服务 ![3.jpg][3] mongodb Replica Set 副本集构建: Replica Set 节点类型分为三种: standard:常规节点,它存储一份完整的数据副本,参与选举投票,有可能成为primary节点; passive:存储了完整的数据副本,参与投票,不能成为primary节点; arbiter:仲裁节点,只参与投票,不接收复制的数据,也不能成为primary节点。 2个常规节点和一个arbiter节点,arbiter节点由于不同步数据,所以负载会很小,部署对硬件没有太大的要求。 ###arbiter 节点### dbpath = /usr/local/mongodb3.26/workspaces/mongo_04/dbs logpath = /usr/local/mongodb3.26/workspaces/mongo_04/logs/mongodb.log bind_ip = 127.0.0.1 port = 27004 #以守护进程启动 fork = true nohttpinterface = true directoryperdb=true #master = true 否则会报错 #F CONTROL [main] Failed global initialization: BadValue: replication.replSet is not allowed when master is specified replSet=rs_setname/127.0.0.1:27005,127.0.0.1:27006 启动: /usr/local/mongodb3.26/bin/mongod -f /usr/local/mongodb3.26/workspaces/mongo_04/mongodb_04.conf 其他两个常规节点配置相同,只是端口不同 分别启动三个机器上的mongodb实例,使用mongodb客户端登陆两个常规节点中的任何一个,执行如下命令: rs.initiate( {"_id" : "rs_setname", "members" : [ {"_id" : 1, "host" : "127.0.0.1:27005"}, {"_id" : 2, "host" : "127.0.0.1:27006"}, {"_id" : 3, "host" : "127.0.0.1:27004", "arbiterOnly" : true} ] }); 或 rs.initiate( {"_id" : "rs_setname", "members" : [ {"_id" : 1, "host" : "127.0.0.1:27005"}, {"_id" : 2, "host" : "127.0.0.1:27006"} ] }); rs.addArb('127.0.0.1:27004'); 启动后发现情况:三台机器 .1:27004 为Arbite .1:27005 为Primary .1:27006 为Secondary 在创建数据的时候只允许在主机中创建,其他都报错 为了验证能主动容灾,所以我主动kill掉.1:27005 kill 前: rs_setname:PRIMARY> rs.status(); { "set" : "rs_setname", "date" : ISODate("2016-06-13T09:10:47.616Z"), "myState" : 1, "term" : NumberLong(1), "heartbeatIntervalMillis" : NumberLong(2000), "members" : [ { "_id" : 1, "name" : "127.0.0.1:27005", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 1413, "optime" : { "ts" : Timestamp(1465808561, 2), "t" : NumberLong(1) }, "optimeDate" : ISODate("2016-06-13T09:02:41Z"), "electionTime" : Timestamp(1465808234, 1), "electionDate" : ISODate("2016-06-13T08:57:14Z"), "configVersion" : 1, "self" : true }, { "_id" : 2, "name" : "127.0.0.1:27006", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 823, "optime" : { "ts" : Timestamp(1465808561, 2), "t" : NumberLong(1) }, "optimeDate" : ISODate("2016-06-13T09:02:41Z"), "lastHeartbeat" : ISODate("2016-06-13T09:10:45.625Z"), "lastHeartbeatRecv" : ISODate("2016-06-13T09:10:47.191Z"), "pingMs" : NumberLong(0), "syncingTo" : "127.0.0.1:27005", "configVersion" : 1 }, { "_id" : 3, "name" : "127.0.0.1:27004", "health" : 1, "state" : 7, "stateStr" : "ARBITER", "uptime" : 823, "lastHeartbeat" : ISODate("2016-06-13T09:10:45.625Z"), "lastHeartbeatRecv" : ISODate("2016-06-13T09:10:46.407Z"), "pingMs" : NumberLong(0), "configVersion" : 1 } ], "ok" : 1 } kill 后: .1:27005 在stateStr 模块出现一个问题提醒. .1:27006 变化为了 PRIMARY rs_setname:PRIMARY> rs.status(); { "set" : "rs_setname", "date" : ISODate("2016-06-13T09:14:34.470Z"), "myState" : 1, "term" : NumberLong(2), "heartbeatIntervalMillis" : NumberLong(2000), "members" : [ { "_id" : 1, "name" : "127.0.0.1:27005", "health" : 0, "state" : 8, "stateStr" : "(not reachable/healthy)", "uptime" : 0, "optime" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "optimeDate" : ISODate("1970-01-01T00:00:00Z"), "lastHeartbeat" : ISODate("2016-06-13T09:14:33.996Z"), "lastHeartbeatRecv" : ISODate("2016-06-13T09:11:53.721Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "Connection refused", "configVersion" : -1 }, { "_id" : 2, "name" : "127.0.0.1:27006", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 1614, "optime" : { "ts" : Timestamp(1465809124, 1), "t" : NumberLong(2) }, "optimeDate" : ISODate("2016-06-13T09:12:04Z"), "electionTime" : Timestamp(1465809123, 1), "electionDate" : ISODate("2016-06-13T09:12:03Z"), "configVersion" : 1, "self" : true }, { "_id" : 3, "name" : "127.0.0.1:27004", "health" : 1, "state" : 7, "stateStr" : "ARBITER", "uptime" : 1048, "lastHeartbeat" : ISODate("2016-06-13T09:14:33.918Z"), "lastHeartbeatRecv" : ISODate("2016-06-13T09:14:31.542Z"), "pingMs" : NumberLong(0), "configVersion" : 1 } ], "ok" : 1 } 当恢复后,发现中间停顿大约3秒左右又重新回复正常,在损坏期间的数据自动同步好了。 到此,如果我kill掉 .1:27006 会怎样? 实验,如果仲裁者的服务挂掉后,主服务器挂了还是从服务器还能否顶上? 答案 是否定的. #-----相关命令: rs.conf()查看配置情况 rs.status()查看各个节点的状态 经过一小段时间后,他们会选一台作为PRIMARY,其他的常规节点为SECONDARY,同时在js shell中看到提示符从">"变为对应的 "PRIMARY>" 或 "SECONDARY>" 或 "ARBITER>"。可以在PRIMARY是通过rs.stepDown()来切换PRIMARY,执行此命令后会在剩余的常规节点选一个来充当PRIMARY。 四、分片集群结构 由多个副本集组成,配置较为复杂,维护结点较多,使用分片策略减少单点压力,高可用性,但当chunck迁移时,有可能带来性能下降 ![4.jpg][4] 名词解释 Mongod:mongo数据库实例,用于存储数据库表,配置等信息。根据具体的配置,可以作为存储数据的数据结点,存储配置信息的mongo config; Mongos:mongo集群服务的路由,读取mongo config信息,根据配置分发请求到指定的shard上,可理解为一种特殊的mongod; Config Servers : Config服务器存储着集群的metadata信息,包括每个服务器,每个shard的基本信息和chunk信息Config服务器主要存储的是chunk信息。每一个config服务器都复制了完整的chunk信息。 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上 [1]: http://blogimg.bravedu.com/2016/06/299733086.jpg [2]: http://blogimg.bravedu.com/2016/06/1904163450.jpg [3]: http://blogimg.bravedu.com/2016/06/116890373.jpg [4]: http://blogimg.bravedu.com/2016/06/1281899851.jpg 赞 3 分享 赏 您可以选择一种方式赞助本站 支付宝扫码赞助 BraveDu 署名: 网络副手~寻路人
看了这么多mongodb 集群 只有这里讲的最详细 看了楼主的文章 真真有用 细节很到位 比如" 使用mongodb客户端登陆两个常规节点中的任何一个,执行如下命令: rs.initiate" 其他文章没这种提示 几分钟之前 我还在各种报错 看了楼主的 一路顺溜 各种成功
d