2.1权限管理:
2.1.1 当从头建立了一个MongoDB之后,并没有启动权限管理之前,我们尝试从本机,远程机器来访问数据库,看看读写权限是否有限制?并没有从远程来访问,这种方案肯定是不予采取的。不够安全
2.1.2 给admin数据库加一个user,然后重启MongoDB,并启动–Auth选项来启动访问认证;s**ecurity.authorization enabled设置选项**
2.1.3 给数据库增加一个只读用户,和一个可读可写的用户。在哪个db上建立的user,就会被默认放在那个db上,可以用db 命令来查看当前是哪个database
2.2 索引创建:
2.2.1在创建索引的时候,会锁住数据库,而不仅仅是collection。所以我们首先要建立一个非常巨大的collection,然后在这个collection上建立索引。同时,查询和更新该collection,此时应该被锁住。并尝试建立一个新的collection,锁库的话,在建立一个极大collection的时候,collection也应该是有延时的。实验证明,这是在建立索引的时候,整个database都被锁住了,此时创建新的collection都被阻塞了。
2.2.2有一种索引叫做background index,这种索引不像foreground index会引起锁, 而只是在没有collection更新的时候,才抽取数据,并且排序,创建索引。
db.expense.createIndex({“expense_date”:1,”comments”:1},{“background”:true})
2.2.3是不是有一种hint,可以在创建foreground index的时候,忽略当前的lock,就像sql server的nolock一样,可以读取正在创建index 的collection数据。
2.3备份与还原:
2.3.1备份当前的数据库
2.3.2还原备份库到新库
2.4读写分离
2.4.1将一个collection的数据,全部复制到另一个collection中,这个新复制的collection负责只读。基于被复制的collection数据量极大,采取的措施是分批导入。写一段脚本实现分批
这个任务一开始最困难的地方在于mongo shell与javascript的类型转换。比如ObjectID, Date类型,要从mongo转换到javascript,这套规则比较难以接受。
MongoDB文档(BSON) 比起javascript(JSON)多了这些数据类型:
- BSON: Binary JavaScript Object Notation; JSON: JavaScript Object Notation.
- ObjectID: BSON文档的自增列。属于Object数据类型,因此使用new ObjectId()可以生成一个ObjectId.
- Date:BSON中的Date会以ISODate来存储。也是一个object类型,因此用 new ISODate来定义和赋值。Javascript中有date数据类型, date() , date(“2017-12-01”), ISODate(“2017-01-01”) 都是有效的BSON数据类型。
var temp_source = db.expense.find().limit(2000);
while(temp_source.hasNext())
{
var temp_source_row = temp_source.next();
var temp_objectid = temp_source_row._id ;
if ( db.expense_replica.find({“_id”:temp_objectid}).count()>0 )
{
continue ;
}
else{
db.expense_replica.insert(temp_source_row);
}
}
上面这段代码,在limit(2000)的时候,可以运行的很顺利,但是一旦超过2000,或者将2000的限制去掉,那么整个脚本就会无故报错,说不定是什么原因,需要增加log的粒度,看看是怎么回事。基于robomongo环境,执行的脚本,初步推断是robomongo的错误。但是将这段脚本,放在mongo shell中执行,也有错误,等到812574个文档后,直接报停。原因是db.eval的错误。由此可见,这种类似cursor的方式,也会有很多的局限性。
2.4 Replica Set
2.4.1 replica set的硬件需求: 每台 MongoDB Server必须要装有mongodb 数据库。replica set的用途,就是用来复制数据的。举一个三台mongodb 组成的 replica set 来说,每一台都包含完整的数据。至于怎么实现每台都有完整的数据,保持着数据的一致性,原理留到以后分析。目前最重要的事情,就是实现 replica set.
2.4.2 replica set 中每台 MongoDB Server 都要以 server name 作为连接,而不是以 IP. 那么 CentOS 中,怎么去修改 server name 呢? centos: hostnamectl set-hostname centos00
假设我现在重命名了三台机器, centos00, centos01, centos02
centos00:
ens33: 192.168.64.130 broadcast:192.168.64.255
virbr0: 192.168.122.1 broadcast:192.168.122.255
centos01:
ens33:192.168.64.131 broadcast:192.168.64.255
virbro: 192.168.122.1 broadcast:192.168.122.255
centos02:
ens33:192.168.64.132 broadcast:192.168.64.255
virbr0:192.168.122.1 192.168.122.255
在/etc/hosts里面添加:
192.168.64.130 centos00
192.168.64.131 centos01
192.168.64.132 centos02
2.4.3 replica set 需要配置 Heart Beating 吗? 类似 sql server 的集群一样,“心跳”就是用来高速传输复制数据,或者快速响应集群服务器互相通信?
2.4.4 replica set 配置的时候,依靠什么来互相认可 server 本身是在一个 replica set 之中, 仅仅依靠 replica set Name ?
这一步需要配置:
1) 首先,随便登陆一台mongodb server, 然后宣布replica set开始布局。使用 rs 这个助手对象,调用他的方法来初始化一个replica set.
rs.initiate( { _id: “homecluster”, members: [ { _id: 0, host: “centos00:27017” } ] } )
2 ) 第一步里面初始化的replica set ,并不能主动抓取以replica set 名字相同的已经运行的 mongod 进程,需要手工添加这些进程(其实就是安装在不同server上的Mongodb)。rs.add()
rs.add(“centos02”)
rs.add(“centos01”)
这里呢,要注意,修改配置文件,让访问都走实际分配的IP,而不是127.0.0.1
# network interfaces
net:
port: 27017
bindIp: 192.168.64.131
否则呢,出现这样的错误:
{
"ok" : 0,
"errmsg" : "Quorum check failed because not enough voting nodes responded; required 2 but only the following 1 voting nodes responded: centos00:27017; the following nodes did not respond affirmatively: centos02:27017 failed with Connection refused",
"code" : 74,
"codeName" : "NodeNotFound"
}
3) 当 replica set 建立好之后,primary node 支持了所有的 读和写。 默认的这种模式,起到了数据灾备的作用,但是并没有起到读写分离。我们需要将读操作,都转移到另外两台 mongodb 上。这时候就要开启允许secondary node读的选项。
当看到这样的错误 :
"ok" : 0,
"errmsg" : "not master and slaveOk=false",
"code" : 13435,
"codeName" : "NotMasterNoSlaveOk"
表明 我们链接的是 secondary数据库 ,需要设置允许访问即可 (不介意数据的实时性)
rs.slaveOk()
2.4.5 有趣的问题是:三台 mongodb 组成的 replica set, 其中有一台服务器宕机了,这时候只有2台服务器了,假如没有arbiter server(仲裁服务器),那么剩下的2台服务器, 到底谁会充当primary 的角色呢?
3 Sharding
第一步,我们已经完成了replica set的搭建, homecluster. 这只是一个replica set, 所以充其量就只能用作一个shard node. 并且启动sharding role: shardsvr
# mongod.conf
# for documentation of all options, see:
# http://docs.mongodb.org/manual/reference/configuration-options/
# where to write logging data.
systemLog:
destination: file
logAppend: true
path: /MongoDB/Shard01/Log/Mongodb.log
# Where and how to store data.
storage:
dbPath: /MongoDB/Shard01/Data/
journal:
enabled: true
# engine:
# mmapv1:
# wiredTiger:
# how the process runs
processManagement:
fork: true # fork and run in background
pidFilePath: /var/run/mongodb/mongodshard01.pid # location of pidfile
# network interfaces
net:
port: 57017
bindIp: 192.168.64.130 # Listen to local interface only, comment to listen on all interfaces.
#security:
#operationProfiling:
#replication:
replication:
replSetName: homecluster
#sharding:
sharding:
clusterRole: shardsvr
## Enterprise-Only Options
#auditLog:
#snmp:
第二步,我们需要建立三台(暂时可以在每台replica set node)上创建configuration server. .这三台server和平常用的单实例mongodb server没有区别,所以按照正常的安装mongodb server来重复创建三台。
configuration server,在版本3.4之后,已经换成集群(replica set)了,所以用mirror方式搭建的replica set已经不再支持了。我们需要搭建三台mongod组成的replica set,并且启动configsvr选项。
# mongod.conf
# for documentation of all options, see:
# http://docs.mongodb.org/manual/reference/configuration-options/
# where to write logging data.
systemLog:
destination: file
logAppend: true
path: /MongoConf/log/Mongodb.log
# Where and how to store data.
storage:
dbPath: /MongoConf/db
journal:
enabled: true
# engine:
# mmapv1:
# wiredTiger:
# how the process runs
processManagement:
fork: true # fork and run in background
pidFilePath: /var/run/mongodb/mongodconf.pid # location of pidfile
# network interfaces
net:
port: 37017
bindIp: 192.168.64.130 # Listen to local interface only, comment to listen on all interfaces.
#security:
#operationProfiling:
#replication:
replication:
replSetName: csReplSet
#sharding:
sharding:
clusterRole: configsvr
## Enterprise-Only Options
#auditLog:
#snmp:
第三步,搭建mongos进程,Mongos是一个路由,用来分配读写,对一个sharding来说,可以分配n个mongos,只要他们使用同一套configuration server和sharding server.比较特殊的 是mongos没有自己的data file. mongos是一个mongod进程,监听某一个端口,所以连上mongos的方法和连Mongod的方法一样:
mongod –host mongoshost –port mongosport
# mongod.conf
# for documentation of all options, see:
# http://docs.mongodb.org/manual/reference/configuration-options/
# where to write logging data.
systemLog:
destination: file
logAppend: true
path: /MongoConf/log/Mongodbs.log
# Where and how to store data.
# engine:
# mmapv1:
# wiredTiger:
# how the process runs
processManagement:
fork: true # fork and run in background
pidFilePath: /var/run/mongodb/mongos.pid # location of pidfile
# network interfaces
net:
port: 47017
bindIp: 192.168.64.130 # Listen to local interface only, comment to listen on all interfaces.
#security:
#operationProfiling:
#replication:
#sharding:
## Enterprise-Only Options
#auditLog:
#snmp:
到这里只要登陆mongos,添加replica set 作为一个shard就可以了。sh.addShard().
欢迎关注个人微信公众号