MongoDB 性能瓶颈分析

    一、前情简介

    二、操作方式

    (1)首先是确认防火墙,端口是否开放,MongoDB1.82升级2.02安装成功,所有操作在内网进行。

    (2)使用Rsync将R410服务器的MongoDB主库数据同步到R710中。同步结束之后,删除R710本地Local文件。以从库模式启动,开始同步R410中MongoDB主库的数据。在同步延时在1s左右。确认数据及时同步。

    rsync是类unix系统下的数据镜像工具——remote sync。一款快速增量备份工具 Remote Sync,远程同步 支持本地复制,或者与其他SSH、rsync主机同步。

    (3)在确认数据同步后,切断所有数据库Write操作的入口。使MongoDB主库的数据不再出现变动。这之后确认从库的数据已经与主库完全同步。进入主库,shutDownServer()。停止主库服务。然后进入从库,shutDownServer。停止从库服务。

    然后再将R710中的从库以主库的模式重新启动。这时同时切换所有访问数据库程序的Hosts。使其从R410的主机IP指向到R710的主机IP。这时启动所有服务。

    三、启动后的惊心动魄

    • 明显是处理不过来。创建的conn连接数越来越多,导致客户端频繁的出发TimeOut。最后甚至引起了MongoDB锁死,不再执行任何操作。写入队列堆积到20000+。之后进行查询,网上说MongoDB2.02 + R710需要在启动参数中追加numactl —interleave=all 。经过添加后,松了一口气,因为无效。之后的几天频繁出现问题,MongoDB占用内存最高只打到5GB的热点数据。在昨天中午数据库彻底锁死宕机。

    • 问题被定位在R710的硬件设备不兼容上。被迫在白天的时候重新操作了一次之前的工作,将数据库迁移回R410。在晚上的时候进行观测,发现数据依然不够理想。还是一样的效果。

    • 之后开始怀疑是因为MongoDB1.82升级到2.02导致的问题,开始查阅资料。但是依然毫无进展。

    四、一些性能优化

    • 进行Nginx和MongoDB的log观察。发现每分钟大概14000的动态请求。而MongoDB的log一直在展示一些可怕的慢查询,最长的一次竟然有370秒!
    • MonogoDB有个很坑爹的地方就Auth验证,我之前的日志还描述过这个东西,但是没想到每次创建连接时的密码验证竟然成了瓶颈所在。希望大家慎用。可以选择封闭MongoDB所在主机的外网IP,然后使用内网无密码访问最佳。

    • 进行服务器性能优化,在频繁调用的几个接口紧急使用缓存来缓解问题。而一些不重要不需要及时更新的查询则切换到从库进行查询。并切掉了一些需要及时更新的数据接口也访问从库,需要mark下数据库缓解后再调整回去。

    • 这之后数据的读写队列在300-1000左右,依然是不健康的状态。

    五、再一次定位问题

    • MongoDB的占用的内存热点数据依然是5GB左右。崩溃了。
    • 定位问题到MongoDB的数据由于不在内存中,所以导致读写速度障碍。
    • 写了一段Java程序进行R710数据库数据循环插入,希望能测试出是否可以提高内存占用量。
    • 果然,结果是插入一段时间之后。MongoDB的内存占用已经到达36GB。理想中的结果。
    • 不过线上环境不能随便插入数据,所以使用python写了一段全表扫描数据的脚本执行。 结果竟然无效。

    推论是插入会直接放入热点中,查询可能是需要经历一段时间和几次的命中才会。坑爹。目前能做的就是等待,等待MongoDB的热点内存占用提高,才能缓解所有问题。直到Mongos测试OK

    六、其实。。最重要的地方在这里

    问题主因就是优化不足,还轻率的进行了数据库切换。

    • MongoDB在R410时候运行,所有的热点数据在内存映射Mapping。

    • 而R710没有,需要再规则下重新进行映射。 最坑爹的就是这里。这段时间需要很久。

    • 而数据库重启导致用户重连服务,暴起的连接数和请求数直接压垮数据库。甚至会导致数据库启动就宕机的危险。