mongo的基本整理

mongo

mongo的基本命令

db.help() 查看db命令帮助

rs.help() // 在mongod中执行

sh.help() // 数据库分片的相关指令,需要在mongos中执行。

db.listCommands() // mongo的所有的命令都可以使用 db.runCommand()执行

db.adminCommand({getParameter:"*"}) // 查看服务器的当前配置参数。 db.adminCommand({setParameter:1, enableFlowControl: false}) 可以修改对应的值,这里修改的是enableFlowControl设置为false.

mongo分片

shard 命令

sh.status()

sh.isBalancerRunning()

sh.enableSharding()

sh.shardCollection()

Sharded Cluster

  • shard: 分片,一般每个分片由一个副本集构成。
  • mongos: 一般处理query路由器。提供client和 sharded cluster 接口
  • config servers : 存储元数据和config文件

主分片primary shard

在sharded cluster中,每个数据库都会设置主的shard,也就是如果这个数据库中的表没有启用分片,默认数据全部在这个分片。类似普通的副本集。

如果启动了分片,数据会依据分片的片键分布在多个shard中。

片键

sharded cluster的集合如果启用了分片,需要设置指定的分片的片键,数据会依据片键分配到不同的shard中。片键需要考虑的至少有三个方面分片建的基数,平率,单调性。

  • 分片建的基数,如果分片建只有4个值,最多可以创建4个分片,再多的分片没有用,不会有数据路由上去。
  • 分片建的频率,如果数据绝大数都是某个建值数据,那么就会造成数据然后绝大多数都在一个分片上,不能均匀分配。
  • 分配的单调性,如果单调增减的数据,可能由于一个范围的数据被分配到一个分片,如时间戳分片,那么一个时间段只会在一个分片上,此时相当于单分片写入。

mongoDB 副本集相关问题。

mongo 副本集命令

rs.status() // 查看mongo副本集状态.

rs.config() //查看副本集的配置,可以获取 writemajority的数目,副本节点的投票权等配置信息

rs.add("host:port") // 加入节点。

rs.remove("host:port") // 移除节点。

rs.addArb("host:port") // 加入仲裁节点

var config = rs.config() // 修改副本集的配置方法
config.members[1].priority=100 // 设置投票的优先级为 100
rs.reconfig(config) // 重新配置config

rs.printSecondaryReplicationInfo() // 查看从节点的oplog状态

rs.printReplicationInfo() // 查看节点的oplog信息

mongo oplog

mongo oplog是一个特殊的集合,保存mongo的滚动的记录。 集合local.oplog.rs 。 oplog的大小默认是磁盘的5%,最大不超出50GB。

mongo的 readConcern https://docs.mongodb.com/v4.2...

mongo副本集节点

mongo副本集节点种类

  1. primary 主节点,负责读写。写入Oplog,提供给secondary同步修改。
  2. secondary节点,主要是用来备份主节点的数据,同步数据syschost 来源可以是主节点,也可以是另外一个从节点。当然如果你配置了读写分离,也会负责读。一般不特别配置,默认都是不做读。
  3. hidden 副本节点,隐藏节点,客户端看不见的节点。不能进行读,也不会成为primary。
  4. 延迟节点。设置一个节点,允许和主节点存在一定时间的延迟。一般不使用。
  5. 仲裁节点,只参与投票,但是不会进行读写。几乎不会有资源的消耗。但是如果一个副本集是 主--> 从 ---> 仲裁,三个节点构成的副本集,如果一个主,或者从节点挂掉。就会变得只有主 --> 仲裁,导致无法写入majority。触发flowcontrol严重降低写入速度。可以通过调大flowcontrol,或者先把flowcontrol设置为false。

mongo write majority, read majority
majority大多数是多少,所有的可以投票节点的一半以上。

副本集的flowControl机制

mongodb副本集写入时默认是写入majority,(1 + 节点数的一半。 3个节点时,majority=2),如果P (primary) -- S (secondary) --A (arbiter), P ,S有一个节点挂掉或者从节点性能问题,严重落后主节点,会导致写入不足2个节点。然后新的P节点就会触发flowcontrol机制,限制写入,等待从节点赶上。有时为了让mongo先恢复写速度,可以调节参数。

db.adminCommand({setParameter:1, flowControlMinTicketsPerSecond:10000}) // 可以调大flowcontrol的漏洞的ticket的数目,

db.adminCommand({setParameter:1, enableFlowControl: false}) // 不行就直接关闭flowControl。

关于w:majority. 按道理说,服务器默认的写入是majority(rs.conf() 查看),那么为什么没有触发客户端的等待呢?在客户端强制设置w:majority时,客户完全hang请求(达不到w:majority时)。rs.conf()
"getLastErrorDefaults" : {

 "w" : 1,
 "wtimeout" : 0
 }

"writeConcernMajorityJournalDefault" : true, 这个字段表示的是,如果客户端写入为majority但是没有设置journal.那么默认也要等待写入journal。
getLastErrorDefaults 表示写入的确认个数,和等待时间。

{ w: <value>, j: <boolean>, wtimeout: <number> } // 在客户端指定写入为majority时,设置了超时时间,就算返回超时,没有达到大多数。也是成功写入了数据的。

mongo问题

mongo目前4.0+版本的默认存储引擎使用的wiredTiger存储引擎。mongo绝大数的问题可能都是需要调优wiredTiger.

wiredTiger

  1. wiredTiger是一个文档级别的并发控制,允许同一时间修改同一个集合的不同文档。
  2. wiredTiger使用mvcc版本控制,所有的数据提供一个修改的快照snapshot,每隔一段时间将所有的快照写入,作为一个checkpoint(数据恢复点)。
    同一时间只会有一个有效的checkpoint。最新的生成,删除上一个。4.0+每60s生成一个checkpoint。
  3. jounal日志,类似mysql的redo log。保存checkpoint执行的数据修改。如果在新生成的checkpoint执行,mongo出现宕机,可以通过最后的有效的checkpoint和jounal重放,把数据进行恢复。

wiredTiger的tcmalloc

wiredTiger使用tcmalloc作为申请内存的组件。tcmalloc申请内存会在主机内部缓存起来,类似与内部维护一个内存池,不必每次从操作系统申请内存,开销小。但是问题是tcmalloc内存的释放的速度不可控,容易造成内存内存的free buffer过大,却没有还给操作系统。导致oom,mongo被kill。

可以通过db.serverStatus().tcmalloc查看tcmalloc内存的使用情况。

tcmalloc提供了释放速度字段来调节缓存的释放速度tcmallocReleaseRate,从0-9,0表示永不释放,默认是1,也不是越大越好释放越快,也就和原始的malloc没有什么区别了。如果可以设置为中间值,然后观察性能吧。

mongo命令 : db.adminCommand({setParameter:1, tcmallocReleaseRate:4})

wiredTiger配置

  • wiredTigerConcurrentReadTransactions
    允许并发读取的最大值,默认128,当压力大时,可以设置调大,一般不调节。
    db.adminCommand( { setParameter: 1, wiredTigerConcurrentReadTransactions: <num> } )
  • wiredTigerConcurrentWriteTransactions
    并发写最大数,默认128

    可以查看: db.serverStatus().wiredTiger.concurrentTransactions

    例子:

    {
     "write" : {
     "out" : 0,
     "available" : 128,
     "totalTickets" : 128
     },
     "read" : {
     "out" : 3,
     "available" : 125,
     "totalTickets" : 128
     }
    }

    如果读写的available值为0,说明有有排队,可以把值调大一些。

  • wiredTiger cacheSize
    通过db.serverStatus().wiredTiger.cache 查看maximum bytes configured字段,为当前服务器的cachesize。如果需要调整,动态不重启调整
    db.adminCommand({setParameter:1, wiredTigerEngineRuntimeConfig:'cache_size=600M'}) ,重启时失效. 也可以在mongo的配置文件修改,然后重启永久生效。

wiredTiger的cache淘汰和checkpoint

wiredTiger

  • checkponit,每一段时间给dirty脏页(和集合的文件不一致),生成一个快照,也就是数据持久化点。如果mongo重启,会读取最新的持久化点,恢复之前的状态。(checkponit每60秒触发一次)
  • journal日志,mongo的修改预写日志,每100ms写入一次。如果mongo异常关闭,mongo读取最新的checkpoint和重放journal日志进行数据恢复。恢复到宕机之前的状态。
  1. wiredTiger页面类型

    • 内存页面 磁盘页面解压,处理成内存的page格式。
    • 磁盘页面 磁盘页面是内存页面经过处理,并压缩而成的(reconcile)。磁盘页面可以直接输入磁盘。
  2. 脏页类型

    • 完全脏页: 页面内的数据全部都是完全提交的数据,和被覆盖的数据。刷盘时,删除覆盖数据(数据被多次修改,以前的提交已经不会被任何事务看见的数据),将最新的数据页面reconcile成磁盘页面刷盘。(这类肯定很少)
    • 不完全脏页: 除了完全提交,还有未完全提交,只有部分事务可见的数据。刷盘时,删除覆盖数据,将提交的数据刷盘,但是页面保留modify部分。
  3. 缓存淘汰机制
    eviction_target 80 当 cache used 超过 eviction_target,后台evict线程开始淘汰 CLEAN PAGE
    eviction_trigger 95 当 cache used 超过 eviction_trigger,用户线程也开始淘汰 CLEAN PAGE
    eviction_dirty_target 5 当 cache dirty 超过 eviction_dirty_target,后台evict线程开始淘汰 DIRTY PAGE
    eviction_dirty_trigger 20 当 cache dirty 超过 eviction_dirty_trigger, 用户线程也开始淘汰 DIRTY PAGE

mongo每次到达checkpoint时,dirty数据量大,导致一次生成的checkpoint数据过高。如果100G的cache,dirty 5%,大概每次要刷5G进入磁盘。(不确定,mongo dirty小于5%时也会淘汰吗?)
当dirty大于5%时,eviction线程开始淘汰脏页,刷盘。尽量使每次checkpoint刷盘的数据尽可少。
当dirty大于20%时,用户线程暂停业务处理,先协助处理evict dirty page。此时业务的性能基本都很低。

内存使用低(默认配置时,cache 使用小于87.5%,或者dirty小于17.5%)
对于完全页面直接调和成磁盘页面刷盘,并将干净page页面加入LRU,提供驱逐。
对于不完全页,将能持久化的页面刷盘,不能删除的保留。只能释放其中的脏页modify的部分内容释放。

内存使用高
对于完全脏页面直接调和成磁盘页面刷盘,然后删除内存page。释放内存
对于不完全脏页,将能持久化的页面刷盘,不能删除的保留。只能释放其中的脏页modify的部分内容释放。

P-S-A (主从,仲裁)
如果一个数据节点延迟或者挂掉。导致无法满足w:majority.触发flowcontol.同时也触发了r:majority https://docs.mongodb.com/v4.2...
那么导致所有的修改,不会得到确认,属于脏数据。导致数据提交点不会被提前。导致每次做checkponit都会将之前的数据重新做。也就导致checkponit的负担也来越重。一般被确认的数据后续会刷入具体的collection文件,但是未被确认的数据会一直在checkpoint中。在PSA架构中,尽量把r:majority关掉。不然延迟就会导致触发 r:majority问题。

wiredTiger问题

  • wiredTiger的缓存脏缓存占比。dirty过高会导致业务的线程参与页面淘汰。业务线程就会hang住了。

参考资料

mongo权威指南第二版

https://docs.mongodb.com/v4.2... // mongo serverStatus部分

问题参考

mongo数据库恢复官方方案:

  1. https://docs.mongodb.com/v4.2... 单机版
  2. https://docs.mongodb.com/v4.2... // 副本集

mongo jira 可以查询或者提相关问题

https://jira.mongodb.org/brow...

mongo社区

https://www.mongodb.com/commu...

问题

  1. mongo日志中出现 "serverStatus was slow"
    一般是服务器负载过重,cpu、或者磁盘。 mongo在没有明显延迟的情况下无法相应命令状态。
    参考: https://www.mongodb.com/commu...

wiredTiger参考

https://www.percona.com/blog/... (checkpoint,和脏页的调优)

一篇机器翻译的wiredTIger文章
https://blogs.vicsdf.com/arti...

内存evict:
https://www.bookstack.cn/read...

https://www.freeaihub.com/pos...

readConcern:
https://www.bookstack.cn/read...

https://docs.mongodb.com/manu...

https://developer.aliyun.com/...

https://www.cnblogs.com/xibuh... // wiredTiger缓存模型

oppo mongodb优化分享

分享的挺好的

  1. https://zhuanlan.zhihu.com/p/...
  2. https://zhuanlan.zhihu.com/p/...
作者:结义原文地址:https://segmentfault.com/a/1190000042282880

%s 个评论

要回复文章请先登录注册