`

MongoDB线上事故案例分享

阅读更多

 

转至: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

分享到:
评论

相关推荐

    基于SpringBoot+Elasticsearch+MongoDB开发的技术分享平台源码(课程大作业项目).zip

    基于SpringBoot+Elasticsearch+MongoDB开发的技术分享平台源码(课程大作业项目).zip基于SpringBoot+Elasticsearch+MongoDB开发的技术分享平台源码(课程大作业项目).zip基于SpringBoot+Elasticsearch+MongoDB开发的...

    mongodb demo案例代码

    mongodb demo案例代码

    mongoDB 案例 服务和jar包

    包含 jar包 ,案例 服务安装包,源码。使用手册

    mongodb常用函数使用案例

    mongodb常用函数使用案例,主要是针对update,insert,find函数

    MongoDB架构图分享.pdf

    MongoDB架构图分享.pdf MongoDB架构图分享.pdf MongoDB架构图分享.pdf

    MongoDB C/C++开发使用案例Demo

    MongoDB C/C++开发使用案例Demo(含源代码例子、编译好的MongoDB C库文件(.h .lib .dll)、开发环境搭建配置文档等),可直接用于项目开发

    2019年MongoDB年终大会PPT分享.zip

    本次活动包括云服务专场、生态技术专场和MongoDB专场10+大牛的现场分享。会前我们开展了MongoDB征文比赛,获得一等奖的朋友也来到现场为大家分享自己的MongoDB实践。接下来我们为大家来分享本次大会集锦。

    Nodejs-MongoDB实战案例-简易用户管理系统.zip

    使用NodeJS express框架操作MongoDB的实战案例,功能涵盖常用的增删改查和分页查询,对学习nodejs有很大帮助。

    基于MongoDB的日志系统Mongodb-Log.zip

    mongodb-log 是一个基于MongoDB的Python日志系统。 MongoDB 的 Capped Collection是一个天生的日志系统,MongoDB自己的oplog就是用它来存储的,Capped Collection的特点是可以指定Collection的大小,当记录总大小...

    mongoDB内部分享和交流

    NULL 博文链接:https://rtxbc.iteye.com/blog/864969

    MongoDB 分享文档

    MongoDB的安装,增、删、改、查,MongoDB和传统数据库对比,以及对sql的对比

    C# Mongodb案例 DLL

    这是C# 对monogodb数据库的增查改查小案例,同时里面单独带有引用dll的压缩包

    MongoDB安装包(windows10 64位)

    MongoDB数据库安装包,适用于windows10 64位,需要的可以下载

    Linux安装mongodb客户端

    sudo vim /etc/yum.repos.d/mongodb-org-4.2.repo 写入: [mongodb-org-4.2] name=MongoDB Repository baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.2/x86_64/ gpgcheck=1 enabled=1 gpg...

    MongoDB MapReduce分享.ppt

    NULL 博文链接:https://superhuo.iteye.com/blog/1193485

    MongoDB笔记.docx

    一、MongoDB简介 3 二、MongoDB结构 3 二、MongoDB 数据库关系型(这里并不是值关系型数据库的关系) 3 1、MongoDB一对一关系型 3 2、MongoDB一对多关系型 4 3、MongoDB多对多关系型 4 三、创建数据库(mongodb_test...

    MongoDB应用设计模式

    资源名称:MongoDB应用设计模式内容简介:无论是在构建社交媒体网站,还是在开发一个仅在内部使用的企业应用程序,《MongoDB应用设计模式》展示了MongoDB需要解决的商业问题之间的连接。你将学到如何把MongoDB设计...

    2021MongoDB中文社区杭州大会干货分享版.zip

    MongoDB 典型用例分享及新特性介绍-唐峰; 阿里云MongoDB云原生演进之路-陈祝红; 基于 MongoDB 构建零售行业实时库存系统的实践之路 - 杨庆麟; MongoDB在南瓜电影的落地实战经验分享-殷金良; 基于MongoDB构建「...

    如何安装MongoDB 如何使用MongoDB

    本课程是一套关于MongoDB应用开发的实战性教程,名为《深入浅出MongoDB应用实战开发(基础、开发指南、系统管理、集群及系统架构)》,教程侧重于讲解MongoDB的常用特性及高级特性,从实际开发的角度出发对MongoDB...

    mongodb安装文件安装步骤常用命令和案例.rar

    比较全面的记录了单机版的mongodb在Linux下的安装步骤。常用命令和案例。不用再自己做课件,需要的内容都有

Global site tag (gtag.js) - Google Analytics