MongoDB必知必会(更新中)

1.用户管理

db.createUser(
   {
     user: "",
     pwd: "",
     roles: [ { role: "root", db: "admin" } ]
   }
 )
mongo --port 27017 -u'' -p'' --authenticationDatabase 'admin' --eval "use admin;db.createUser({user:\"r\",pwd:\"\",roles:[{role:\"clusterMonitor\",db:\"admin\"},{role:\"read\",db:\"local\"}]})"

db.updateUser("admin",{roles:[ {role:"root",db:"admin"} ]})

db.grantRolesToUser(
    "mongodb_exporter",
    [
      { role: "clusterMonitor", db: "admin" },{ role: "read", db: "local" },{ role: "read", db: "game" },{ role: "read", db: "common" }
    ]
)

#创建自定义角色

```sql

```javascript

#语法:

dbcreateRole(
{
role:"<name>",
privileges:[
{resource:{<resource>},actions:["action",]}
],
roles:[
{role:"<role>",db:"<database>"}|"<role>"
],
authenticationRestrictions:[
{clientSource:["<IP 地址>"|"<CIDR range>",],
{serverAddress:["<IP 地址>"|"<CIDR range>",]}
]
}
)

其中,resource为指定数据库或者集合,若设置为空,则默认当前数据库的全部集合。

actions:指定权限

use admin

dbcreateRole(
{
role:"role_yeyz",
privileges:[
{resource:{db:"yeyz",collection:"test"},
actions:["find","insert","update"]
}
],
roles:[
{role:"read",db:"yeyz1"}
]
}
)

 dbcreateUser(
{
user: "yeyz_1",
pwd: "123456",
roles: [ { role: "role_yeyz", db: "admin" }]
}
)

2.集群管理&监控

#设置占有内存大小
db.adminCommand({setParameter: 1, wiredTigerEngineRuntimeConfig: "cache_size=52G"})
#刷脏比例调整
db.adminCommand( { "setParameter": 1, "wiredTigerEngineRuntimeConfig": "eviction_dirty_target=1,eviction_dirty_trigger=40"})
db.adminCommand({setParameter: 1, wiredTigerEngineRuntimeConfig: "eviction=(threads_min=2,threads_max=8)"})

#初始化副本集
cfg={_id :"gz",configsvr: true,members:[{ _id: 0, host: "" },{ _id: 1, host: "" },{ _id: 2, host: "" }]}
rsconf = {
   _id: "gamemongo",
   members: [
     {
      _id: 0,
      host: ":27017",
  "priority":3
     },
     {
      _id: 1,
      host: ":27017",
  "priority":1
      },
      {
      _id: 2,
      host: ":27017",
  "priority":1
      }
     ]
 }
rs.initiate(cfg)
#调整优先级
cfg = rs.conf()
cfg.members[0].priority = 3
rs.reconfig(cfg)
#成员增减
rs.add('127.0.0.1:20001');
rs.remove()
#日志轮转
use admin
db.runCommand({ logRotate :1 } )
#慢查询阈值
db.setProfilingLevel(1,{slowms:800})

#查看执行时间较长的操作
db.currentOp({"active" : true,"secs_running" : { "$gt" : 2000 }});
#关闭节点
db.shutdownServer({timeoutSecs: 60});

#查看连接数
db.serverStatus().connections;

#查看执行操作时间较长的动作
db.currentOp({"active" : true,"secs_running" : { "$gt" : 2000 }});

3.数据操作

#索引操作
db.gameUser.createIndex({"expiretime" : 1},{ background: true, expireAfterSeconds: 86400, name: "gameUser_expiretimeIndex"})
db.gameUser.dropIndex("gameIdAndUserIdIndex")
db.gameUser.createIndex({"gameId" : 1,"userId" : 1 },{unique:true, background: true, name: "gameIdAndUserIdIndex"})
#查看最新的数据记录
db.game.find().sort({"created": -1}).limit(1)
#查看oplog最新数据
db.oplog.rs.find().sort({"created": -1}).pretty().limit(1)
#时间范围查询
db.game.find({"$and":[{"created":{"$gt":ISODate("2021-07-20T14:23:00")}},{"created":{"$lt":ISODate("2021-07-20T14:30:00")}}]}).sort({"created": -1})    
#导出索引
// 当前脚本名为exportImportIndexes.js
let joinStr = "*_*";

// 查询所有表的索引
function findAllIndexes() {
    // 获取所有表
    let allCollections = db.getCollectionNames();
    for (var colName of allCollections) {
        let indexes = db.getCollection(colName).getIndexes();
        // 输出表索引信息
        print(colName, joinStr, JSON.stringify(indexes));
    }
}
findAllIndexes();
mongo -u'' -p'' --authenticationDatabase 'admin' localhost:port/dbname index_find.js >index.log



var collectionList = db.getCollectionNames();
for (var index in collectionList) {
    var collection = collectionList[index];
    var cur = db.getCollection(collection).getIndexes();
    if (cur.length == 1) {
        continue;
    }
    for (var index1 in cur) {
        var next = cur[index1];
        if (next["key"]["_id"] == '1') {
            continue;
        }
print(" db.getCollection(\"" + collection + "\").ensureIndex(" + JSON.stringify(next.key) + ",{background:1, unique:" + (next.unique || false) + "" + (next.expireAfterSeconds > 0 ? ", expireAfterSeconds :" + next.expireAfterSeconds: "") + " })"
        )
    }
};



#mongo导出数据

./mongodump -u -p'' -h127.0.0.1:port --authenticationDatabase admin -o /data/dump
--excludeCollection 不导出某个库

对数据排序后导出csv文件

mongoexport -h 127.0.0.1:27017 -d NBSPRC -c town --sort {'code':1} --type=csv -f code,name,link -o town.csv
  • -h 数据地址:端口
  • -c 数据库集合名称(表名称)
  • –sort 对查询结果按照某个字段进行排序
  • –type=csv 指定查询结果输出格式,csv或者json
  • -f 指定查询结果要输出的字段
  • -o 输出文件名称

在这里插入图片描述

#导入数据
./mongorestore --port  -u -p''  --authenticationDatabase admin -d test /data/dump/

在这里插入图片描述

4.Mirrored Reads

主库复制一定比例的读流量到从库,一定程度避免主从切换后 新主上大量的cache miss

db.adminCommand( { setParameter: 1, mirrorReads: { samplingRate: 0.10 } } )

5.内存占用&释放

5.1 连接和请求占⽤的内存

如果实例的连接数很⼤,可能会消耗⼀部分的内存,原因如下:
每个连接,后端都有对应处理这个连接上的请求的线程。每个线程最多可以开销1MB的线程栈,通常情况下在几十KB~几百KB。
每个TCP连接在内核层⾯有读缓冲区和写缓冲区,由TCP内核参数tcp_rmem和tcp_wmem等确定,这块的内存使⽤⽤户⽆需关⼼。但并发连接越多,默认套接字缓存越⼤,则TCP占⽤内存越⼤。
每接收到⼀个请求,会有个请求上下⽂,整个过程中可能分配很多临时缓冲区,⽐如请求包、应答包和排序的临时缓冲区等,这些在请求结束时都会释放,但这个释放只是归还给内存分配器 tcmalloc,tcmalloc优先会还到⾃⼰的cache⾥,然后逐步再归还给操作系统。
很多情况下,内存使⽤率⾼的原因是tcmalloc未及时归还内存⾄操作系统,这⼀块最⼤可能达到几十GB。

db.serverStatus().tcmalloc

tcmalloc cache = pageheap_free_bytes + total_free_bytes

5.2 创建索引过程中的内存消耗

正常的业务数据写⼊情况下,Secondary节点会维持⼀个最⼤约256M的buffer⽤于数据回放。在创建索引方面,当Primary节点创建索引完成后,Secondary节点回放过程中可能消耗更多的内存。
Secondary节点并行回放创建索引,那就会消耗更多的内存,多个索引同时创建时可能导致实例内存溢出。

5.3 引擎内存

db.serverStatus().wiredTiger.cache

bytes currently in the cache后的值为内存大小

6.cpu占用过高

6.1扫描⾏数过多

MongoDB为多线程应⽤,如果存在单个查询扫描⾏数过多,该查询所在线程的CPU占⽤时间会变⻓

1 全表扫描

当在 system.profile集合或者运⾏⽇志⽂件发现COLLSCAN关键字时,就表示该查询进行了全表扫描。通过添加索引的方法优化,如果当前已不能使用该方法,则在业务侧控制该表的数据量和执行频率。

2.索引设计和优化

除了全表扫描以外,当查询的扫描行数关键字docsExamined超过1000且执行频率较高时,我们需要关注该查询。除了全表扫描以外,造成docsExamined过多⼀般有以下情况:

  • 多条件过滤时,未使⽤组合索引或不满⾜最左前缀匹配原则。
  • 未使⽤索引做排序操作。
  • 查询过于复杂,或者存在⼤量的聚合类操作,基本⽆法从索引层⾯做到极致优化,或者导致查询⾛错解析计划。
  • 数据列的数据选择性和运⾏频率的评估错误,未能做到最好的折中。

针对以上问题的更多信息,请参见以下官⽅⽂档:

  • 组合索引的原理和使⽤⽅法,详情请参见:https://docs.mongodb.com/manual/core/index-compound/。
  • 使⽤索引排序,详情请参见:https://docs.mongodb.com/manual/tutorial/sort-results-with-indexes/。
  • 使⽤Hint固化执⾏计划,详情请参考:https://docs.mongodb.com/manual/reference/operator/meta/hint/和https://docs.mongodb.com/manual/reference/method/cursor.hint/。
  • 索引的数据选择性和运⾏频率折中⽅法,详情请参见:https://docs.mongodb.com/manual/tutorial/create-queries-that-ensure-selectivity/。

6.2并发过大

如果确认查询层⾯没有问题,那么引起实例CPU占用高的可能原因为业务并发过⾼。如果是由于业务请求量过⼤,并发过⾼导致了CPU占用高的问题

  • 单实例垂直配置升降级,使得单实例能够承载更多的读写量。
  • 配置副本集层⾯的读写分离,或者添加该副本的只读实例。
  • 升级⾄MongoDB分⽚集群,通过数据⽔平拆分的⽅式横向,线性扩展系统性能。
  • 如果是Mongos路由节点CPU占满,则直接添加Mongos节点个数并设置Mongos节点的负载均衡。

7.io过高

  • 内存不够。I/O问题与内存的CacheSize⼤⼩息息相关。CacheSize越⼤,表示能够缓存的热数据越⼤
  • 与磁盘I/O相关的参数和配置问题。例如MongoDB Journal和运⾏⽇志频繁刷新,写入安全机制(WriteConcern)设置不合理,分⽚集群的MoveChunk错误等。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值