最近弄了下mongodb的副本集,
首先说下没有认证情况的副本集,相对比较简单,因为环境有限,我在同一台服务器上做了模拟。
--rest参数是打开web监控页面,比如我们这里监听37017端口,则打开http://192.168.75.132:38017/(mongod端口加上1000)就可以看到这个mongodb数据库进程的信息,如果是副本集就能查看整个副本集的相关信息。
启动三个mongo节点,这个是最简单的副本集的结构,两个节点是不能起到副本集的作用的。 ./bin/mongod --fork --dbpath data/rs0-0/ --logpath log/rs0-0/rs0-0.log --rest --replSet rs0 --port 37017 ./bin/mongod --fork --dbpath data/rs0-1/ --logpath log/rs0-1/rs0-1.log --rest --replSet rs0 --port 37018 ./bin/mongod --fork --dbpath data/rs0-2/ --logpath log/rs0-2/rs0-2.log --rest --replSet rs0 --port 37019 进入作为主节点的mongo ./bin/mongo -port 37017 use admin #初始化一个Replica set,创建一个副本集配置对象 rsconf={ "_id" : "rs0", "members" : [ { "_id" : 0, "host" : "192.168.75.132:37017" } ] } rs.initiate(rsconf) 添加另外两个从节点 rs.add("192.168.75.132:37018") rs.add("192.168.75.132:37019") rs.conf()可以查看集群的配置情况,还可以使用此来修改节点的属性,还可以设置 priority,hidden, slaveDelay, cfg=rs.conf()
{
"_id" : <num>,
"host" : <hostname:port>,
"priority" : 0, //设置为0后则不会通过投票变为主节点
"slaveDelay" : <seconds>, // 延迟同步时间
"hidden" : true // 隐藏节点,则客户端不能连接,但是可以投票
}
cfg.members[2].priority = 2 rs.reconfig(cfg, {'force':true}) 执行rs.reconfig()命令会强制整个副本集集群进行一次election,这样priority较高的37019节点便成了primary节点 整个election过程需要一点时间,在这之间整个集群的所有节点都是secondary。election的策略不仅仅就是根据priority值来,会综合很多其他的因素。经过测试,就算是priority值高,但如果是出现问题,刚刚启动,一般不会成为primary节点,而是变为secondary节点。 添加仲裁者: mkdir –p data/rs0-arb;mkdir –p log/rs0-arb ./bin/mongod --fork --dbpath data/rs0-arb/ --logpath log/rs0-arb/rs0-arb.log --rest --replSet rs0 --port 40000 然后进入primary节点执行下面命令添加arbiter: rs.addArb("192.168.75.132:40000") 移除成员: 移除一个成员使用rs.remove()命令: rs.remove("192.168.75.132:37019")
下面说下带认证的副本集的配置,说明下,下面的是3.*版本的环境下的,2.*版本的会有不一样的地方,不过建议使用3.*版本的。
副本集搭建有认证情况 在此我们需要配置三个mong单节点,然后将其结合组成副本集, 安装路径/usr/local/mongd 三个mongdb分别占用端口27017 27018 27019 在/usr/local/mongd下面创建四个数据目录和一个配置目录以及一个日志目录 mkdir /usr/local/mongd/data{1..4} mkdir /usr/local/mongd/log mkdir /usr/local/mongd/etc 三个mongodb的配置文件分别如下所示:配置文件的路径: /usr/local/mongd/etc/ 添加三个配置文件,内容如下: mongodb_primary.conf port=27017 dbpath=/usr/local/mongod/data1/ logpath=/usr/local/mongod/log/mongodb.log pidfilepath=/usr/local/mongod//mongod.pid fork=true logappend=true shardsvr=true directoryperdb=true #auth=true #replSet=rs0 #oplogSize=100 #keyFile=/usr/local/mongod/etc/mongo.pass ###这个文件后边需要手动生成,路径和文件名都是自定义的 mongodb_slave1.conf port=27018 dbpath=/usr/local/mongod/data2/ logpath=/usr/local/mongod/log/mongodb.log pidfilepath=/usr/local/mongod//mongod.pid fork=true logappend=true shardsvr=true directoryperdb=true #auth=true replSet=rs0 oplogSize=100 keyFile=/usr/local/mongod/etc/mongo.pass ###三个配置文件中这个文件需要一致 mongodb_slave2.conf port=27019 dbpath=/usr/local/mongod/data3/ logpath=/usr/local/mongod/log/mongodb3.log pidfilepath=/usr/local/mongod//mongod3.pid fork=true logappend=true shardsvr=true directoryperdb=true #auth=true replSet=rs0 oplogSize=100 keyFile=/usr/local/mongod/etc/mongo.pass ###三个配置文件中这个文件需要一致 ###还可以添加一个仲裁的配置文件 mongodb_arb.conf port=27019 dbpath=/usr/local/mongod/data_arb/ logpath=/usr/local/mongod/log/mongodb_arb.log pidfilepath=/usr/local/mongod//mongod_arb.pid fork=true logappend=true shardsvr=true directoryperdb=true #auth=true replSet=rs0 oplogSize=100 keyFile=/usr/local/mongod/etc/mongo.pass ###三个配置文件中这个文件需要一致 首先启动一个节点,即先启动第一个mongodb,27017端口的那个,因为在此我想用其做primary节点 mongod -f /usr/local/mongod/etc/mongodb_primary.conf 启动后,连接节点,在里面添加用户,在此 我添加了一个root角色的用户(权限最高的用户了), 添加用的方法如下: use admin db.createUser({user:"admin",pwd:"123456",roles:[{role:"root",db:"admin"}]}) 用户添加完成后,关闭mongodb,然后修改mongodb的配置文件,只修改第一个的配置文件就行,因为在此,我们就启动了第一个mongodb数据库, 修改的配置如下所示: port=27017 dbpath=/usr/local/mongod/data1/ logpath=/usr/local/mongod/log/mongodb.log pidfilepath=/usr/local/mongod//mongod.pid fork=true logappend=true shardsvr=true directoryperdb=true auth=true ###去掉注释 replSet=rs0 ###去掉注释 oplogSize=100 ###去掉注释 keyFile=/usr/local/mongod/etc/mongo.pass ###去掉注释 然后生成一个keyFile,副本集之间通过此文件来进行验证, openssl rand -base64 521 > /usr/local/mongod/etc/mongo.pass ###这个名字随意定义,但是配置文件中也需要制定这个文件的,在此我的是同一台机器,所以,路径相同,如果是不同机器之间的做副本集,则需要将此文件复制到不同的机器上去 创建完成后,还需要修改此文件的权限为600,只有拥有者有权限,其余的组和其他用户没有任何的权限 chmod 600 /usr/local/mongod/etc/mongo.pass 修改完成后,启动mongdb数据库即可 这次需要三个数据都启动, 然后登陆数据库进行操作就行,但是,切记需要先验证账号和密码才可以 use admin; db.auth('admin', '123456'); 接下来就可以配置副本集了 #初始化一个Replica set,创建一个副本集配置对象 rsconf={ "_id" : "rs0", "members" : [ { "_id" : 0, "host" : "192.168.75.132:37017" } ] } rs.initiate(rsconf) #添加两个从的副本集节点 rs.add("192.168.75.132:37018"); rs.add("192.168.75.132:37019"); rs.addArb("192.168.75.132:40000"); 然后就是添加用户和建库 这些都要在primary节点执行, use robo; db.createUser({user:'robo',pwd:'robo',roles:[{role:'readWrite',db:'robo'}]});//经测试,使用Robomongo连接,选择两种认证(MONGODB-CR,SCRAM-HAS-1)都可以联通
php的代码调用如下 :
$server = "192.168.75.132:27017,192.168.75.132:27018,192.168.75.132:27019";// 可以只有一部分,如两台的信息 $server = "192.168.75.132:27018,192.168.75.132:27019"; $options = [ 'readPreference' => MongoClient::RP_SECONDARY_PREFERRED, 'replicaSet' => 'rs',//要连接的集群名称 ]; $user = 'wayne'; $passwd = 'wayne'; $dbname = 'wayne_com'; $collectName = 'test_list'; $dsn = "mongodb://$user:$passwd@{$server}/{$dbname}"; $mongo = new MongoClient($dsn, $options); $mongo->selectDB($dbname); $coll = $mongo->selectCollection($dbname, $collectName); $where = ['name'=>'tong']; $cursor = $coll->find([])->limit(5); if ($cursor) { foreach ($cursor as $doc) { var_dump($doc); } } else { echo 'empty data'; }
今天测试了下node.js 调用副本集的脚本,测试通过。记录下来。
var MongoClient = require('mongodb').MongoClient; // mongodb://user:password@server:port/dbname?replicaSet=replicaSetName 连接的完整格式,副本集不需要写出所有的服务器的列表,只写一部分也是可以使用的,但如果写入部分的服务器出问题了,是否会出现失败,待以后确认 var url = 'mongodb://wayne:wayne@192.168.75.132:27018,192.168.75.132:27019/wayne_com?replicaSet=rs'; MongoClient.connect(url, function (err, db) { console.log('error', 'db connect is ok'); var collection = db.collection('test_list'); console.log('error', 'collection is ok'); collection.find({}).toArray(function (err, result) { console.log(err, result); }); });