MongoDB数据库

重要通知

MongoDB基本概况

MongoDB, 基于C++编写实现的分布式文件存储非关系型数据库,旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。

简介与核心思想

MongoDB, 基于C++编写实现的分布式文件存储非关系型数据库,旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。

存储引擎

WiredTiger:从mongodb3.2开始默认, MMAPv1: In-Memory:

备注

从mongodb3.2开始默认的存储引擎是WiredTiger;
3.3版本之前的默认存储引擎是MMAPv1;
mongodb4.x版本不再支持MMAPv1存储引擎。

WiredTiger核心优势

最大化可用缓存: WiredTiger最大限度地利用可用内存作为缓存来减少I / O瓶颈。使用了两个缓存:WiredTiger缓存和文件系统缓存。WiredTiger缓存存储未压缩的数据并提供类似内存的性能。操作系统的文件系统缓存存储压缩数据。当在WiredTiger缓存中找不到数据时,WiredTiger将在文件系统缓存中查找数据。
高吞吐量: WiredTiger使用“写入时复制” - 当文档更新时,WiredTiger将制作文档的新副本并确定最新版本以返回给读者。此方法允许多个客户端同时修改集合中的不同文档,从而实现更高的并发性和吞吐量。当应用程序使用具有多个内核的主机(越多越好)并且多个线程正在写入不同的文档时,实现最佳写入性能。

可扩展的高性能数据存储解决方案

在高负载的情况下,添加更多的节点,可以保证服务器性能;

资源

配置下载:https://www.mongodb.com/download-center/community
语法连接示例:https://www.mongodb.com/what-is-mongodb
文档:https://docs.mongodb.com/manual/

基本语法

查看版本:./bin/mongo --version

远程连接

步骤一:配置用户角色 步骤二: mongodb:/106.13.47.239:27017/admin -u "root" -p "123456"
mongodb://root:123456@106.13.47.239:27017/
mongodb://106.13.47.239:27017

分布式架构

https://www.cnblogs.com/littleatp/p/8563273.html

代码示例

async connect() { mogo.connect('mongodb://localhost/test', {useNewUrlParser: true});

let db = mogo.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
  console.log("we're connected!");
});

}

安装配置

注意配置,注意配置,注意配置

数据存储路径配置、日志路径配置

这是最容易报错的地方

下载, 注意不同Linux环境安装解压会报错, 可以在不同服务器配置不同版本

curl -O https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.0.6.tgz curl -O https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel62-4.2.2.tgz

tar -zxvf mongodb-linux-x86_64-3.0.6.tgz mv mongodb-linux-x86_64-3.0.6 /usr/local/src cd /usr/local/src/mongodb-linux-x86_64-3.0.6

添加可执行文件到PATH 路径中

export PATH=/usr/local/src/mongodb-linux-x86_64-3.0.6/bin:$PATH

/data/db 是 MongoDB 默认的启动的数据库路径, 手动修改数据库路径, 可以配置文件

./bin/mongod --dbpath /home/mongodb/db

启用配置文件, 启用后,无需再次启动mongdb服务

./bin/mongod -f mongo.conf ./bin/mongod mongo.conf #显示完整信息

如果出现如下错误

about to fork child process, waiting until server is ready for connections. forked process: 13568 ERROR: child process failed, exited with error number 1 or 48

问题

FATAL ERROR: Out of memory trying to allocate internal tcmalloc data (bytes, object-size) 131072 48

1: 文件配置错误; 2: 锁

问题:number 1

1.环境CentOS7.0

2.Linux安装配置MongoDB4.0后启动报错:ERROR: child process failed, exited with error number 1

3.解决方法:MongoDB4.0很3.x的版本日志文件不同,3.x为/logs/mongodb.log文件,而4.0为logs文件。

所以在配置logs的时候去创建了/logs/mongodb.log就会报错,将其删除,在mongo根目录下touch logs解决了问题,再次启动启动成功。

100, 则是/home/mongodb/db/mongod.lock

1, 则是配置错误

解决一,直接清除日志目录

rm -rf /home/mongodb/logs/* rm -rf /home/mongodb/db/mongod.lock

启动交互式环境

./bin/mongo

查看版本

./bin/mongo -version

启动交互式环境时, 或许会报错, W NETWORK Failed to connect to 127.0.0.1:27017, reason: errno:111 Connection refused

解决方法, 自动修复指令

./bin/mongod --repair

关闭mongodb方式一

use admin;
db.adminCommand({shutdown : 1, force : true});
db.shutdownServer({force : true});

关闭mongodb方式二

ps -ef | grep mongodb kill PID #杀进程

验证

show dbs;

报错, 查看所有数据库,发现报错,因为没有用户验证

2020-01-02T21:11:35.661+0800 E QUERY Error: listDatabases failed:{ "ok" : 0, "errmsg" : "not authorized on admin to execute command { listDatabases: 1.0 }", "code" : 13 }

当前登陆用户不具备相应权限

通过创建一个用户,赋予用户root权限

见User,conf配置

./User.conf

查看数据库信息

db.stats();

#开机自启动

#卸载

停止服务

删除服务管理器中的mongodb

./bin/mongod --remove 删除mongodb目录

程序代码

init.js

const mongodb = require('mongodb');
const uuid = require("uuid");

const Grammar = require('./example/init.js');
const GetData = require('./example/get-data.js');

module.exports = async function() {
  console.log("|-----" + "MongoDB" + "-----FILE_URL: " + __filename);

  //业务模型 
  await init(); 
  //Grammar();
  //GetData(); 
  //Test();   
}

async function init() {
  const mongo = mongodb.MongoClient;
  //const url = "mongodb://root:123456@49.235.198.78:27017/";  //〔腾讯云〕1核2G-50G | 49.235.198.78
  //const url = "mongodb://root:123456@110.43.33.21:27017/";   //〔金山云〕1核2G-20G | 110.43.33.21
  const url = "mongodb://root:123456@106.13.47.239:27017/";  //〔百度云〕106.13.47.239 | 2核4G-40G

  const pomise = new Promise((resolve, reject)=> {
    mongo.connect(url, {useNewUrlParser: true, useUnifiedTopology: true}, (err, res)=> {
      if (err) {
        reject(err);
      }; 
      resolve(res); 
    });
  });

  await pomise.then((res)=> {
    global.MongoClient = res;
  }).catch((err)=> {
    console.log(err); 
  }); 
}

async function Test() {
  const dbase = MongoClient.db('test'); 
  const collect = dbase.collection("example");
  
  let doc = {title: '军事战争', article_id: uuid.v1(), subtitle: '伊朗与美国之间的冲突越演越烈'};

  collect.insertOne(doc, function(err, res) {
    if (err) throw err;
    console.log(res);
  });
}

example.js

const uuid = require("uuid");


module.exports = function() {
  const dbase = MongoClient.db('program');
  const collect = dbase.collection("users");


  //查询数据
  function queryData() {
    let queryDoc = {};

    collect.find(queryDoc).toArray(function(err, res) { 
      if (err) throw err;
      console.log(res);
    });
  }
  //queryData();


  //查询分页  | 读取指定数量的数据
  function queryLimitData() {
    collect.find().limit(2).toArray((err, res)=> {
      if (err) throw err;
      console.log(res);
    });
  }
  //queryLimitData();


  //查询分页  | 跳过指定数量的数据
  function querySkitData() {
    collect.find().skip(2).limit(2).toArray((err, res)=> {
      if (err) throw err;
      console.log(res);
    });
  }
  //querySkitData();


  //排序  type=1 升序  type=-1 降序
  function sortData() {
    let sort  = {type: 1};
    
    collect.find().sort(sort).toArray((err, res)=> {
      if (err) throw err;
      console.log(res);
    });
  }
  //sortData();


  //插入数据  | 不限制条数
  function insertData() {
    let password = uuid.v4().replace(/\-/g, "");
    let doc = { account: "李大钊", password: password };

    collect.insert(doc, function(err, res) {
      if (err) throw err;
      console.log(res);
    });
  }
  //insertData();


  //插入数据  | 单条
  function insertOneData() {
    let password = uuid.v4().replace(/\-/g, "");
    let doc = { account: 1111, password: password };

    collect.insertOne(doc, function(err, res) {
      if (err) throw err;
      console.log(res);
    });
  }
  //insertOneData();


  //插入数据  | 多条
  function insertManyData() {
    let ManyDoc = [
      {account: "菜鸟教程", password: "www.runoob"},
      {account: "菜鸟教程", password: "www.runoob"},
      {account: "菜鸟教程", password: "www.runoob"}
    ];

    collect.insertMany(ManyDoc, (err, res)=> {
      if (err) throw err;
      console.log(res);
    });
  }
  //insertManyData();


  //更新数据  | 限制满足条件的第一条数据
  function updateData() {
    let whereDoc = {account: '菜鸟教程'};
    let updateDoc = {$set: {password: 'no123456'}};

    collect.update(whereDoc, updateDoc, (err, res)=> {
      if (err) throw err;
      console.log(res);
    });
  }
  //updateData();


  //更新数据  | 限制满足条件的第一条数据
  function updateOneData() {
    let whereDoc = {account: '菜鸟教程'};
    let updateDoc = {$set: {password: 'no123456'}};

    collect.updateOne(whereDoc, updateDoc, (err, res)=> {
      if (err) throw err;
      console.log(res);
    });
  }
  //updateOneData();


  //更新数据  | 多条
  function updateManyData() {
    let whereDoc = {account: '菜鸟教程'};
    let updateDoc = {$set: {password: 'no123456'}};

    collect.updateMany(whereDoc, updateDoc, (err, res)=> {
      if (err) throw err;
      console.log(res);
    });
  }
  //updateManyData();


  //删除数据  | 单条
  function deleteOneData() {
    let whereDoc = {account: '菜鸟教程'};
    collect.deleteOne(whereDoc, (err, res)=> {
      if (err) throw err;
      console.log(res);
    });
  }
  //deleteOneData();


  //删除数据  | 多条
  function deleteManyData() {
    let whereDoc = {account: '菜鸟教程'};
    collect.deleteMany(whereDoc, (err, res)=> {
      if (err) throw err;
      console.log(res);
    });
  }
  //deleteManyData();


}

query.js

module.exports = function() {
  const dbase = MongoClient.db('program');
  const collect = dbase.collection("users");


  //查询数据  | 检索集合中匹配的数据类型  $type
  function queryData() {
    let queryDoc = {account: {$type: 16}};

    collect.find(queryDoc).toArray(function(err, res) { 
      if (err) throw err;
      console.log(res);
    });
  }
  //queryData();


}

update.js

module.exports = async function() {
  console.log("|-----" + "更新" + "-----FILE_URL: " + __filename);

  //业务模型
  await init();

}

async function init() {
  global.dbase = MongoClient.db('test');
  global.collect = dbase.collection("trees");

  //Test();
  //Example();

}

//(node:17080) DeprecationWarning: collection.update is deprecated. Use updateOne, updateMany, or bulkWrite instead.

//禁止重复插入数据
async function Test() {
  let query = {name: '梧桐刚刚的工号的22'};
  let update = {$set: {name: '梧桐刚刚的工号的11', age: 11}};

  collect.updateOne(query, update, {upsert: true, multi: true}, function(err, res) {
    if (err) throw err;
    //console.log(res);   
  });

}

async function Example() {
  let query = {name: '梧桐刚刚的工号的'};
  let update = {$set: {name: '梧桐刚刚的工号的'}};

  collect.updateOne(query, update, {upsert: true, multi: true}, function(err, res) {
    if (err) throw err;
    //console.log(res);   
  });

}





### 
> 

``` ts
























## 基础语法
> 

### 操作符
> 
# 条件操作符
> $gt: (>) 大于 
> $lt: (<) 小于 
> $gte: (>=) 大于等于 
> $lte: (<= ) 小于等于 
# 代码示例
> db.col.find({likes : {$gt : 100}})


# Limit
> 读取指定数量的数据记录
> db.COLLECTION_NAME.find().limit(NUMBER)


# Skip
> 跳过指定数量的数据
> db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)
# 只会显示第二条文档数据
> db.col.find({},{"title":1,_id:0}).limit(1).skip(1)


# $type
> 基于BSON类型来检索集合中匹配的数据类型,并返回结果
-----------------------------------------------------------------------
  类型	                   数字	备注
-----------------------------------------------------------------------
  Double	                1	 
  String	                2	 
  Object	                3	 
  Array	                  4	 
  Binary data	            5	 
  Undefined	              6	    已废弃。
  Object id	              7	 
  Boolean	                8	 
  Date	                  9	 
  Null	                  10	 
  Regular Expression	    11	 
  JavaScript	            13	 
  Symbol	                14	 
  JavaScript (with scope)	15	 
  32-bit integer	        16	 
  Timestamp	              17	 
  64-bit integer	        18	 
  Min key	                255	   Query with -1.
  Max key 	              127	 
-----------------------------------------------------------------------
# 代码示例
> db.col.find({"title" : {$type : 2}})
> db.col.find({"title" : {$type : 'string'}})




### 插入文档
> 

# 插入文档: insert
> db.COLLECTION_NAME.insert(document)
# 插入文档: save, 如果不指定 _id 字段 save() 方法类似于 insert() 方法。如果指定 _id 字段,则会更新该 _id 的数据。
> db.COLLECTION_NAME.save(document)

# 查看文档
> db.COLLECTION_NAME.find()

# 3.2版本后其他方法

# 向指定集合中插入一条文档数据
> db.COLLECTION_NAME.insertOne({})

# 向指定集合中插入多条文档数据
> db.COLLECTION_NAME.insertMany({}, {}, ..., {})

# 一次性插入多条数据


# 更新文档
> db.COLLECTION_NAME.update()


# 删除文档
> db.COLLECTION_NAME.remove()




### 查询文档
> 

# 查询
> db.COLLECTION_NAME.find(query, projection)

# 需要以易读的方式来读取数据,可以使用 pretty() 方法
> db.COLLECTION_NAME.find().pretty()

# 总条数
> db.COLLECTION_NAME.find().count();



### 更新文档
> 

# 更新已存在的文档
> db.COLLECTION_NAME.update(
>  <query>,
>  <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>
   }
> )

# 参数
> query : update的查询条件,类似sql update查询内where后面的。
> update : update的对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询内set后面的
> upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
> multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
> writeConcern :可选,抛出异常的级别。


# 代码示例
> 实现了不重复插入数据
db.COLLECTION_NAME.update(
  {'title':'MongoDB 教程'},
  {$set:{'title':'MongoDB'}},
  {upsert: true, multi: true}
)

# 设置某个字段不能重复,即整个文档不能插入
mgdbcol.updateMany({name: doc.name}, {$set: doc}, {upsert: true, multi: true}, function(err, res) {
  if (err) throw err;
  console.log(res.result);
});


# 更新一条
db.COLLECTION_NAME.updateOne

# 更新多条
db.COLLECTION_NAME.updateMany




### 管道操作符
> 

$project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
$match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。
$limit:用来限制MongoDB聚合管道返回的文档数。
$skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
$unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
$group:将集合中的文档分组,可用于统计结果。
$sort:将输入文档排序后输出。
$geoNear:输出接近某一地理位置的有序文档。


### 集合
> 

# 创建集合
> db.createCollection(name, options)
----------------------------------------------------------------------------------------------------------------
  字段	          类型	  描述
----------------------------------------------------------------------------------------------------------------
  capped	        布尔	(可选)如果为 true,则创建固定集合。固定集合是指有着固定大小的集合,当达到最大值时,它会自动覆盖最早的文档。当该值为 true 时,必须指定 size 参数。
  autoIndexId	     布尔	(可选)如为 true,自动在 _id 字段创建索引。默认为 false。
  size	          数值	(可选)为固定集合指定一个最大值,以千字节计(KB)。如果 capped 为 true,也需要指定该字段。
  max	            数值	(可选)指定固定集合中包含文档的最大数量。
----------------------------------------------------------------------------------------------------------------
> db.createCollection('articles')



# 删除集合
> use DATABASE_NAME;
> show collections; 
> db.COLLECTION_NAME.drop();


### 聚合
> 


### 排序
> 

# 使用 sort() 方法对数据进行排序,sort() 方法可以通过参数指定排序的字段,并使用 1-1 来指定排序的方式,其中 1 为升序排列,而 -1 是用于降序排列。
> db.COLLECTION_NAME.find().sort({KEY:1})


### 数据库
> 

# 切换至指定数据库, 如果数据库不存在,则创建数据库,否则切换到指定数据库
> use DATABASE_NAME;

# 查看所有数据库, 过滤空数据库
> show dbs;

# 删除数据库, 删除当前数据库,默认为test
> use DATABASE_NAME;
> db.dropDatabase();


### 索引
> 
















## mongoose
> 

``` ts
  //数据模型
  model: mogo.model("dialogMd", new Schema({
    name: String,
    date: {   
      type: String, 
      default: plug.formatDate()
    }  
  }, {collection: "dataBaseName"}))
module.exports = {
  name: "Mongoose",


  async run() {
    //console.log(this.name);

    let mogo = require('mongoose');
    let Schema = mogo.Schema;
    let url = "mongodb://localhost:27017/test";
    let options = {useNewUrlParser: true};

    mogo.connect(url, options);

    let collect = mogo.connection;

    //错误
    collect.on("error", (err)=> {
      console.log(err);
    });

    //初次连接
    collect.once("open", (res)=> {
      //console.log("初次连接");
    });

    //业务模型
    this.test(mogo, Schema);
  },

  async test(mogo, Schema) {
    let scm = new Schema({
      name: String
    },{
      collection: "course"
    });

    let model = mogo.model("model", scm); 
 
    let collect = model.collection;

    //this.query(model, collect);
    //this.insert(model, collect);

  },

  async query(model, collect) {
    let args = { 
      name: "测试数据"
    };
    
    model.find({}, (err, rst)=> {
      console.log(rst);
    }); 
  },

  async insert(model, collect) {
    let doc = new model({
      name: `测试数据 ${plug.randomID()}` 
    });

    collect.insert(doc, (err, data)=> {
      if (err) {console.log(err); return;}
      console.log(data);
    });
  },
 
  //生成token
  async token(mogo, Schema) {
    let name = plugin.randomID();
  }


}

属性与方法

MongoError MongoNetworkError MongoTimeoutError MongoServerSelectionError MongoParseError MongoWriteConcernError MongoBulkWriteError BulkWriteError Admin MongoClient Db Collection Server ReplSet Mongos ReadPreference GridStore Chunk Logger AggregationCursor CommandCursor Cursor GridFSBucket CoreServer CoreConnection Binary Code Map DBRef Double Int32 Long MinKey MaxKey ObjectID ObjectId Symbol Timestamp BSONRegExp Decimal128 connect instrument

核心技术

磁盘空间不足与自动扩容

Linux扩容

大规模数据处理方案

当某台服务器的mongodb数据越来越大,导致存储空间不足时

分片

使用分片动机

复制所有的写入操作到主节点;
延迟的敏感数据会在主节点查询;
单个副本集限制在12个节点;
当请求量巨大时会出现内存不足;
本地磁盘不足;
垂直扩展价格昂贵。

限制数据重复

let doc = {title: '军事战争', subtitle: '伊朗与美国之间的冲突越演越烈'};
mgdbcol.update(doc, {$set: doc}, {upsert: true, multi: true}, function(err, res) {
  if (err) throw err;
  console.log(res.result);
});

修改器

$mod $set

mongo.conf

# get /usr/local/src/mongodb-linux-x86_64-3.0.6/mongo.conf D:/devpt/project/server/admin/database/mongodb/configure
# put D:/devpt/project/server/admin/database/mongodb/configure/mongo.conf /usr/local/src/mongodb-linux-x86_64-3.0.6


dbpath=/home/mongodb/db
#3.0   如果4.0,则需要注意配置路径与文件名
logpath=/home/mongodb/logs/mongodb.log

# 启用日志文件,默认启用
journal=true 
# 是否追加方式写入日志,默认True 
logappend=true
#是否以守护进程方式运行,默认false 
fork = true  

#bind_ip=127.0.0.1
#匹配任何IP, 默认监听所有IP
#bind_ip=0.0.0.0   

#端口号 
port = 27017
#连接数据库需要验证  
auth=true  

#副本集
#replSet=mdcluster
#位置:/usr/local/src/mongodb-linux-x86_64-3.0.6/mongo.conf

#启动配置
> ./bin/mongod -f mongo.conf




#用户自己动手配置, 非系统自动生成

dbpath=/home/software/mongodb/data/db
logpath=/home/software/mongodb/data/log/logs.log

journal=true  # 启用日志文件,默认启用
logappend=true  # 是否追加方式写入日志,默认True
fork = true  #是否以守护进程方式运行,默认false

#bind_ip=127.0.0.1
bind_ip=0.0.0.0  #匹配任何IP
port = 27017  #端口号
auth=true  #连接数据库需要验证



# 普通配置文件
# mongodb.conf
dbpath=/var/lib/mongodb  
logpath=/var/log/mongodb/mongodb.log 
pidfilepath=/var/log/mongodb/master.pid  
directoryperdb=true  
logappend=true  
bind_ip=127.0.0.1 
port=27017  
fork=true  

# 集群配置文件
dbpath=/var/lib/mongodb  
logpath=/var/log/mongodb/mongodb.log 
pidfilepath=/var/log/mongodb/master.pid  
directoryperdb=true  
logappend=true  
replSet=name  
bind_ip=127.0.0.1 
port=27017  
fork=true  
noprealloc=true 




# mongodb.conf

# 数据库文件位置
dbpath=/var/lib/mongodb

#日志文件的路径
logpath=/var/log/mongodb/mongodb.log

# 是否追加方式写入日志,默认True
logappend=true

# 设置绑定ip
bind_ip = 127.0.0.1
# 设置端口
port = 27017

# 是否以守护进程方式运行,默认false
fork = true

# 启用日志文件,默认启用
journal=true

# 启用定期记录CPU利用率和 I/O 等待,默认false
#cpu = true

# 是否以安全认证方式运行,默认是不认证的非安全方式
#noauth = true
#auth = true

# 详细记录输出,默认false
#verbose = true

#用于开发驱动程序时验证客户端请求
#objcheck = true

# # 启用数据库配额管理,默认false
#quota = true

# 设置oplog日志记录等级,默认0
#   0=off (default)
#   1=W
#   2=R
#   3=both
#   7=W+some reads
#oplog = 0

# 是否打开动态调试项,默认false
#nocursors = true

# 忽略查询提示,默认false
#nohints = true

# 禁用http界面,默认为localhost:28017
#nohttpinterface = true

# 关闭服务器端脚本,这将极大的限制功能,默认false
#noscripting = true

# 关闭扫描表,任何查询将会是扫描失败
#notablescan = true

# 关闭数据文件预分配
#noprealloc = true

# 为新数据库指定.ns文件的大小,单位:MB
# nssize = <size>

# 用于Mongo监控服务器的Accout token。
#mms-token = <token>

# Mongo监控服务器的服务器名称。
#mms-name = <server-name>

# Mongo监控服务器的Ping间隔时间,即心跳
#mms-interval = <seconds>

# Replication Options

# 设置主从复制参数
#slave = true # 设置从节点
#source = master.example.com # 指定从节点的主节点
# Slave only: 指定要复制的单个数据库
#only = master.example.com
# or
#master = true # 设置主节点
#source = slave.example.com 

# 设置副本集的名字,所有的实例指定相同的名字属于一个副本集
replSet = name

#pairwith = <server:port>

# 仲裁服务器地址
#arbiter = <server:port>

# 默认为false,用于从实例设置。是否自动重新同步
#autoresync = true

# 指定的复制操作日志(OPLOG)的最大大小
#oplogSize = <MB>

# 限制复制操作的内存使用
#opIdMem = <bytes>

# 设置ssl认证
# Enable SSL on normal ports
#sslOnNormalPorts = true

# SSL Key file and password
#sslPEMKeyFile = /etc/ssl/mongodb.pem
#sslPEMKeyPassword = pass

权限配置

用户 User

添加root角色

步骤一

use admin;

步骤二

db.createUser({ user:"root", pwd:"123456", roles:[{role:"root",db:"admin"}] }); Successfully added user: { "user" : "root", "roles" : [ { "role" : "root", "db" : "admin" } ] }

验证

use admin; db.auth("root","123456"); 1

验证

show dbs; admin 0.078GB local 0.078GB

有可能出现异常信息

2019-02-25T20:21:35.106-0500 EQUERY [JS] Error: couldn't add user: "role" is not a valid argument to createUser : _getErrorWithCode@src/mongo/shell/db.js:25:!3 @(shell):1:1

这大概是语法与版本差异所致,注意核对不同MongoDB版本对应的语法

继续之前操作数据库, 则OK

添加用户时各个角色对应权限

数据库用户角色:read、readWrite; 数据库管理角色:dbAdmin、dbOwner、userAdmin; 集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager; 备份恢复角色:backup、restore 所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase 超级用户角色:root

集群与分布式系统架构

分布式系统

集群

副本集架构

基本操作

判断当前运行的Mongo服务是否为主节点:db.isMaster()
查看副本集的配置:rs.conf()
查看副本集状态:rs.status()

自动增量

资源

技术文档:https://docs.mongodb.com/manual/reference/method/js-replication/

简介与核心思想

副本集:将数据同步在多个服务器的过程;
在多个服务器上存储数据副本,提高了数据的可用性, 并可以保证数据的安全性;
复制还允许您从硬件故障和服务中断中恢复数据。

MongoDB的副本集的优势

主节点提供所有增删查改服务,备节点不提供任何服务 主从在主机宕机后所有服务将停止,而副本集在主机宕机后,副本会接管主节点成为主节点,不会出现宕机

备注

配置副本集, 如果配置得不好, 后期会给mongodb造成很多潜在的隐患, 例如启动服务等;

实现机制

副本集(Replica Set)是一组MongoDB实例组成的集群,由一个主(Primary)服务器和多个备份(Secondary)服务器构成;
通过Replication,将数据的更新由Primary推送到其他实例上,在一定的延迟之后,每个MongoDB实例维护相同的数据集副本;
通过维护冗余的数据库副本,能够实现数据的异地备份,读写分离和自动故障转移。

架构

MASTER: SECONDARY: 不允许读写, 如果在SECONDARY数据库中操作,会报错,例如 show dbs; 2020-01-15T18:09:29.968+0800 E QUERY Error: listDatabases failed:{ "note" : "from execCommand", "ok" : 0, "errmsg" : "not master" }

解决方案

rs.slaveOk()

master

关闭正在运行的MongoDB服务器

创建实例, 如果在配置文件中配置,则省略此步骤

./bin/mongod -f mongo.conf --replSet mdmaster

每台服务器统一配置,副本集名称相同

需要授权登录,如果设置密码

启动一个新副本集

rs.initiate();

查看副本集配置

rs.conf();

查看副本集状态

rs.status();

rs.initiate({ _id: "mdcluster", version: 1, members: [ { _id: 0, host : "49.235.198.78:27017", arbiterOnly: true }, { _id: 1, host : "110.43.33.21:27017", priority:2 }, { _id: 2, host : "106.13.47.239:27017", priority:1 } ] } );

副本集添加成员

mdmaster:PRIMARY> rs.add(HOST_NAME:PORT);

rs.add("49.235.198.78:27017"); rs.add("110.43.33.21:27017"); rs.add("106.13.47.239:27017");

移除

rs.remove(HOST_NAME:PORT);

添加仲裁

rs.addArb(HOST_NAME:PORT);

向副本集中添加备份节点

rs.add({"_id": 3, "host": "172.16.250.240:27017", "priority": 0, "hidden": true});

判断当前运行的Mongo服务是否为主节点

db.isMaster();

slaver

备份与恢复

手动备份

限制于数据量不大的场景

复制、拷贝、备份

mongodump -h 127.0.0.1:27017 [DATABASE_NAME] -o [db_directory]

代码示例

mongodump -h 127.0.0.1:27017 -d test -o /Users/ysun/program/database/ mongodump -h 127.0.0.1:27017 -d test -o D:\download

恢复

mongorestore -h 127.0.0.1:27017 -d [DATABASE_NAME] [db_directory]

代码示例

mongorestore -h 127.0.0.1:27017 -d program /Users/ysun/program/database/program mongorestore -h 127.0.0.1:27017 -d test D:\devpt\program\database\test

工程化建设方案

性能调优最佳实践

生态系统

体系源码

Last Updated:
Contributors: 709992523