资讯专栏INFORMATION COLUMN

记录一次并发读取MongoDB的踩坑过程

luffyZh / 1524人阅读

摘要:出现的问题笔者前段时间开发一个新项目的某个功能模块要读取老游戏中某个数据库计作库连续读库中的个集合相当于的张表取数据在测试环境单次操作时是内但是并发测试情况下比如内个并发时读取库个集合的耗时能达到以上甚至且个并发请求几乎同时完成但是在我本地

出现的问题

笔者前段时间开发一个新项目的某个功能模块,要读取老游戏中某个Mongo数据库(计作A库),连续读A库中的6个集合(相当于MySQL的6张表)取数据,在测试环境,单次操作时是10ms内,但是并发测试情况下,比如1s内100个并发时,读取A库6个集合的耗时能达到2s以上,甚至7,8s,且n个并发请求几乎同时完成,但是在我本地环境,并发下,平均一次操作也在几十ms到100多ms上下浮动,并发请求也比较正常

下面讲述一下整个处理过程

初步分析

虽然使用MongoDB的经验不多,但是在我的认知里,MongoDB的读取性能不可能如此低,不然如何投入生产环境?

那么,到底是哪里出了问题呢?

对比本地环境和测试环境使用方式,发现一个区别,我本地环境在Docker中跑的Mongo容器实例,为了方便,并没有设置用户名和密码,直接ip+端口号连接,而测试环境用了用户名密码,不管三七二十一,按照高中时候学的生物学中对照实验的思路,目前就只发现一个区别,先进行验证

本地连接Mongo的url
127.0.0.1:27017
本地环境配置用户名密码,得出结论:账号授权数据库切换耗时阻塞

先按照网上的教程,给Admin数据库建立一个管理员账号,拥有Mongo实例中读写任何一个db的权限

db.createUser({user:"root",pwd:"123456",roles:[{role:"userAdminAnyDatabase",db:"admin"}]})

使用账号密码后,无并发时,仍然是ms级别,但是发现,本地环境和测试环境一样,并发时,耗时达到数秒,且n个并发请求几乎同时完成,好像某个操作导致阻塞,然后这个阻塞操作完成后,没有阻塞只会,并发读取操作正常执行,可以确定是Mongo数据库的账号管理相关问题

为啥账号模块会导致这么大的缺陷?

通过神器Google搜索,看了n篇博客,发现一篇12年的博客

该文作者在生产环境使用Mongo数据库,有性能问题,其中一个关键点是,Mongo数据库,如果有用户名和密码,在每次建立数据库连接时,都会验证用户名密码,建议在生产环境不要使用用户名和密码,通过禁止外网访问,通过内网ip以及限制ip的方式,访问mongo数据库

由于线上老项目是lua写的,公司已经一年多未进行代码维护,且准备后面新项目上线后,直接下线老项目,笔者以及公司其他后端,都不懂lua,为了避免导致不可预料的问题,同时,在我看来,用户名和密码,对于数据库而言是最重要的安全模块,全球那么多公司在使用,就算账号验证有一定的性能损耗,但是也不可能有这么大的问题,应该还是我自己使用方面的问题,继续深入寻找原因

通过请教一位同事,公司另一个基础服务(计作B服务吧)在生产环境也用了MongoDB,且流量也很大,并没有问题,通过对比

我的方式:
user:123456@127.0.0.1:27017/admin
然后在代码中通过use,切换到baby库

B服务的方式:
针对baby数据库建立一个账号,由baby库授权
user:123456@127.0.0.1:27017/baby?authSource=baby&maxPoolSize=50

区别在于我是跳转到baby库,而正常环境下是使用该数据库下的用户

说明数据库授权耗时以及数据库切换也比较耗时,为啥会耗时,看到一篇博客讲到了Mongo的账号授权原理,知道了建立连接数据库授权时会导致库级锁(即连接a在使用时,连接b进行授权,也会导致baby库锁定,连接a被阻塞)

本地环境为数据库配置账户密码,直连,本地正常,测试环境依然延迟数秒

于是接着本地也适用B服务一样的方式,通过baby库下建立user账号,直连的方式连接,本地环境耗时正常,并发下读取6个集合,在100ms以内,属于正常性能,但是发到测试环境,并发下虽然耗时减少了,相对于之前的8s,现在依然有1s多的延迟

连接数据库方式一样,但是耗时差别很大,经过上一步知道了耗时是因为数据库锁机制导致的问题,后面在Google上搜Mongo锁机制,在知乎上看到了一个回答

mongodb 最初是全局锁,后来库锁,接着3.0进化到表锁了... 现在使用 WiredTiger 可以实现文档锁...

对比了测试环境和本地环境的版本,本地是最新的,已经是3.6版本,测试环境还是2.6版本,属于库锁

到此,可以知道问题所在了,MongoDB账号授权机制以及数据库锁机制

总结

感兴趣的客观可以搜索MongoDB锁机制相关博客,网上文章很多,我就不在此啰嗦了

Mongo数据库,在生产环境,尽量通过限制内网ip才可以访问的方式保证安全,防止攻击

其次,不要通过admin管理员用户连接数据库,该账号只是做为管理员使用,而不应该作为生产环境使用,MongoDB的思想是账号和数据库绑定,而不是实例,MySQL是一个MySQL实例对应账号,不针对某db

尽量使用3.X的新版本MongoDB,数据库锁已经完善

以上只是我个人解决这个问题的全过程,博客写的不够思路清晰,过去了半个月,细节也记得不是很清楚了了,希望能给技术圈有所贡献,谢谢支持

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/19199.html

相关文章

  • 一次使用Fiddler抓包工具抓取Https协议数据踩坑过程

    摘要:直到今天,突然看到一个有意思的微信小游戏。后来试了几次之后才发现,这个小游戏比较刁,不仅做了微信的登录授权,而且做了手机端访问的判断,更甚至竟然用的还是协议的网页。调用的目标发生了异常。 记一次使用Fiddler抓包工具抓取Https协议数据的踩坑过程 前言 记得从刚入门前端第一天开始,当时的师傅就跟我介绍了一个可以抓取一些必须要在微信浏览器打开的链接的工具Fiddler,主要用来抓取...

    JackJiang 评论0 收藏0
  • Notadd 2.0 全新 Node.js 版本~ (开发中) [从 PHP 到 node 踩坑

    摘要:有着最全的协议支持,同时有各种非阻塞拓展,可以说是最符合要求的,但是异步需要对做很大的改动。的计划将基于开发,同时也提供一些无法提供的功能和特性。 一点小遗憾 对于 Notadd 我们本来期望它实现更多... 尽管我们也尝试做了很多努力,但是由于 PHP 本身的局限,以及考虑到开发环境配置的复杂程度,最终使用了折中方案。接下来,我们谈谈整个技术选型历程,也供今后相关开发者做借鉴和参考:...

    Tonny 评论0 收藏0
  • 首个最全的MongoDB 3.6 全览

    摘要:先睹为快振奋人心的时刻终于到来了,在经过一个上市的日子后,终于发布了。实战在线开启认证模式解读我是上海小胖,专注等开源数据库的,拥抱开源,接受收费。上海小胖原创地址欢迎各位大神前来评论。每周五,敬请期待,上海小胖独更。 MongoDB 3.6 先睹为快 Part 1 振奋人心的时刻终于到来了,在经过一个MongoDB 上市的日子后,MongoDB 终于发布了MongoDB 3.6 RC...

    陈江龙 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<