MongoDB学习笔记

打印 上一主题 下一主题

主题 950|帖子 950|积分 2850

MongoDB

一.先容

1.1 NoSQL 和MongoDB

NoSQL=Not Only SQL,⽀持类似SQL的功能, 与Relational Database相辅相成。其性能较⾼,不使⽤SQL意味着没有布局化的存储要求(SQL为布局化的查询语句),没有约束之后架构更加灵活。
NoSQL数据库四⼤家族 列存储 Hbase,键值(Key-Value)存储 Redis,图像存储 Neo4j,⽂档存储 MongoDB
MongoDB 是⼀个基于分布式⽂件存储的数据库,由 C++ 编写,可以为 WEB 应⽤提供可扩展、⾼性能、易摆设的数据存储办理⽅案。
MongoDB 是⼀个介于关系数据库和⾮关系数据库之间的产品,是⾮关系数据库中功能最丰富、最像关系数据库的。在⾼负载的环境下,通过添加更多的节点,可以保证服务器性能。
1.2 MongoDB 体系布局


RDBMSMongoDBdatabase(数据库)database(数据库)table (表)collection( 集合)row( ⾏)document( BSON ⽂档)column (列)field (字段)index(唯⼀索引、主键索引)index (⽀持地理位置索引、全⽂索引 、哈希索引)join (主外键关联)embedded Document (嵌套⽂档)primary key(指定1⾄N个列做主键)primary key (指定_id field做为主键) 1.3 BSON

BSON是⼀种类json的⼀种⼆进制形式的存储格式,简称Binary JSON,它和JSON⼀样,⽀持内嵌的⽂档对象和数组对象,但是BSON有JSON没有的⼀些数据范例,如Date和Binary Data范例。BSON可以做为⽹络数据互换的⼀种存储形式,是⼀种schema-less的存储形式,它的优点是灵活性⾼,但它的缺点是空间利⽤率不是很理想。
{key:value,key2:value2} 这是⼀个BSON的例⼦,此中key是字符串范例,后⾯的value值,它的范例⼀般是字符串,double,Array,ISODate等范例。
BSON有三个特点:轻量性、可遍历性、⾼效性
MongoDB使⽤了BSON这种布局来存储数据和⽹络数据互换。Document就是BSON格式
⼀个Document对应关系数据库就是⼀条记载(Record)
MongoDB中Document 中可以出现的数据范例
数据范例说明表明举例String字符串UTF-8 编码的字符串才是合法的{key:“cba”}Integer整型数值根据你所采⽤的服务器,可分为32位或64位{key:1}Boolean布尔值⽤于存储布尔值{key:true}Double双精度浮点值⽤于存储浮点值{key:3.14}ObjectId对象ID⽤于创建⽂档的ID{_id:new ObjectId()}Array数组⽤于将数组或列表或多个值存储为⼀个键{arr:[“a”,“b”]}Timestamp时间戳从开始纪元开始的毫秒数{ ts: new Timestamp() }Object内嵌⽂档⽂档可以作为⽂档中某个key的value{o:{foo:“bar”}}Null空值表示空值或者未定义的对象{key:null}Date或者ISODate格林尼治时间⽇期时间,⽤Unix⽇期格式来存储当前⽇期或时间{birth:new Date()}Code代码可以包含JS代码{x:function(){}}File⽂件1、⼆进制转码(Base64)后存储 (<16M)
2.GridFS(>16M)GridFS ⽤两个集合来存储⼀个⽂件:fs.files与fs.chunks 真正存储必要使⽤mongofiles -d gridfs put song.mp3 1.4 适⽤场景

适用场景:


  • ⽹站数据:Mongo ⾮常得当实时的插⼊,更新与查询,并具备⽹站实时数据存储所需的复制及⾼度伸缩性。
  • 缓存:由于性能很⾼,Mongo 也得当作为信息根本办法的缓存层。在体系重启之后,由Mongo 搭建的持久化缓存层可以避免下层的数据源过载
  • ⼤尺⼨、低价值的数据:使⽤传统的关系型数据库存储⼀些⼤尺⼨低价值数据时会⽐较浪费,在此之前,许多时候程序员往往会选择传统的⽂件进⾏存储。
  • ⾼伸缩性的场景:Mongo ⾮常得当由数⼗或数百台服务器构成的数据库,Mongo 的蹊径图中已经包含对MapReduce 引擎的内置⽀持以及集群⾼可⽤的办理⽅案。
  • ⽤于对象及JSON 数据的存储:Mongo 的BSON 数据格式⾮常得当⽂档化格式的存储及查询
具体应⽤场景:


  • 游戏场景
    使⽤ MongoDB 存储游戏⽤户信息,⽤户的装备、积分等直接以内嵌⽂档的形式存储,⽅便查询、更新。
  • 物流场景
    使⽤ MongoDB 存储订单信息,订单状态在运送过程中会不断更新,以 MongoDB 内嵌数组的形式来存储,⼀次查询就能将订单所有的变更读取出来。
  • 外交场景
    使⽤ MongoDB 存储存储⽤户信息,以及⽤户发表的朋侪圈信息,通过地理位置索引实现附近的⼈、地点等功能。
  • 物联⽹场景
    使⽤ MongoDB 存储所有接⼊的智能设备信息,以及设备汇报的⽇志信息,并对这些信息进⾏多维度的分析。
  • 直播
    使⽤ MongoDB 存储⽤户信息、礼物信息等。
应⽤特征:


  • 应⽤必须不必要事件及复杂 join ⽀持
  • 新应⽤,需求会变,数据模子⽆法确定,想快速迭代开辟
  • 应⽤必要2000-3000以上的读写QPS(更⾼也可以)
  • 应⽤必要TB甚⾄ PB 级别数据存储
  • 应⽤发展敏捷,必要能快速⽔平扩展
  • 应⽤要求存储的数据不丢失
  • 应⽤必要99.999%⾼可⽤
  • 应⽤必要⼤量的地理位置查询、⽂本查询
1.5 搭建

去官网下载社区版,本文用的MongoDB 4.2.24,机器是mac,然后将压缩包解压即可
1.5.1 单机



  • cd到解压路径下
  • 创建一个生存数据的目录(mongo/data)
  • 单机启动:
    1. ./bin/mongod
    复制代码
  • 指定配置⽂件⽅式的启动
    1. ./bin/mongod
    2. -f mongo.conf
    复制代码
  • 配置⽂件样例
    1. #数据库⽬录
    2. dbpath=mongo/data/
    3. #监听的端⼝
    4. port=27017
    5. # 监听IP地址,默认全部可以访问
    6. bind_ip=0.0.0.0
    7. #是否以后台启动的⽅式启动
    8. fork=true
    9. #⽇志路径
    10. logpath = mongo/data/MongoDB.log
    11. #是否追加⽇志
    12. logappend = true
    13. #是开启⽤户密码登陆
    14. auth=false
    复制代码
  • shell 的启动
    1. #启动mongo shell
    2. ./bin/mongo
    3. #指定主机和端⼝的⽅式启动
    4. ./bin/mongo --host=主机IP --port=端⼝
    复制代码
1.5.2 复制集



  • cd到解压路径下
  • 创建三个生存数据的目录(mongo/data/server1、mongo/data/server2、mongo/data/server3)
  • 新建三个conf文件,命名分别是mongo_27017、mongo_27018、mongo_27019
  • mongo_27017.conf
    1. # 主节点配置
    2. dbpath=mongo/data/server1
    3. bind_ip=0.0.0.0
    4. port=27017
    5. fork=true
    6. logpath=/data/mongo/logs/server1.log
    7. replSet=testReplicaRets
    复制代码
  • mongo_27018.conf
    1. # 主节点配置
    2. dbpath=mongo/data/server2
    3. bind_ip=0.0.0.0
    4. port=27018
    5. fork=true
    6. logpath=/data/mongo/logs/server2.log
    7. replSet=testReplicaRets
    复制代码
  • mongo_27019.conf
    1. # 主节点配置
    2. dbpath=mongo/data/server3
    3. bind_ip=0.0.0.0
    4. port=27019
    5. fork=true
    6. logpath=/data/mongo/logs/server3.log
    7. replSet=testReplicaRets
    复制代码
  • 启动
    1. ./bin/mongod
    2. -f mongo_27017.conf./bin/mongod
    3. -f mongo_27018.conf./bin/mongod
    4. -f mongo_27019.conf
    复制代码
  • 随便进入一个节点,进行初始化
    1. var cfg ={"_id":"testReplicaRets",
    2. "protocolVersion" : 1,
    3. "members":[
    4. {"_id":1,"host":"localhost:27017","priority":10},
    5. {"_id":2,"host":"localhost:27018"},
    6. {"_id":3,"host":"localhost:27019"},
    7. ]
    8. }
    9. rs.initiate(cfg)
    10. rs.status()
    复制代码
  • 节点的动态增删
    1. 增加节点
    2. rs.add("localhost:27019")
    3. 删除slave 节点
    4. rs.remove("localhost:27019")
    复制代码
  • 仲裁节点动态增删
    1. rs.addArb("localhost:37020")
    复制代码
复制集成员的配置参数
参数字段范例说明取值说明_id整数_id:0复制集中的标示,不能重复host字符串host:“主机:端⼝”节点主机名arbiterOnly布尔值arbiterOnly:true是否为仲裁(裁判)节点priority整数priority=0|1权重,默认1,是否有资格变成主节点,取值范围0-1000,0永远不会变成主节点hidden布尔值hidden=true|false,0|1是否潜伏,权重必须为0,才可以设置votes整数votes= 0|1是否为投票节点,0 不投票,1投票slaveDelay整数slaveDelay=3600从库的延迟多少秒buildIndexes布尔值buildIndexes=true|false,0|1主库的索引,从库也创建,_id索引⽆效 1.5.3 分片集群



  • 配置config节点集群

    • 创建好各个配置节点必要的目录
    • 配置conf文件

      • config_37017.conf
        1. dbpath=config_37017
        2. port=37017
        3. bind_ip=0.0.0.0
        4. fork=true
        5. logpath = config_37017/config.log
        6. logappend = true
        7. auth=false
        8. replSet=testConfig
        9. configsvr=true
        复制代码
      • config_37018.conf
        1. dbpath=config_37018
        2. port=37017
        3. bind_ip=0.0.0.0
        4. fork=true
        5. logpath = config_37018/config.log
        6. logappend = true
        7. auth=false
        8. replSet=testConfig
        9. configsvr=true
        复制代码
      • config_37019.conf
        1. dbpath=config_37019
        2. port=37017
        3. bind_ip=0.0.0.0
        4. fork=true
        5. logpath = config_37019/config.log
        6. logappend = true
        7. auth=false
        8. replSet=testConfig
        9. configsvr=true
        复制代码

    • 启动
      1. ./bin/mongod
      2. -f config/config_37017.conf./bin/mongod
      3. -f config/config_37018.conf./bin/mongod
      4. -f config/config_37019.conf
      复制代码
    • 初始化,要切换到admin库下
      1. use admin
      2. var cfg ={"_id":"testConfig",
      3. "members":[
      4. {"_id":1,"host":"localhost:37017"},
      5. {"_id":2,"host":"localhost:37018"},
      6. {"_id":3,"host":"localhost:37019"}]
      7. };
      8. rs.initiate(cfg)
      复制代码

  • 配置shard(分片)节点集群

    • 创建节点必要的目录
    • 配置conf文件
      和配置复制集一样,只不过要在配置文件中加上
      1. shardsvr=true
      复制代码
    • 启动
      1. #分片1./bin/mongod
      2. -f config/mongo_27018.conf./bin/mongod
      3. -f config/mongo_27019.conf./bin/mongod
      4. -f config/mongo_27020.conf#分片2./bin/mongod
      5. -f config/mongo_27021.conf./bin/mongod
      6. -f config/mongo_27022.conf./bin/mongod
      7. -f config/mongo_27023.conf
      复制代码
    • 初始化
      进入某个分片集群任意节点对该集群进行初始化
      1. #分片1
      2. var cfg ={"_id":"shard1",
      3. "protocolVersion" : 1,
      4. "members":[
      5. {"_id":1,"host":"localhost:27020"},
      6. {"_id":2,"host":"localhost:27018"},
      7. {"_id":3,"host":"localhost:27019","arbiterOnly":true}
      8. ]
      9. };
      10. rs.initiate(cfg)
      11. rs.reconfig(cfg)
      12. rs.status()
      13. #分片2
      14. var cfg ={"_id":"shard2",
      15. "protocolVersion" : 1,
      16. "members":[
      17. {"_id":1,"host":"localhost:27023"},
      18. {"_id":2,"host":"localhost:27021"}
      19. {"_id":3,"host":"localhost:27022","arbiterOnly":true}
      20. ]
      21. }
      22. rs.initiate(cfg)
      23. rs.reconfig(cfg)
      24. rs.status()
      复制代码

  • 配置路由节点

    • 创建节点必要的目录
    • 配置conf文件
      和配置单机启动时一样,只不过要在配置文件中加上
      1. configdb=testConfig/localhost:37017,localhost:37018,localhost:37019
      复制代码
    • 启动
      1. ./bin/mongos -f route/route_27017.conf
      复制代码

  • 为路由添加分⽚节点
    进⼊路由mongos
    1. sh.status()
    2. sh.addShard("shard1/localhost:27018,localhost:27019,localhost:27020");
    3. sh.addShard("shard1/localhost:27021,localhost:27022,localhost:27023");
    4. sh.status()
    复制代码
  • 指定⽚键
    进⼊路由mongos
    为数据库开启分⽚功能
    1. sh.enableSharding("testdb")
    复制代码
    为指定集合开启分⽚功能
    1. sh.shardCollection("testdb.test_datas",{"⽚键字段名如name":索引说明,如hashed})
    复制代码
二.命令

2.1 基本操纵

  1. 查看数据库:show dbs;
  2. 切换数据库 如果没有对应的数据库则创建:use 数据库名;
  3. 创建集合:db.createCollection("集合名")
  4. 查看集合:show tables;或show collections;
  5. 删除集合:db.集合名.drop();
  6. 删除当前数据库:db.dropDatabase()
复制代码
2.2 CURD

2.2.1 插入

单条:db.集合名.insertOne(BSON)
  1. db.testdb.insertOne({name:"张晓峰",birthday:new ISODate("2000-07-01"),gender:1,expectSalary:15000,city:"bj"})
复制代码
多条:db.集合名.insertMany([BSON,BSON])
  1. db.testdb.insertMany(
  2.     [{name:"李丽",birthday:new Date("1996-05-01 14:20:09"),gender:0,expectSalary:21000,city:"sz"},
  3.      {name:"李平",birthday:new Date("1997-07-01 14:20:09"),gender:0,expectSalary:22000,city:"sz"}])
复制代码
2.2.2 查询

db.集合名.find(条件)
比力查询
操纵条件格式例⼦RDBMS中的条件等于{key:value}db.col.find({字段名:值}).pretty()where 字段名=值大于{key:{$gt:value}}db.col.find({字段名:{$gt:值}}).pretty()where 字段名>值大于等于{key:{$gte:value}}db.col.find({字段名:{$gte:值}}).pretty()where 字段名>=值小于{key:{$lt:value}}db.col.find({字段名:{$lt:值}}).pretty()where 字段名<值小于等于{key:{$lte:value}}db.col.find({字段名:{$lte:值}}).pretty()where 字段名<=值不等于{key:{$ne:value}}db.col.find({字段名:{$ne:值}}).pretty()where 字段名!=值 逻辑条件查询
  1. and 条件:MongoDB 的 find() ⽅法可以传⼊多个键(key),每个键(key)以逗号隔开,即常规 SQL 的 AND 条件 db.集合名.find({key1:value1, key2:value2}).pretty()
  2. or 条件:db.集合名.find({$or:[{key1:value1}, {key2:value2}]}).pretty()
  3. not 条件:db.集合名.find({key:{$not:{$操作符:value}}).pretty()
复制代码
分⻚查询
db.集合名.find({条件}).sort({排序字段:排序⽅式})).skip(跳过的⾏数).limit(⼀⻚体现多少数据)
2.2.3 修改

  1. db.集合名.update(<query>,<update>,{upsert: <boolean>,multi: <boolean>,writeConcern: <document>})
复制代码
参数说明:


  • query : update的查询条件,类似sql update查询内where后⾯的。
  • update : update的对象和⼀些更新的操纵符(如                                             s                               e                               t                               ,                                      set,                        set,inc…)等,也可以理解为sql update中set后⾯的

    • $set:设置字段值
    • $unset:删除指定字段
    • $inc:对修改的值进⾏⾃增

  • upsert : 可选,这个参数的意思是,假如不存在update的记载,是否插⼊objNew,true为插⼊,默认是false,不插⼊。
  • multi:可选,MongoDB 默认是false,只更新找到的第⼀条记载,假如这个参数为true,就把按条件查出来多条记载全部更新。
  • writeConcern:可选,⽤来指定mongod对写操纵的回执⾏为⽐如写的⾏为是否必要确认。
    writeConcern 包括以下字段:{ w: , j: , wtimeout: }

    • w:该选项要求确认操纵已经流传到指定数目的mongod实例或指定标签的mongod实例
      w=0:非应答式写入,不返回任何相应,所以无法知道写入是否乐成,但是对于尝试向已关闭的套接字写入或者网络故障会返回socket exceptions和 networking errors
      w=1(默认):应答式写入,要求确认操纵已经流传到指定的单个mongod实例或副本集主实例
      w>1(用于副本集环境):该值用于设定写入节点的数目,包括主节点
      w=“majority”:适用于集群架构,要求写入操纵已经通报到绝大多数投票节点以及主节点后进行应答
      :要求写入操纵已经通报到指定tag标记副本集中的成员后进行应答
    • j:该选项要求确认写操纵已经写入journal日志之后应答客户端(必要开启journal功能)
    • wtimeout:指定write concern的时间限制,以防止写操纵无穷制被阻塞导致无法应答给客户端
      wtimeout的单位为ms,当w值大于1时生效,该参数即仅适用于集群环境
      当某个节点写入时超出指定wtimeout之后,mongod将返回一个错误
      在捕捉到超时之前,mongod并不会撤销其他节点已乐成完成的写入
      wtimeout值为0时等同于没有配置wtimeout选项,容易导致由于某个节点挂起而无法应答

对于单实例应答的环境,是将数据写入到内存后开始应答,除非j:true,则保证掉电后不会丢失数据
2.2.4 删除

  1. db.collection.remove(<query>,{justOne: <boolean>,writeConcern: <document>})
复制代码
参数说明:


  • query :(可选)删除的⽂档的条件。
  • justOne : (可选)假如设为 true 或 1,则只删除⼀个⽂档,假如不设置该参数,或使⽤默认值 false,则删除所有匹配条件的⽂档。
  • writeConcern :(可选)⽤来指定mongod对写操纵的回执⾏为。
2.3 聚合操纵

聚合是MongoDB的⾼级查询语⾔,它允许我们通过转化归并由多个⽂档的数据来⽣成新的在单个⽂档⾥不存在的⽂档信息。⼀般都是将记载按条件分组之后进⾏⼀系列求最⼤值,最⼩值,均匀值的简单操纵,也可以对记载进⾏复杂数据统计,数据挖掘的操纵。聚合操纵的输⼊是集中的⽂档,输出可以是⼀个⽂档也可以是多个⽂档。
分类


  • 单⽬的聚合操纵(Single Purpose Aggregation Operation)
  • 聚合管道(Aggregation Pipeline)
  • MapReduce 编程模子
2.3.1 单⽬的聚合操纵

单⽬的聚合命令常⽤的有:count() 和 distinct()
  1. db.lg_resume_preview.find({}).count()
复制代码
2.3.2 聚合管道(Aggregation Pipeline)

MongoDB中聚合(aggregate)主要⽤于统计数据(诸如统计均匀值,求和等),并返回盘算后的数据结果。
表达式:处理输⼊⽂档并输出。表达式只能⽤于盘算当前聚合管道的⽂档,不能处理别的的⽂档。
表达式描述$sum盘算某个字段的总和或者求count$avg盘算均匀值$min获取集合中所有⽂档对应值得最⼩值$max获取集合中所有⽂档对应值得最⼤值$push在结果⽂档中插⼊值到⼀个数组中$addToSet在结果⽂档中插⼊值到⼀个数组中,但数据不重复$first根据资源⽂档的排序获取第⼀个⽂档数据$last根据资源⽂档的排序获取末了⼀个⽂档数据 MongoDB 中使⽤ db.COLLECTION_NAME.aggregate([{},…]) ⽅法来构建和使⽤聚合管道,每个⽂档通过⼀个由⼀个或者多个阶段(stage)构成的管道,经过⼀系列的处理,输出相应的结果。
MongoDB的聚合管道将MongoDB⽂档在⼀个管道处理完毕后将结果通报给下⼀个管道处理。管道操纵是可以复的。
聚合框架中常⽤的⼏个操纵:


  • $group:将集合中的⽂档分组,可⽤于统计结果。
  • $project:修改输⼊⽂档的布局。可以⽤来重命名、增长或删除域,也可以⽤于创建盘算结果以及嵌套⽂档。
  • **                                        m                            a                            t                            c                            h                            ∗                            ∗                            :⽤于过滤数据,只输出符合条件的⽂档。                                  match**:⽤于过滤数据,只输出符合条件的⽂档。                     match∗∗:⽤于过滤数据,只输出符合条件的⽂档。match使⽤MongoDB的标准查询操纵。
  • $limit:⽤来限制MongoDB聚合管道返回的⽂档数。
  • $skip:在聚合管道中跳过指定数目的⽂档,并返回余下的⽂档。
  • $sort:将输⼊⽂档排序后输出。
  • $geoNear:输出接近某⼀地理位置的有序⽂档。
  1. db.testdb.aggregate([{$group : {_id: "$city", avgSal:{$avg:"$expectSalary"}}},{$project : {city:"$city", salary : "$avgSal"}}])
  2. db.testdb.aggregate([{$group:{_id: "$city",count:{$sum : 1}}}, {$match:{count:{$gt:1}}}])
复制代码
2.3.3 MapReduce 编程模子

Pipeline查询速率快于MapReduce,但是MapReduce的强⼤之处在于能够在多台Server上并⾏执⾏复杂的聚合逻辑。MongoDB不允许Pipeline的单个聚合操纵占⽤过多的体系内存,假如⼀个聚合操纵消耗20%以上的内存,那么MongoDB直接停⽌操纵,并向客户端输出错误消息。
MapReduce是⼀种盘算模子,简单的说就是将⼤批量的⼯作(数据)分解(MAP)执⾏,然后再将结果归并成最闭幕果(REDUCE)。
  1. db.collection.mapReduce(
  2. function() {emit(key,value);}, //map 函数
  3. function(key,values) {return reduceFunction}, //reduce 函数
  4. {
  5. out: collection,
  6. query: document,
  7. sort: document,
  8. limit: number,
  9. finalize: <function>,
  10. verbose: <boolean>
  11. }
  12. )
复制代码
使⽤ MapReduce 要实现两个函数 Map 函数和 Reduce 函数,Map 函数调⽤ emit(key, value), 遍历 collection 中所有的记载, 将 key 与 value 通报给 Reduce 函数进⾏处理。
参数说明:


  • map:是JavaScript 函数,负责将每⼀个输⼊⽂档转换为零或多个⽂档,⽣成键值对序列,作为 reduce 函数参数
  • reduce:是JavaScript 函数,对map操纵的输出做归并的化简的操纵(将key-value变成key-values,也就是把values数组变成⼀个单⼀的值value)
  • out:统计结果存放集合
  • query: ⼀个筛选条件,只有满⾜条件的⽂档才会调⽤map函数。
  • sort: 和limit联合的sort排序参数(也是在发往map函数前给⽂档排序),可以优化分组机制
  • limit: 发往map函数的⽂档数目的上限(要是没有limit,单独使⽤sort的⽤处不⼤)
  • finalize:可以对reduce输出结果再⼀次修改
  • verbose:是否包括结果信息中的时间信息,默以为fasle
  1. db.testdb.mapReduce(
  2. function() { emit(this.city,this.expectSalary); },
  3. function(key, value) {return Array.avg(value)},
  4. {
  5. query:{expectSalary:{$gt: 15000}},
  6. out:"cityAvgSal"
  7. }
  8. )
复制代码
三.索引Index

索引是⼀种单独的、物理的对数据库表中⼀列或多列的值进⾏排序的⼀种存储布局,它是某个表中⼀列或若⼲列值的集合和指向这些值数据⻚的逻辑指针清单。
索引⽬标是提⾼数据库的查询服从,没有索引的话,查询会进⾏全表扫描(scan every document in a collection),数据量⼤时严重低落了查询服从。默认环境下Mongo在⼀个集合(collection)创建时,⾃动地对集合的_id创建了唯⼀索引。
3.1 索引范例



  • 单键索引 (Single Field)
MongoDB⽀持所有数据范例中的单个字段索引,而且可以在⽂档的任何字段上定义。
对于单个字段索引,索引键的排序顺序⽆关紧要,由于MongoDB可以在任⼀⽅向读取索引。
  1. db.集合名.createIndex({"字段名":排序⽅式})
复制代码
特殊的单键索引 逾期索引TTL(Time To Live)
TTL索引是MongoDB中⼀种特殊的索引, 可以⽀持⽂档在⼀定时间之后⾃动逾期删除,⽬前TTL索引只能在单字段上建⽴,而且字段范例必须是⽇期范例。
  1. db.集合名.createIndex({"⽇期字段":排序⽅式}, {expireAfterSeconds: 秒数})
复制代码


  • 复合索引(Compound Index)
    复合索引⽀持基于多个字段的索引, 复合索引要注意的重要事项包括:字段顺序与索引⽅向。
    1. db.集合名.createIndex( { "字段名1" : 排序⽅式, "字段名2" : 排序⽅式 } )
    2. 排序⽅式参数是1或-1
    复制代码
  • 多键索引(Multikey indexes)
    针对属性包含数组数据的环境,MongoDB⽀持针对数组中每⼀个element创建索引,Multikey indexes⽀持strings,numbers和nested documents
  • 地理空间索引(Geospatial Index)
针对地理空间坐标数据创建索引。
2dsphere索引,⽤于存储和查找球⾯上的点
2d索引,⽤于存储和查找平⾯上的点
  1. db.company.insert(
  2. {
  3. loc : { type: "Point", coordinates: [ 116.482451, 39.914176 ] },
  4. name: "⼤望路地铁",
  5. category : "Parks"
  6. }
  7. )
  8. db.company.ensureIndex( { loc : "2dsphere" } )
  9. 参数为2dsphere 或者 2d。还可以建⽴组合索引。
  10. db.company.find({
  11. "loc" : {
  12. "$geoWithin" : {
  13. "$center":[[116.482451,39.914176],0.05]
  14. }
  15. }
  16. })
复制代码


  • 全⽂索引
    MongoDB提供了针对string内容的⽂本查询,Text Index⽀持任意属性值为string或string数组元素的索引询。
    注意:⼀个集合仅⽀持最多⼀个Text Index,中⽂分词不理想 推荐ES。
    1. db.集合.createIndex({"字段": "text"})
    2. db.集合.find({"$text": {"$search": "coffee"}})
    复制代码
  • 哈希索引 Hashed Index
    针对属性的哈希值进⾏索引查询,当要使⽤Hashed index时,MongoDB能够⾃动的盘算hash值,⽆需程序盘算hash值。注:hash index仅⽀持等于查询,不⽀持范围查询。
    1. db.集合.createIndex({"字段": "hashed"})
    复制代码
3.2 索引管理



  • 创建索引并在后台运⾏
    1. db.COLLECTION_NAME.createIndex({"字段":排序⽅式}, {background: true});
    复制代码
  • 获取针对某个集合的索引
    1. db.COLLECTION_NAME.getIndexes()
    复制代码
  • 索引的⼤⼩
    1. db.COLLECTION_NAME.totalIndexSize()
    复制代码
  • 索引的重建
    1. db.COLLECTION_NAME.reIndex()
    复制代码
  • 索引的删除
    1. db.COLLECTION_NAME.dropIndex("INDEX-NAME")
    2. db.COLLECTION_NAME.dropIndexes()
    3. 注意: _id 对应的索引是删除不了的
    复制代码
3.3 explain 分析

explain参数:


  • queryPlanner:queryPlanner是默认参数
       参数寄义plannerVersion查询操持版本namespace要查询的集合(该值返回的是该query所查询的表)数据库.集合indexFilterSet针对该query是否有indexFilterparsedQuery查询条件winningPlan被选中的执⾏操持winningPlan.stage被选中执⾏操持的stage(查询⽅式),常⻅的有:COLLSCAN/全表扫描、IXSCAN/索引扫描、FETCH/根据索引去检索⽂档、SHARD_MERGE/归并分⽚结果、IDHACK/针对_id进⾏查询等winningPlan.inputStage⽤来描述⼦stage,而且为其⽗stage提供⽂档和索引关键字。winningPlan.stage的child stage假如此处是IXSCAN,表示进⾏的是index scanning。winningPlan.keyPattern所扫描的index内容winningPlan.indexNamewinning plan所选⽤的indexwinningPlan.isMultiKey是否是Multikey,此处返回是false,假如索引建⽴在array上,此处将是true。winningPlan.direction此query的查询顺序,默认是forward,假如⽤了.sort({字段:-1})将体现backward。filter过滤条件winningPlan.indexBoundswinningplan所扫描的索引范围,假如没有制定范围就是[MaxKey, MinKey],这主要是直接定位到mongodb的chunck中去查找数据,加快数据读取。rejectedPlans被拒绝的执⾏操持的详细返回,此中具体信息与winningPlan的返回中意义雷同serverInfoMongoDB服务器信息
  • executionStats:executionStats会返回执⾏操持的⼀些统计信息(有些版本中和allPlansExecution等同)。
       参数寄义executionSuccess是否执⾏乐成nReturned返回的⽂档数executionTimeMillis查询的执⾏耗时,越小越好totalKeysExamined索引扫描次数totalDocsExamined⽂档扫描次数executionStages这个分类下描述执⾏的状态stage扫描⽅式,具体可选值与上⽂的雷同nReturned查询结果数目executionTimeMillisEstimate检索document得到数据的时间inputStage.executionTimeMillisEstimate该查询扫描⽂档 index所⽤时间works⼯作单位数,⼀个查询会分解成⼩的⼯作单位advanced优先返回的结果数docsExamined⽂档检查数⽬,与totalDocsExamined⼀致。检查了统共的document个数,⽽从返回上⾯的nReturned数目
  • allPlansExecution:allPlansExecution⽤来获取所有执⾏操持,结果参数是queryPlanner 参数和executionStats的拼接。
常见的stage的范例如下:


  • COLLSCAN:全表扫描
  • IXSCAN:索引扫描
  • FETCH:根据索引去检索指定document
  • SHARD_MERGE:将各个分⽚返回数据进⾏merge
  • SORT:表明在内存中进⾏了排序
  • LIMIT:使⽤limit限制返回数
  • SKIP:使⽤skip进⾏跳过
  • IDHACK:针对_id进⾏查询
  • SHARDING_FILTER:通过mongos对分⽚数据进⾏查询
  • COUNT:利⽤db.coll.explain().count()之类进⾏count运算
  • TEXT:使⽤全⽂索引进⾏查询时候的stage返回
  • PROJECTION:限定返回字段时候stage的返回
对于平凡查询,比力快的stage的组合(查询的时候尽可能⽤上索引):
Fetch+IDHACK
Fetch+IXSCAN
Limit+(Fetch+IXSCAN)
PROJECTION+IXSCAN
SHARDING_FITER+IXSCAN
必要优化的的stage:
COLLSCAN(全表扫描)
SORT(使⽤sort但是⽆index)
COUNT 不使⽤index进⾏count)
3.4 慢查询分析



  • 开启内置的查询分析器,记载读写操纵服从
    db.setProfilingLevel(n,m),n的取值可选0,1,2

    • 0:表示不记载
    • 1:表示记载慢速操纵,假如值为1,m必须赋值单位为ms,⽤于定义慢速查询时间的阈值
    • 2:表示记载所有的读写操纵

  • 查询监控结果
    db.system.profile.find().sort({millis:-1}).limit(3)
  • 分析慢速查询
    应⽤程序设计是否公道
    是否有不正确的数据模子
    是否有硬件配置问题,是否缺少索引等
  • 解读explain结果 确定是否缺少索引
3.5 索引底层实现原理

MongoDB 是⽂档型的数据库,它使⽤BSON 格式生存数据,⽐关系型数据库存储更⽅便。MySql是关系型数据库,数据的关联性是⾮常强的,区间访问是常⻅的⼀种环境,底层索引组织数据使⽤B+树,B+树由于数据全部存储在叶⼦节点,而且通过指针串在⼀起,如许就很容易的进⾏区间遍历甚⾄全部遍历。MongoDB使⽤B-树,所有节点都有Data域,只要找到指定索引就可以进⾏访问,单次查询从布局上来看要快于MySql。
B-树的特点:


  • 多路⾮⼆叉树
  • 每个节点既生存数据⼜生存索引
  • 搜刮时相当于⼆分查找
B-树是⼀种⾃均衡的搜刮树,形式很简单:

B+树是B-树的变种,B+ 树的特点:


  • 多路⾮⼆叉
  • 只有叶⼦节点生存数据
  • 搜刮时 也相当于⼆分查找
  • 增长了 相邻节点指针

MongoDB和MySql的差异:


  • B+树相毗邻点的指针可以⼤⼤增长区间访问性,可使⽤在范围查询等,⽽B-树每个节点 key 和 data 在⼀起得当随机读写 ,⽽区间查找服从很差。
  • B+树更得当外部存储,也就是磁盘存储,使⽤B-布局的话,每次磁盘预读中的许多数据是⽤不上的数据。因此,它没能利⽤好磁盘预读的提供的数据。由于节点内⽆ data 域,每个节点能索引的范围更⼤更准确。
  • B-树每个节点即生存数据⼜生存索引,树的深度⼤,所以磁盘IO的次数多,B+树只有叶⼦节点生存数据,较B-树⽽⾔深度⼩,磁盘IO少,有利于区间访问
四.架构

4.1 逻辑布局

MongoDB 与 MySQL 中的架构相差不多,底层都使⽤了可插拔的存储引擎以满⾜⽤户的差别必要。⽤户可以根据程序的数据特征选择差别的存储引擎,在最新版本的 MongoDB 中使⽤了 WiredTiger 作为默认的存储引擎,WiredTiger 提供了差别粒度的并发控制和压缩机制,能够为差别种类的应⽤提供了最好的性能和存储率。
在存储引擎上层的就是 MongoDB 的数据模子和查询语⾔了,由于 MongoDB 对数据的存储与 RDBMS 有较⼤的差异,所以它创建了⼀套差别的数据模子和查询语⾔
4.2 数据模子

范例:


  • 内嵌
    内嵌的⽅式指的是把相关联的数据生存在同⼀个⽂档布局之中。MongoDB的⽂档布局允许⼀个字段或者⼀个数组内的值作为⼀个嵌套的⽂档。
  • 引⽤
    引⽤⽅式通过存储数据引⽤信息来实现两个差别⽂档之间的关联,应⽤程序可以通过解析这些数据引⽤来访问相关数据。
选择:


  • 选择内嵌

    • 数据对象之间有包含关系 ,⼀般是数据对象之间有⼀对多或者⼀对⼀的关系 。
    • 必要经常⼀起读取的数据。
    • 有 map-reduce/aggregation 需求的数据放在⼀起,这些操纵都只能操纵单个 collection。

  • 选择引⽤

    • 当内嵌数据会导致许多数据的重复,而且读性能的优势⼜不⾜于覆盖数据重复的毛病 。
    • 必要表达⽐较复杂的多对多关系的时候 。
    • ⼤型层次结果数据集嵌套不要太深。

4.3 WiredTiger存储引擎

存储引擎是MongoDB的核⼼组件,负责管理数据怎样存储在硬盘和内存上。MongoDB⽀持的存储引擎有MMAPv1,WiredTiger和InMemory。InMemory存储引擎⽤于将数据只存储在内存中,只将少量的元数据(meta-data)和诊断⽇志(Diagnostic)存储到硬盘⽂件中,由于不必要Disk的IO操纵,就能获取所需的数据,InMemory存储引擎⼤幅度低落了数据查询的延迟(Latency)。从mongodb3.2开始默认的存储引擎是WiredTiger,3.2版本之前的默认存储引擎是MMAPv1,mongodb4.x版本不再⽀持MMAPv1存储引擎
  1. storage:
  2. journal:
  3.         enabled: true
  4. dbPath: /data/mongo/
  5. ##是否⼀个库⼀个⽂件夹
  6. directoryPerDB: true
  7. ##数据引擎
  8. engine: wiredTiger
  9. ##WT引擎配置
  10. WiredTiger:
  11.         engineConfig:
  12.                 ##WT最⼤使⽤cache(根据服务器实际情况调节)
  13.                 cacheSizeGB: 2
  14.                 ##是否将索引也按数据库名单独存储
  15.                 directoryForIndexes: true
  16.                 journalCompressor:none (默认snappy)
  17.         ##表压缩配置
  18.         collectionConfig:
  19.                 blockCompressor: zlib (默认snappy,还可选none、zlib)
  20.         ##索引配置
  21.         indexConfig:
  22.                 prefixCompression: true
复制代码
4.3.1 优势



  • ⽂档空间分配⽅式
    WiredTiger使⽤的是BTree存储 MMAPV1 线性存储 必要Padding
  • 并发级别
    WiredTiger ⽂档级别锁 MMAPV1引擎使⽤表级锁
  • 数据压缩
    snappy (默认) 和 zlib ,相⽐MMAPV1(⽆压缩) 空间节省数倍。
  • 内存使⽤
    WiredTiger 可以指定内存的使⽤⼤⼩。
  • Cache使⽤
    WT引擎使⽤了⼆阶缓存WiredTiger Cache, File System Cache来保证Disk上的数据的最终⼀致性。⽽MMAPv1 只有journal ⽇志。
4.3.2 ⽂件和作⽤



  • WiredTiger.basecfg: 存储基本配置信息,与 ConfigServer有关系
  • WiredTiger.lock: 定义锁操纵
  • table.wt*: 存储各张表的数据
  • WiredTiger.wt: 存储table* 的元数据
  • WiredTiger.turtle: 存储WiredTiger.wt的元数据
  • journal: 存储WAL(Write Ahead Log)
4.3.3 实现原理

写请求
WiredTiger的写操纵会默认写⼊ Cache ,并持久化到 WAL (Write Ahead Log),每60s或Log⽂件到达2G做⼀次 checkpoint (当然我们也可以通过在写⼊时传⼊ j: true 的参数强制 journal ⽂件的同步 ,writeConcern { w: , j: ,wtimeout: }) 产⽣快照⽂件。WiredTiger初始化时,规复⾄最新的快照状态,然后再根据WAL规复数据,保证数据的完整性。
Cache是基于BTree的,节点是⼀个page,root page是根节点,internal page是中间索引节点,leaf page真正存储数据,数据以page为单位读写。WiredTiger采⽤Copy on write的⽅式管理写操纵(insert、update、delete),写操纵会先缓存在cache⾥,持久化时,写操纵不会在原来的leaf page上进⾏,⽽是写⼊新分配的page,每次checkpoint都会产⽣⼀个新的root page。
checkpoint流程


  • 对所有的table进⾏⼀次checkpoint,每个table的checkpoint的元数据更新⾄WiredTiger.wt
  • 对WiredTiger.wt进⾏checkpoint,将该table checkpoint的元数据更新⾄临时⽂件WiredTiger.turtle.set
  • 将WiredTiger.turtle.set重命名为WiredTiger.turtle。
  • 上述过程假如中间失败,WiredTiger在下次连接初始化时,⾸先将数据规复⾄最新的快照状态,然后根据WAL规复数据,以保证存储可靠性
Journaling
在数据库宕机时 , 为保证 MongoDB 中数据的持久性,MongoDB 使⽤了 Write Ahead Logging 向磁盘上的journal ⽂件预先进⾏写⼊。除了 journal ⽇志,MongoDB 还使⽤检查点(checkpoint)来保证数据的⼀致性,当数据库发⽣宕机时,我们就必要 checkpoint 和 journal ⽂件协作完成数据的规复⼯作。


  • 在数据⽂件中查找上⼀个检查点的标识符
  • 在 journal ⽂件中查找标识符对应的记载
  • 重做对应记载之后的全部操纵
五.集群⾼可⽤

5.1 主从复制架构

master-slave架构中master节点负责数据的读写,slave没有写⼊权限只负责读取数据
在主从布局中,主节点的操纵记载成为oplog(operation log)。oplog存储在体系数据库local的oplog.$main集合中,这个集合的每个⽂档都代表主节点上执⾏的⼀个操纵。从服务器会定期从主服务器中获取oplog记载,然后在本机上执⾏!对于存储oplog的集合,MongoDB采⽤的是固定集合,也就是说随着操纵过多,新的操纵会覆盖旧的操纵!
主从布局没有⾃动故障转移功能,必要指定master和slave端,不推荐在⽣产中使⽤。
mongodb4.0后不再⽀持主从复制!
5.2 复制集replica sets

复制集是由⼀组拥有雷同数据集的mongod实例做构成的集群。
复制集是⼀个集群,它是2台及2台以上的服务器构成,以及复制集成员包括Primary主节点,secondary从节点和投票节点。
复制集提供了数据的冗余备份,并在多个服务器上存储数据副本,提⾼了数据的可⽤性,保证数据的安全性。
特点:


  • ⾼可⽤
    防⽌设备(服务器、⽹络)故障。
    提供⾃动failover 功能。
    技能来保证⾼可⽤
  • 灾难规复
    当发⽣故障时,可以从其他节点规复⽤于备份。
  • 功能隔离
    我们可以在从节点上执⾏读操纵,减少主节点的压⼒。⽐如:⽤于分析、报表,数据挖掘,体系任务等。
5.2.1架构原理

⼀个复制集中Primary节点上能够完成读写操纵,Secondary节点仅能⽤于读操纵。Primary节点必要记载所有改变数据库状态的操纵,这些记载生存在 oplog 中,这个⽂件存储在 local 数据库,各个Secondary节点通过此 oplog 来复制数据并应⽤于本地,保持本地的数据与主节点的⼀致。oplog 具有幂等性,即⽆论执⾏⼏次其结果⼀致,这个比mysql 的⼆进制⽇志更好⽤。
oplog的构成布局
  1. {
  2. "ts" : Timestamp(1446011584, 2),
  3. "h" : NumberLong("1687359108795812092"),
  4. "v" : 2,
  5. "op" : "i",
  6. "ns" : "test.nosql",
  7. "o" : { "_id" : ObjectId("563062c0b085733f34ab4129"), "name" : "mongodb", "score" :"10"}
  8. }
复制代码


  • ts:操纵时间,当前timestamp + 计数器,计数器每秒都被重置
  • h:操纵的全局唯⼀标识
  • v:oplog版本信息
  • op:操纵范例

    • i:插⼊操纵
    • u:更新操纵
    • d:删除操纵
    • c:执⾏命令(如createDatabase,dropDatabase)
    • n:空操纵,特殊⽤途

  • ns:操纵针对的集合
  • o:操纵内容
  • o2:更新查询条件,仅update操纵包含该字段
复制集数据同步分为初始化同步和keep复制同步。初始化同步指全量从主节点同步数据,假如Primary节点数据量⽐较⼤同步时间会⽐较⻓。⽽keep复制指初始化同步过后,节点之间的实时同步⼀般是增量同步。
初始化同步有以下两种环境会触发


  • Secondary第⼀次加⼊
  • Secondary落后的数据量凌驾了oplog的⼤⼩,如许也会被全量复制
MongoDB的Primary节点选举基于⼼跳触发。⼀个复制集N个节点中的任意两个节点维持⼼跳,每个节点维护其他N-1个节点的状态。
  1. ⼼跳检测:整个集群需要保持⼀定的通信才能知道哪些节点活着哪些节点挂掉。mongodb节点会向副本集中的其他节点每2秒就会发送⼀次pings包,如果其他节点在10秒钟之内没有返回就标示为不能访问。每个节点内部都会维护⼀个状态映射表,
  2. 表明当前每个节点是什么⻆⾊、⽇志时间戳等关键信息。如果主节点发现⾃⼰⽆法与⼤部分节点通讯则把⾃⼰降级为
  3. secondary只读节点。
复制代码
主节点选举触发的机会:


  • 第⼀次初始化⼀个复制集
  • Secondary节点权重⽐Primary节点⾼时,发起更换选举
  • Secondary节点发现集群中没有Primary时,发起选举
  • Primary节点不能访问到⼤部分(Majority)成员时主动降级
当触发选举时,Secondary节点尝试将⾃身选举为Primary。主节点选举是⼀个⼆阶段过程+多数派协议。


  • 第⼀阶段:
    检测⾃身是否有被选举的资格 假如符合资格会向别的节点发起本节点是否有选举资格的FreshnessCheck,进⾏同寅仲裁
  • 第⼆阶段:
    发起者向集群中存活节点发送Elect(选举)请求,仲裁者收到请求的节点会执⾏⼀系列合法性检查,假如检查通过,则仲裁者(⼀个复制集中最多50个节点 此中只有7个具有投票权)给发起者投⼀票。
    pv0通过30秒选举锁防⽌⼀次选举中两次投票。
    pv1使⽤了terms(⼀个单调递增的选举计数器)来防⽌在⼀次选举中投两次票的环境。
多数派协议:
发起者假如得到凌驾半数的投票,则选举通过,⾃身成为Primary节点。得到低于半数选票的缘故原由,除了常⻅的⽹络问题外,雷同优先级的节点同时通过第⼀阶段的同寅仲裁并进⼊第⼆阶段也是⼀个缘故原由。因此,当选票不⾜时,会sleep[0,1]秒内的随机时间,之后再次尝试选举。
5.3 分⽚集群 Shard Cluster

分⽚(sharding)是MongoDB⽤来将⼤型集合⽔平分割到差别服务器(或者复制集)上所采⽤的⽅法。不必要功能强⼤的⼤型盘算机就可以存储更多的数据,处理更⼤的负载
分片缘故原由


  • 存储容量需求超出单机磁盘容量。
  • 活跃的数据集超出单机内存容量,导致许多请求都要从磁盘读取数据,影响性能。
  • IOPS超出单个MongoDB节点的服务能⼒,随着数据的增⻓,单机实例的瓶颈会越来越显着。
  • 副本集具有节点数目限制。
扩展方式:


  • 垂直扩展:增长更多的CPU和存储资源来扩展容量。
  • ⽔平扩展:将数据集分布在多个服务器上。⽔平扩展即分⽚
5.3.1 ⼯作原理


分⽚集群由以下3个服务构成:


  • Shards Server: 每个shard由⼀个或多个mongod历程构成,⽤于存储数据。
  • Router Server: 数据库集群的请求⼊⼝,所有请求都通过Router(mongos)进⾏协调,不必要在应⽤程序添加⼀个路由选择器,Router(mongos)就是⼀个请求分发中⼼它负责把应⽤程序的请求转发到对应的Shard服务器上。
  • Config Server: 配置服务器。存储所有数据库元信息(路由、分⽚)的配置
概念


  • ⽚键(shard key):为了在数据集合中分配⽂档,MongoDB使⽤分⽚主键分割集合。
  • 区块(chunk):在⼀个shard server内部,MongoDB还是会把数据分为chunks,每个chunk代表这个shard server内部⼀部分数据。MongoDB分割分⽚数据到区块,每⼀个区块包含基于分⽚主键的左闭右开的区间范围
  • 分⽚计谋

    • 范围分⽚(Range based sharding)
      范围分⽚是基于分⽚主键的值切分数据,每⼀个区块将会分配到⼀个范围。
      范围分⽚得当满⾜在⼀定范围内的查找,例如查找X的值在[20,30)之间的数据,mongo 路由根据Config server中存储的元数据,可以直接定位到指定的shard的Chunk中。
      缺点: 假如shard key有显着递增(或者递减)趋势,则新插⼊的⽂档多会分布到同⼀个chunk,⽆法扩展写的能⼒

    • hash分⽚(Hash based sharding)
      Hash分⽚是盘算⼀个分⽚主键的hash值,每⼀个区块将分配⼀个范围的hash值。
      Hash分⽚与范围分⽚互补,能将⽂档随机的分散到各个chunk,充分的扩展写能⼒,补充了范围分⽚的不⾜,缺点是不能⾼效的服务范围查询,范围查询要分发到后端所有的Shard才能找出满⾜条件的⽂档。

    • 组合⽚键
      数据库中没有⽐较合适的⽚键供选择,或者是打算使⽤的⽚键基数太⼩(即变革少如星期只有7天可变革),可以选另⼀个字段使⽤组合⽚键,甚⾄可以添加冗余字段来组合。⼀般是粗粒度+细粒度进⾏组合。
    分片计谋的选择⽆⾮从两个⽅⾯思量,数据的查询和写⼊,最好的效果就是数据查询时能命中更少的分⽚,数据写⼊时能够随机的写⼊每个分⽚,关键在于怎样权衡性能和负载。

六.安全认证

MongoDB 默认是没有账号的,可以直接连接,⽆须身份验证。
MongoDB 服务端开启安全检查之前,⾄少必要有⼀个管理员账号,admin 数据库中的⽤户都被视为管理员假如 admin 库没有任何⽤户的话,纵然在其他数据库中创建了⽤户,启⽤身份验证,默认的连接⽅式依然会有超等权限,即仍旧可以不验证账号密码还是能进⾏ CRUD,安全认证相当于⽆效。
6.1 用户相关操纵

在为库添加的用户之前要先切换到该库下


  • ⽤户添加⻆⾊
    1. use admin;#切换到admin
    2. db.createUser(
    3. {
    4. user: "账号",
    5. pwd: "密码",
    6. roles: [
    7. { role: "⻆⾊(MonngoDB 已经约定好的⻆⾊)", db: "安全认证的数据库" },
    8. { role: "⻆⾊(MonngoDB 已经约定好的⻆⾊)", db: "安全认证的数据库" }
    9. ]
    10. }
    11. )
    复制代码
  • 修改密码
    1. db.changeUserPassword( 'root' , 'rootNew' );
    复制代码
  • ⽤户添加⻆⾊
    1. db.grantRolesToUser( '⽤户名' , [{ role: '⻆⾊名' , db: '数据库名'}])
    复制代码
  • 以auth启动mongod
    1. ./bin/mongod
    2. -f conf/mongo.conf --auth(也可以在mongo.conf 中添加auth=true 参数)
    复制代码
  • 验证⽤户
    1. db.auth("账号","密码")
    复制代码
  • 删除⽤户
    1. db.dropUser("⽤户名")
    复制代码
6.2 脚色



  • read:允许⽤户读取指定数据库(数据库⽤户⻆⾊)
  • readWrite:允许⽤户读写指定数据库(数据库⽤户⻆⾊)
  • dbAdmin:允许⽤户在指定数据库中执⾏管理函数,如索引创建、删除,检察统计或访问system.profile(数据库管理⻆⾊)
  • userAdmin:允许⽤户向system.users集合写⼊,可以在指定数据库⾥创建、删除和管理⽤户(数据库管理⻆⾊)
  • clusterAdmin:只在admin数据库中可⽤,赋予⽤户所有分⽚和复制集相关函数的管理权限(集群管理⻆⾊)
  • readAnyDatabase:只在admin数据库中可⽤,赋予⽤户所有数据库的读权限(所有数据库⻆⾊)
  • readWriteAnyDatabase:只在admin数据库中可⽤,赋予⽤户所有数据库的读写权限(所有数据库⻆⾊)
  • userAdminAnyDatabase:只在admin数据库中可⽤,赋予⽤户所有数据库的userAdmin权限(所有数据库⻆⾊)
  • dbAdminAnyDatabase:只在admin数据库中可⽤,赋予⽤户所有数据库的dbAdmin权限(所有数据库⻆⾊)
  • root:只在admin数据库中可⽤。超等账号,超等权限(超等⽤户⻆⾊)
  • dbOwner:库拥有者权限,即readWrite、dbAdmin、userAdmin⻆⾊的合体(数据库管理⻆⾊)
dbOwner 、userAdmin、userAdminAnyDatabase间接或直接提供了体系超等⽤户的访问
6.3 分⽚集群安全认证

和上面的操纵一样只是多一个密钥文件


  • 天生密钥文件
    1. openssl rand -base64 756 > data/mongodb/testKeyFile.file
    2. chmod 600 data/mongodb/keyfile/testKeyFile.file
    复制代码
  • 配置节点集群和分⽚节点集群开启安全认证和指定密钥⽂件
    1. auth=true
    2. keyFile=data/mongodb/testKeyFile.file
    复制代码
  • 在路由配置⽂件中 设置密钥⽂件
    1. keyFile=data/mongodb/testKeyFile.file
    复制代码
七.数据备份与规复

7.1 目标



  • 防止硬件故障引起的数据丢失
  • 防止人为错误误删数据
  • 时间回溯
  • 监管要求
7.2 实现方式



  • 文件体系快照
  • 复制数据文件
  • mongodump

7.3 mongodump

该命令可以导出所有数据到指定目录中。 mongodump命令可以通过参数指定导出的数据库或者集合。
  1. mongodump -h dbhost -d dbname -o dbdirectory
复制代码


  • -h:MongoDB所在服务器地点,例如:127.0.0.1或者127.0.0.1:37017
  • –db 或者 -d :必要备份的数据库,例如:testdb
  • –out 或者-o:备份的数据存放位置,例如:/root/bdatas 在备份完成后,体系主动在root目录下创建一个bdatas目录,这个目录内里存放该数据库实例的备份数据。
  • -c :和-d 一起利用,备份指定数据库的指定集合
  1. ./bin/mongod
  2. ump --host=192.168.211.136 --port=37017 -d local -c oplog.rs -o=/root/oplog_bak
复制代码
7.4 mongorestore

利用 mongorestore 命令来规复备份的数据。
  1. mongorestore -h <hostname><:port> -d dbname <path>
复制代码


  • –host <:port>, -h <:port>:
    MongoDB所在服务器地点,默以为: localhost:37017
  • –db 或者 -d :
    必要规复的数据库,例如:testdb,这个名称也可以和备份时候的不一样
  • –drop:
    规复的时候,先删除当前数据,然后规复备份的数据。
  • mongorestore
    设置备份数据所在位置,例如:/root/bdatas/testdb
    不能同时指定–dir 选项,–dir也可以设置备份目录。
    注意: 规复指定的数据库 必要在规复的路径中出现数据库的名字
  • –dir:
    指定备份的目录
  1. ./bin/mongorestore -h 127.0.0.1:37017 -d testdb /root/bdatas/testdb
复制代码
7.5 备份和规复的重要选项

mongodump有一个选项是 --oplog(replica set或者master/slave模式专用),
–oplog选项只对全库导出有用,所以不能指定-d选项
oplog有幂等性:已存在的数据,重做oplog不会重复;不存在的数据重做oplog就可以
  1. ./bin/mongod
  2. ump -h 127.0.0.1:37017 --oplog -o /root/bdatas
复制代码
mongorestore的–oplogReplay选项,可以重放oplog.bson中的操纵内容
–oplogLimit可以设置回放的时间节点,即此时间之前的数据规复,假设你后面有误操纵,误操纵的不规复
  1. mongorestore -h localhost:37017 --oplogReplay /root/dump
复制代码
通过 oplog 查询误操纵的末了时间
  1. /root/mongodb/bin/bsondump oplog.rs.bson | grep ""op":"d"" | head
复制代码
或者 利用
  1. db.oplog.rs.find({"op" : "d"}).sort({"ts":-1})
复制代码
  1. mongorestore -h localhost:37017 --oplogReplay --oplogLimit "1443024507:1" /root/dump/local
复制代码
7.6 定时备份



  • 准备备份目录
    1. mkdir -p /root/backup/mongod_bak/mongod_bak_now  /root/backup/mongod_bak/mongod_bak_list
    复制代码
  • 编写备份脚本
    1. vi /root/backup/mongobk.sh
    复制代码
    1. #!/bin/sh
    2. # dump 命令执行路径,根据mongodb安装路径而定
    3. DUMP=/root/mongodb/bin/mongodump
    4. # 临时备份路径
    5. OUT_DIR=/root/backup/mongod_bak/mongod_bak_now
    6. # 压缩后的备份存放路径
    7. TAR_DIR=/root/backup/mongod_bak/mongod_bak_list
    8. # 当前系统时间 DATE=`date +%Y_%m_%d%H%M%S`
    9. # 数据库账号
    10. # DB_USER=user
    11. # 数据库密码
    12. # DB_PASS=password
    13. # 代表删除7天前的备份,即只保留近 7 天的备份 DAYS=7
    14. # 最终保存的数据库备份文件
    15. TAR_BAK="mongod_bak_$DATE.tar.gz"
    16. cd $OUT_DIR rm -rf $OUT_DIR/*
    17. mkdir -p $OUT_DIR/$DATE
    18. $DUMP -h 127.0.0.1 --port 37017 -o $OUT_DIR/$DATE
    19. # 压缩格式为 .tar.gz 格式
    20. tar -zPcvf $TAR_DIR/$TAR_BAK $OUT_DIR/$DATE
    21. # 删除 7 天前的备份文件 find $TAR_DIR/ -mtime +$DAYS -delete
    22. exit
    复制代码
  • 修改脚本权限
    1. chmod +x /root/backup/mongobk.sh
    复制代码
  • 编辑crontab
    1. crontab -e
    复制代码
    1. #表示每天凌晨2点30执行备份
    2. 30 2 * * * /root/backup/mongobk.sh
    复制代码
  • 检察crontab 的状态
    1. service crond status
    复制代码
  • 假如没有启动 可以利用下面的命令 启动定时服务 和参加开机自启动
    1. # 启动定时任务
    2. service crond start
    3. # 加入开机自动启动
    4. chkconfig --level 35 crond on
    复制代码
  • 检察定时任务和删除定时任务
    1. crontab -l
    2. crontab -r
    3. crontab -e
    复制代码

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

耶耶耶耶耶

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表