转至:https://cnodejs.org/topic/55c97a997a5d91fa63fe9ce7
前几天,公司一个业务部门的 Mongodb 数据库副本集(1主2从)出现写入和更新延迟现象,最慢的一次更新长达22秒,平均的更新和插入操作在15秒左右,上报到我们公共部门,希望能够得到解决。
之前业务部门已经对这个 Mongodb 使用了一个多月,一直没出问题,又怎么会突然发生延迟这么长的故障呢?
由于 Mongodb 中本写入的是重要的价格政策信息,所以这个故障已经影响正常线上业务了,于是我就担任救火队员,负责解决这个问题了。
于是灾难开始了: 1、删除索引 我们在出问题的集合中发现了一个3个字段的组合索引,而这个组合索引并没有被查询使用到,为了加速插入,我们决定在主库删除这个不使用的索引,然后让它同步到从库上,因为删除索引通常很快。 删除很快,5分钟左右,就把几千万条记录的集合的索引删除了,在我们删除完索引之后,主库的写入速度有了一定下降。没有之前那么夸张的平均15秒了,下降到了4-5秒。
2、恢复索引 这时Mongodb的集群出现报警,从库的读取性能急剧下降,外网业务频繁出现 504(time out)的错误。这时候我们其中的一个DBA同事以为我误删了那个索引引起的全表扫描,导致查询超时,于是他在主库上又将我刚才删除的索引重建了。 这时候更大的灾难降临了,在主库重建索引的时候,所有的主库写操作阻塞了,当主库创建完索引,将oplog同步到从库,从库创建完索引之后,两台从库在集群里的状态分别是:recovering和unreachable。 这时候整个Mongodb集群无法正常提供数据服务了,业务部门职能临时切换备用 sql 方案,勉强恢复对外提供服务,整个故障历时2小时。
3、事故分析: A、删除无用索引肯定会加快写入,但是为什么我删除了这个没有查询命中的索引,会让从库读取性能下降呢? 主库删除索引,同步到从库之后,从库开始删除索引,这时候从库是无法从主库那边拉取同步数据的,因为删除索引会有一个写锁,所以当从库删除完索引之后,主库有大量的更新开始同步到从库,这时候从库压力倍增,导致读取性能下降。
B、恢复索引为什么会导致集群挂掉 DBA同事发现从库查询慢,以为是误删索引,其实并不是,而是由于之前从库删除索引停止同步引起的。 因为创建索引,会直接导致从库写入和读取的锁,并且耗时相比删除索引要长很久,所以两台从库就直接不提供服务了。 当从库创建完索引之后,从库和主库的数据不同步延迟相当大,大量的更新和外网的读取压力,导致整个Mongodb集群无法提供服务了。
4、解决问题 由于目前业务数据骤增,所以我们需要重新审视 Mongodb副本集 是否还能继续为我们提供服务,在Mongodb无法对外提供的时候,我们只能依靠多台redis和sqlserver数据库临时上线,应付业务。
A、在出故障的时候我们查看了Mongodb的状态,竟然有超过5000个连接,连接在主库上等待写操作。于是我们翻看了业务代码,发现10台服务器每台服务器的最大连接池设置了20000个,由于之前我们有测试Mongodb在大连接数下表现确实不佳,于是把代码改回默认的100个,继续跑数据,但是问题依旧,性能大约仍然在update操作 2000次/秒 左右。
B、因为业务的特殊性,集合中存储的当天之后的65天的价格政策信息,而之前没有定期清理垃圾数据,于是我们将过期的政策清理掉,大约清理掉了30%的数据,以为能够恢复原来的写入性能,无奈业务增长太快,就算清除了30%的垃圾数据,还是远远的超过以前的数据量,这个方式宣告失败。
C、翻阅网上Mongodb的资料,发现官方文档上有一些对于写操作的优化方案,文中提到使用SSD可以显著提升写操作的性能,最高可达20倍,于是折腾了运维,火急火燎的将3台Mongodb数据库机器全部加上SSD硬盘,由于换硬盘数据库要清楚,所以在换完硬盘前几小时写入性能非常高,但是当数据量上来之后,性能又跌回 2000次/秒,我们的数据量大约110G,内存当时配置了196G,所以SSD无法优化到写入操作。
D、再次翻阅Mongodb官方资料,发现Mongodb的文档是基于 usePowerOf2Sizes 这个规则来申请内存和空间的,当文档初始化插入4KB时,Mongodb申请的空间大小为8KB,当文档涨到8KB后,则申请16KB,以此类推。文档的增涨会带来数据块的迁移,带来性能损失,如果是文档初始化很小,会逐渐增涨,并增涨到一个相对初始大小很多倍的场景,那么官方推荐调整 usePowerOf2Sizes 这个设置,来初始化给文档分配一定的空间。我们的业务场景和这个很像,初始化只有1KB,以后的多次更新,最多可以将文档更新到80K。于是我们将文档初始化占用的空间设置为96KB,防止因为不断的数据块迁移带来的性能损耗,可惜这个配置还是然并卵。
E、无奈开始找其他出路,想到使用HBASE分布式kv存储方案来解决这个问题,了解到社区的@alsotang 正好非常熟悉HBASE这块,当天晚上就找 @alsotang 讨论解决方案,发现HBASE的查询条件太死,无法像Mongodb那样满足业务场景,经过这几天折腾,我得出结论就是因为并发写锁导致的性能低下,于是 @alsotang 给了我另外一个建议,批量写入,积攒大约几千条写的命令,批量插入。第二天的批量测试结果却是让人眼前一亮,性能从原来的2000次/秒 提升到了5000次/秒了,但是这样可能暂时能扛下来压力,过几个月业务增长之后,可能又存在瓶颈了。
F、由于我们线上使用的是Mongodb2.6,所以存在写入的库级锁,会不会是因为这个导致的并发写入性能低下呢?抱着吃螃蟹的心态,将数据库升级到3.0,还是之前批量写入的代码,空库的写入性能能达到 40000次/秒,在单表6000万数据量下,批量写入也能达到 18000次/秒,而且3.0的内存占用比2.6要少很多。 但是由于改成批量写入,业务端代码改动比较大,所以我们测试了非批量写入的情况,写操作性能也能达到8000次/秒。
G、最终我们还是决定一步到位,搭建了Mongodb3.0的集群,分6片存储之前单机Mongodb的数据,这样理论上能让我们的写性能翻5-6倍,就算不用批量写入,仍然可以达到40000次/秒,应该近几年业务是达不到这个指标的,而且一旦发现瓶颈,我们可以通过增加分片的方式提高集群性能。终于折腾了多天的Mongodb算是告一段落了,至于上线之后Mongodb3.0的坑是否会踩到,只能看脸了。
事故就分析到这里,期间研究了一些Mongodb的优化方案,传送门: http://lucien-zzy.iteye.com/blog/2310843
相关推荐
MongoDB案例3 MongoDB 是一种流行的 NoSQL 数据库,广泛应用于各个领域。然而,在生产环境中,MongoDB 也可能遇到各种问题,如写入和更新延迟、索引删除和恢复、集群故障等。本文将介绍 MongoDB 案例 3 中遇到的...
这是一个基于Vue.js、Express.js和MongoDB的在线点餐系统的设计源码案例。这个系统集成了前端用户界面、后端服务器处理以及数据库存储,旨在提供一个完整的线上订餐解决方案。 首先,Vue.js是当前非常流行的前端...
这是一个基于Vue.js、Express.js和...开发者可以通过此案例学习到如何将Vue.js、Express.js和MongoDB整合在一起,构建一个完整的线上点餐系统。同时,对于想要扩展或定制类似应用的人来说,这也是一个很好的起点。
【标题】:“基于Springboot+Vue的线上辅导班系统的开发与设计源码案例设计” 这个标题揭示了我们讨论的核心——一个结合了Springboot后端框架和Vue前端框架的线上辅导班系统。Springboot是Java领域广泛应用的轻量...
这个项目可能是一个逐步教程或者实战案例,帮助开发者了解如何将这两种强大的工具结合在一起,创建高效、可扩展的Web应用。下面,我们将深入探讨Node.js和MongoDB的主要知识点及其在建站中的应用。 Node.js是基于...
总的来说,“约约看源码(线上)”为我们提供了一个全面研究社交软件开发的实践案例,涵盖了用户交互、数据处理、功能实现等多个方面。通过分析这个源码,开发者不仅可以深化对社交应用工作原理的理解,还能学习到...
网络技术和计算机技术发展至今,已经拥有了深厚的...Java、Python、Node.js、Spring Boot、Django、Express、MySQL、PostgreSQL、MongoDB、React、Angular、Vue、Bootstrap、Material-UI、Redis、Docker、Kubernetes
本压缩包包含了一个完整的线上考试系统源码,适合用于学生的毕业设计、期末大作业或者课程案例研究。 一、系统架构与技术栈 这个线上考试系统可能基于Web开发,使用了前后端分离的技术架构。前端可能使用HTML5、CSS...
文档共享部分,可以采用SpringBoot集成MongoDB或FTP服务器,实现文档的上传、下载和版本控制。Vue组件可以设计为文件管理界面,用户可以浏览、搜索和下载文件。 消息通知方面,SpringBoot可以结合RabbitMQ或...
常用的数据库类型有MySQL、MongoDB等。此外,还需要关注数据传输加密、用户隐私保护等问题。 ### 五、案例分析 #### 5.1 案例背景 假设某电商平台希望通过开发微信小程序来进一步扩大市场份额,提升品牌形象。 ##...
网络技术和计算机技术发展至今,已经拥有了深厚的...Java、Python、Node.js、Spring Boot、Django、Express、MySQL、PostgreSQL、MongoDB、React、Angular、Vue、Bootstrap、Material-UI、Redis、Docker、Kubernetes
网络技术和计算机技术发展至今,已经拥有了深厚的...Java、Python、Node.js、Spring Boot、Django、Express、MySQL、PostgreSQL、MongoDB、React、Angular、Vue、Bootstrap、Material-UI、Redis、Docker、Kubernetes
综上所述,Food Corner项目是一个综合性的全栈Web应用实例,涵盖了从后端开发到前端交互、数据库管理、安全认证等多个环节,是学习和展示全栈开发能力的优秀案例。通过深入分析和实践该项目,开发者可以全面掌握Web...
【标题】:“airbnb-nextjs-mongodb”项目详解:基于...总的来说,这个项目是学习和实践前后端分离、SSR、数据库管理和云服务的绝佳案例。通过它,开发者可以深入理解如何在现代Web环境中构建高性能、可扩展的Web应用。
【标题】中的“毕设&课设&项目&实训-网页设计比赛项目-武大线上问答社区WHUwhy”表明这是一个针对学生设计的项目,旨在帮助他们完成毕业设计、课程设计或者实训任务,同时也是一个参与网页设计比赛的案例。...
总的来说,本项目涵盖了Node.js、Express和MongoDB的综合运用,以及上线环境的部署,对于想要学习全栈开发的开发者来说,是一个很好的实践案例。通过完成这样的项目,不仅可以掌握后端服务的构建,还能了解数据库...
《基于Vue.js、Node.js和MongoDB的学生宿舍管理系统详解》 在信息技术日益发达的今天,学生宿舍管理系统的建设显得尤为重要,它能...对于学习和研究Web开发的人员来说,这是一个很好的实践案例,值得深入研究和借鉴。
微信小程序是一种轻量级的应用开发平台,主要针对移动端,由腾讯公司推出,旨在提供便捷的、无需下载安装即可使用的线上服务。"微信小程序开发-爱靓女带后台案例源码.zip" 是一个包含完整微信小程序开发项目的压缩包...