MongoDB 开发之二

来源:互联网 发布:mac os 远程桌面 编辑:程序博客网 时间:2024/05/22 07:08

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)多了这些数据类型:

  1. BSON: Binary JavaScript Object Notation; JSON: JavaScript Object Notation.
  2. ObjectID: BSON文档的自增列。属于Object数据类型,因此使用new ObjectId()可以生成一个ObjectId.
  3. 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 interfacesnet:  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 runsprocessManagement:  fork: true  # fork and run in background  pidFilePath: /var/run/mongodb/mongodshard01.pid  # location of pidfile# network interfacesnet:  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 runsprocessManagement:  fork: true  # fork and run in background  pidFilePath: /var/run/mongodb/mongodconf.pid  # location of pidfile# network interfacesnet:  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 runsprocessManagement:  fork: true  # fork and run in background  pidFilePath: /var/run/mongodb/mongos.pid  # location of pidfile# network interfacesnet:  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().

这里写图片描述

原创粉丝点击