《万亿级数据库MongoDB集群性能数十倍提高优化实践》核心17问详细解答
说明:
为了更好的理解背景,请提早阅读oschina分享的《万亿级数据库MongoDB集群性能数十倍提高及机房多活容灾实践》一文。html
本文是2020年深圳Qcon全球软件开发大会《专题:现代数据架构》专场、dbaplus专场:万亿级数据库MongoDB集群性能优化实践、mongodb2020年终盛会分享后,得到一致好评。本文收集了会后众多mongodb用户提的比较频繁的17个问题,并对每一个问题进行了详细解答,一并整理到本文中。前端
分享内容回顾以下:node
- MongoDB在OPPO互联网推广经验分享-如何把一个淘汰边缘的数据库逐步变为公司主流数据库
- 谈谈当前国内对MongoDB误解(丢数据、不安全、难维护)?
- MongoDB跨机房多活方案-实现成本、性能、一致性"三丰收"
- MongoDB线程模型瓶颈及其优化方法
- 并行迁移:MongoDB内核扩容迁移速率数倍/数十倍提高优化实践
- 百万级高并发读写/千亿级数据量MongoDB集群性能数倍提高优化实践
- 万亿级数据量MongoDB集群性能数十倍提高优化实践
- 磁盘80%节省-记某服务接口千亿级数据迁移MongoDB,近百台SSD服务器节省原理
关于做者
前滴滴出行技术专家,现任OPPO文档数据库mongodb负责人,负责数万亿级数据量文档数据库mongodb内核研发、性能优化及运维工做,一直专一于分布式缓存、高性能服务端、数据库、中间件等相关研发。后续持续分享《MongoDB内核源码设计、性能优化、最佳运维实践》,Github帐号地址:https://github.com/y123456yzmysql
- 性能优化有推荐的分析和监控工具么?
mongodb经常使用性能分析主要以下:ios
1.1 mongodb自带性能分析工具
mongodb官方对外工具mongostatgit
命令行使用方法(ip:port为代理ip和端口):github
mongostat -h ip:port -u用户名 -p密码 --authenticationDatabase=admin --discoversql
mongostat工具带上--discover,能够把全部分片节点信息一块儿打印出来,直观查看整个集群全部节点实例级监控信息。mongostat统计信息中最核心的几个影响性能的统计项:mongodb
- dirty:存储引擎脏数据比例,默认该值为5%的时候,wiredtiger存储引擎自带的evict现成开始选择脏数据page淘汰到磁盘;若是该值达到20%,客户端请求对应mongodb处理现成将会选择脏数据page淘汰到磁盘,等page淘汰腾出内存空间后,才会处理客户端请求的DB访问,因此若是阀值达到20%客户端访问将会变慢。
- used:存储引擎cacheSize配置占用百分比,若是配置cacheSize=10G,存储引擎实际使用了7G,则used赞比为70%。当该统计值达到80%,evict线程将会触发选择涨数据淘汰,若是这个占比提升到95%,用户请求线程将会触发淘汰,客户端请求将会变慢。
- qrw arw:等待队列数,若是该值越大,说明会引发客户端请求排队处理。通常该值会再dirty占比超过20%,used占比太高超过95%,或者磁盘IO慢会出现。
- vsize res:虚拟内存和物理内存真实占用,若是vsize太高,远远超过res,或者res太高,远远超过cachesize配置,则说明内存碎片,pageheap等问题,这时候能够经过加速tcmalloc内存释放速率来解决问题。
- 慢日志分析
经过如下命令分析日志文件数据库
1)找出文件末尾1000000行中存在扫表的操做,不包含oplog,getMore
tail mongod.log -n 1000000 | grep ms |grep COLLSCAN |grep -v "getMore" | grep -v "oplog.rs"
2)找出文件末尾1000000行中全部的慢日志,不包含oplog,getMore
tail mongodb.log -n 1000000 |grep ms | grep op_msg | grep find | grep -v "oplog.rs" |grep -v "getMore"
3.)找出文件末尾1000000行中执行时间1-10s的请求,不包含oplog,getMore
tail mongodb.log -n 1000000 |grep ms | grep op_msg | grep find | grep -v "oplog.rs" |grep -v "getMore" | egrep [1-9][0-9][0-9][0-9]ms
4)currentOp正在执行的慢操做分析
慢日志只有当请求执行完毕才会,若是一个表很大,一个查询扫表,则整个执行过程可能须要数小时,可能还没记录慢日志,则能够经过以下命令获取当前执行时间超过5s的全部请求,查询请求,command请求:
db.currentOp({"secs_running":{"$gt":5}})
db.currentOp({"secs_running":{"$gt":1}, "op":"query"})
db.currentOp({"secs_running":{"$gt":5}, "op":"command"})
kill查询时间超过5s的全部请求:
db.currentOp().inprog.forEach(function(item){if(item.secs_running > 5 )db.killOp(item.opid)})
- 节点存储引擎监控信息
db.serverStatus().wiredTiger能够获取mongod节点对应存储引擎的各自详细统计信息,里面能够完整获取时延消耗在存储引擎哪个环节。
下面是空余时间分析的wiredtiger源码,分析不是很完整,后续等mongodb server层单机、复制集、分片等完整模块化分析后,会回头继续分析。
1.2 操做系统性能瓶颈分析
系统层面性能分析工具主要有:top、iostat、pstak、ptress、perf、iotop、isof等,具体请参考对应工具说明。
1.3 开源mongodb详细监控套记
开源方案能够参考如下组件:
Grafana+Prometheus+node_exporter+mongodb_exporter
- 服务端组件:
Prometheus #服务端
Grafana #前端展现 - 客户端组件:
node_exporter
mongodb_exporter
2. 会话加标签是怎么指定服务器?
举一个例子形象说明:咱们把用户分为三组,20 岁如下(junior),20 到 40 岁(middle)和 40 岁以上(senior),按照下面的几条命令执行之后,咱们的数据会按照用户年龄段拆分红若干个 chunk,并分发到不一样的 shard cluster 中。
若是对下面的命令不熟悉,能够查看 MongoDB 官方文档关于 Shard Zone/Chunk 的解释。
sh.addShardTag('shard01', 'junior')
sh.addShardTag('shard02', 'middle')
sh.addShardTag('shard03', 'senior')
sh.addTagRange('test.users', {'user.age': MinKey}, {'user.age':20}, 'junior')
sh.addTagRange('test.users', {'user.age': 21}, {'user.age':40}, 'middle')
sh.addTagRange('test.users', {'user.age': 41}, {'user.age': MaxKey}, 'senior')
经过上面的6个命令给'test库的user表加标签,20如下对应标签为'junior',21-40对应标签为'middle',41以上对应标签为'senior'。同时把'junior'标签分配给'shard01',也就是0-20岁的user会所有写到'shard01',21-40岁的user会所有写到'shard01',41岁以上的user会所有写到'shard01'。
这样就能够解决跨机房写的问题,只要对应分片主节点在对应机房便可。
3. 脏数据比例多少算高?
默认20%算高,若是脏数据比例持续性超过20%,能够试着提升wiredtiger存储引擎后台淘汰线程数:
db.adminCommand( { setParameter : 1, "wiredTigerEngineRuntimeConfig" : "cache_size=35GB, eviction=(threads_min=4, threads_max=12)"})
4. 写分开,会有时延吗,是否是有一致性问题?
一致性默认彻底由mongodb复制集自带的主从同步机制来保证最终一致性,不存在双向同步两集群的一致性问题。
若是要实现复制集中主从节点的强一致性,能够经过客户端配置writeconcern策略来解决。
5. 好比想定位详细的慢查询呢?
和问题1雷同,能够经过分析currentop、日志文件或者system.profile慢日志表来获取详细的慢日志信息。建议平台化收集慢日志,这样界面展现分析更加直观。
6. 如何快速定位Mongodb的问题发生在集群中的哪些节点? 在启用读写分离的状况下?
主要经过以下几个步骤来分析:
- db.serverStatus().opLatencies监控mongod实例时延
- 若是由运维研发能力,能够本身收集时延展现,若是没有。则能够借助开源工具系统实现,参考《1.3 开源mongodb详细监控套记》
- 充分利用mongostat监控集群全部节点实时脏数据、队列、内存信息
- 参考《1.1 mongodb自带性能分析工具》
- 慢日志分析, 参考《好比想定位详细的慢查询呢?》
7. 杨老师,就您经验来说,您以为如何保证MongoDB 的安全性呢?
安全性方面主要由如下几方面保证:
- 帐号鉴权认证,一个库一个帐号
- readWrite权限去除删库、删表等危险操做权限
- 不一样业务不混用同一个集群
- 启用黑白名单功能
- 我司mongodb内核增长审计、流量控制、危险操做控制等功能(注:部分功能是mongodb企业级功能,须要付费,可使用percona mongodb版本)
- 数据按期备份,我司mongodb内核增长有热备功能。
注意:若是数据量很大,建议不要使用mongodump备份,mongodump备份会很慢,同时经过mongorestore恢复也是一条数据一条数据恢复,一样很慢。若是有内核研发能力,能够增长热备功能。若是没有内核研发能力,能够经过以下步骤备份:1. 隐藏节点;2. 锁库;3. 拷贝数据文件。或者采用percona mongodb版原本备份。
8. mysql和mongodb双写的话怎么保证事务呢
mysql我不是很了解,mongodb不推荐搭两集群双向同步来备份,直接利用mongodb原生的复制集功能来完成多活容灾,成本、性能、一致性均可以获得保证。即便是4.2分布式事务功能也能够直接利用mongodb自身的机制来保证,具体方案参考我在Qcon全球软件开发大会的分享:
9. hashnum 的方式来说数组中的方式来拆分红多个表? 没太明白
分享的案例2:万亿级数据量mongodb集群性能数倍提高优化实践,不是拆分数据到多个表,而是把一条数据(该数据保护一个数组,数组中包含数百万个子文档)经过hash的方式散列为多条数据。也就是以前数百万个子文档归属于一条数据,如今把他拆分为归属到多条数据。
经过这样合理的数据合并和拆分,最终平衡磁盘IO,实现读和写达到一种平衡态,既能知足业务读需求,同时也能知足业务写需求。
10. 对分片键设计要求高吗?
分片集群片建选择很是重要,对分片模式集群性能起着核心相当重要的做用,分片集群片建选择遵循如下几个原则:
11. 首先须要考虑集群部署是否须要分片?
只有如下状况才须要分片功能:1. 数据量太大,一个分片撑不住;2. 写流量太大,写只能走主节点,一个主节点撑不住,须要扩分片分担写流量。
12. 片建选择原则?
片建选择原则以下: 1. 保证数据尽可能离散;2. 尽可能保证更新和查询到同一个分片(若是同一次更新或者查询到多个分片,只要任何一个分片慢,该操做都会慢;同时部分查询会进一步加重代理聚合负担)。
此外,若是查询注意是范围查询,建议选择范围分片,这样有利于范围数据集中到同一个分片。
13. 大表分片后,写表仍是会跨机房吗?
机房多活打标签方式解决跨机房写问题,一样能够对对应tag表启用分片功能,保证数据到指定的多个分片,每一个分片主节点在指定机房,能够解决跨机房问题。详情参考:《会话加标签是怎么指定服务器?》
14. 老师您好,想请问下:MongoDB适合作商城app数据库吗?通常在哪些场景使用呢?谢谢!
我的以为彻底能够知足要求,同时还有利于业务的快速迭代开发。mongodb自然的模式自由(加字段方便)、高可用、分布式扩缩容、机房多活容灾机制,能够快速推动业务迭代开发。以个人经验,至少90%以上使用mysql的场景,mongodb一样能够知足要求。mongodb惟一缺点多是生态没mysql健全,研究mongodb的人至关少。
15. 老师能讲讲大家容量预警是怎么作的吗?
容量水位咱们分为如下几种:
- 磁盘容量限制
当一个分片中磁盘使用率超过80%,咱们开始扩容增长分片。
- 流量超过阀值
读写流量阀值水位以下:1. 若是是分片的写流量持续性超过3.5W/s(ssd服务器)则扩容分片;2. 若是是读流量单节点持续性超过4W/s(ssd服务器,全部读走磁盘IO),则扩容从节点来解决读流量瓶颈,注意须要配置读写分离。
- CPU阀值
咱们全部实例容器部署,实例若是CPU使用率持续性超过80%,考虑增长容器CPU。
16. 数据一致性在迁移过程当中同步大家是怎么保证的呢
若是经过mongoshake等工具迁移集群,须要提早关闭blance功能,不然没法解决一致性问题。
咱们线上集群只有把数据从集群迁移到另外一个集群的时候才会使用mongoshake,咱们机房多活不是多个集群双写方式,而是同一个集群,经过夫直接的主从同步拉取oplog机制实现一致性,因此不存在一致性问题。能够参考 万亿级数据库MongoDB集群性能优化及机房多活容灾实践
17. 咱们数据体量不太大,主要是杂,这种环境想作好数据治理,老师你建议把重点放在哪些方面?而后有没有一些比较常见的坑?
数据量不大,比较杂的场景,通常集群搞一个复制集便可知足要求,无需分片模式部署。
我猜想大家的比较杂多是利用mongodb的模式自由,形成每条数据的字段各不相同,数据长度大小各不一致。建议在使用模式自由这一功能的时候,必定不要”滥用”、”乱用”,在使用时代码逻辑须要简单控制。我重节线上遇到的对模式自由的”滥用”、”乱用”引发的集群问题:
- 同一个表数据字段各不相同,建议同一个表全部数据的字段保持一致,即便新数据增长字段也须要在老数据中增长该字段,保持字段一致。
- 同一个表的数据的字段控制在50个KV之内,这样对应更新、查询等性能分析有利,减小磁盘IO消耗。
- 若是数据字段过多,查询的时候不要返回全部字段,只获取对本次查询有用的字段,减小忘了IO开销。
- 数组别乱用,数组中的文档保持格式统一。
- 数组中的子文档若是须要查询指定字段,必定记得对数组中嵌套的字段添加子索引。
- 数组字段中的文档必定要控制在必定范围,避免该数组过大,数组过大有遍历、磁盘IO太高等问题。
- 嵌套子文档层数不宜过多。
- ......
18. 现在有多大数据量?
公司内部mongodb规模已经很大了,整体超过数万亿级。
19. 大家对这个大数据平台有多少开发人员?
咱们研发+运维人员不多,mongodb拥有自然的高可用、分布式扩缩容、机房多活容灾等功能,保证了能够用不多的人力来知足公司快速增加的业务需求。
20. 最后:我的2021年规划(为mongodb国内推广及影响力提高作点事)
国内真正拥有企业级分布式数据库自研能力的公司主要集中在阿里、腾讯头部几家,即便二三线互联网公司也没法作到真正意义上的企业级分布式数据库研发能力,拥抱开源是一个明智的选择。
mongodb拥有自然的高可用、分布式扩缩容、机房多活容灾、完善的负载均衡及一致性策略等功能,能够作到最少人力成本知足业务快速增加的需求,我的认为mongodb绝对是头部公司之外企业会分布式数据库需求的一个值得信赖的选择。
正如在Qcon专题:现代数据架构、dbaplus、mongodb中文社区所分享,当前mongodb国内影响力待提高最大的问题在于国内真正研究mongodb内核实现细节的人太少,形成不少复杂问题没法解决,最终这些”人”的问题演变为“mongodb问题”。
在此,后续持续性分享业务接入过程当中的典型踩坑,同时持续性模块化分析mongodb内核设计原理,为mongodb国内影响力提高作点实事,具体计划以下(详见:盘点 2020 | 我要为分布式数据库 mongodb 在国内影响力提高及推广作点事):
20.1 短时间目标
短时间目标主要是把我司数万亿级数据量mongodb业务接入过程所遇到的核心踩坑过程、性能优化案例、机房多活案例等分享到社区,避免国内其余mongodb用户踩一样的坑,这些核心踩坑点也是分享中相关听众最关心的点,主要以下:
- 300条数据操做引起的血案-记一次线上300条数据变动操做引发某10亿级mongodb核心集群不可用故障。
- 主节点持续性OOM-记一次业务排序操做不合理使用引发的核心mongodb集群故障。
- 千亿级/万亿级集群最优索引添加方法-记一次数十亿级核心集群后台索引添加引发的集群抖动及快速恢复过程。
- 连接数耗光如何快速恢复集群-记一次百亿级核心集群连接数耗光的快速自救过程。
- mongodb机房多活方案-实现成本、性能、一致性"三丰收"。
- mongodb线程模型瓶颈及其优化方法。
- 并行迁移-集群扩容速率N倍提高优化实践。
- 千亿级核心元数据mongodb集群性能数倍提高优化实践。
- 万亿级数据量mongodb集群性能数十倍提高优化实践。
- 成本节省-记某服务千亿级数据迁移mongodb,百台SSD服务器节省优化实践。
- 如何快速完成数千亿数据从SSD高IO服务器迁移到SATA盘低IO服务器?
- 。。。。。。
指望完成时间:2021年4-5月
20.2 中期目标
完成Qcon、知乎、github、itpub中专栏《mongodb内核源码实现、性能调优、最佳运维实践系列》中核心文章的分享。
没有什么比源码更有说明力,完成github中mongodb内核源码中文注释分析:
指望完成时间:2021年11月
20.3 年度目标
指望经过对mongodb核心内核核心技术内幕的分享整理,完成以下系列文章或者书籍的编写整理:
- 《分布式mongodb数据库内核设计与实现》
- 《分布式mongodb数据库最佳运维实践》
指望完成时间:2021年12月底
20.4 公司内部目标
1. 公司自研mongodb内核深度优化,最大化解决高并发大流量、大数据量状况下扩容过程的抖动问题。
2. 快速掌握mongodb-4.2分布式事务实现原理,开始大力推广分布式事务功能。
3. 持续分享内部推广过程当中的集群踩坑、性能优化等案例到社区。
4. 其余
指望完成时间:整年