注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

北漂的小羊

Java编程,开发者,程序员,软件开发,编程,代码。新浪微博号:IT国子监

 
 
 

日志

 
 
关于我

在这里是面向程序员的高品质IT技术学习社区,是程序员学习成长的地方。让我们更好地用技术改变世界。请关注新浪微博号: IT国子监(http://weibo.com/itguozijian)

网易考拉推荐

MongoDB 性能测试数据分析  

2012-12-13 19:18:10|  分类: 数据库 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
一、前情简介 

半个月前,公司的MongoDB压力由于用户量暴增导致压力急剧增加,读写能力下降。 
因为对于Mongos 的集群分片机制的了解和测试还不是很充分,所以开始使用最简单的办法来解决:提高配置。 
众所周知,MongoDB是出了名的吃内存。当时定义出来提高MongoDB的办法很简单,插内存。 
但是由于机房问题,插内存需要拔电源,导致停止产品的服务,所以经过研究后。 
用我们备用的R710 64GB内存服务器来替代线上的R410 32GB内存的服务器。 

二、操作方式 

(1)首先是确认防火墙,端口是否开放,MongoDB1.82升级2.02安装成功,所有操作在内网进行。 
(2)使用Rsync将R410服务器的MongoDB主库数据同步到R710中。 
同步结束之后,删除R710本地Local文件。以从库模式启动,开始同步R410中MongoDB主库的数据。 
在同步延时在1s左右。确认数据及时同步。 
(3)在确认数据同步后,切断所有数据库Write操作的入口。使MongoDB主库的数据不再出现变动。 
这之后确认从库的数据已经与主库完全同步。进入主库,shutDownServer()。停止主库服务。 
然后进入从库,shutDownServer。停止从库服务。 
然后再将R710中的从库以主库的模式重新启动。这时同时切换所有访问数据库程序的Hosts。使其从R410的主机IP指向到R710的主机IP。这时启动所有服务。 

三、启动后的惊心动魄 

启动服务之后,MongoDB并没有像我们想象中的疯狂的占用内存,起初只是占用了2.5G左右的内存。 
用户在频繁的访问数据库,通过MongoStat观察到。用户的QR和QW也就是读写队列不停堆积。Locked值居高不下。 
明显是处理不过来。创建的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下数据库缓解后再调整回去。 
经过追查每一个表的索引发现,数据表中有很多冗余索引,有一些没有作为索引条件查询,有一些已经被建为联合索引,却依然没有删除掉。果断Drop掉这些Index。 
这之后数据的读写队列在300-1000左右,依然是不健康的状态。 

五、再一次定位问题 

这之后MongoDB一直在不健康的状态但是并没有再一次宕机。不过危险依然存在。 
MongoDB的占用的内存热点数据依然是5GB左右。崩溃了。 
定位问题到MongoDB的数据由于不在内存中,所以导致读写速度障碍。 
写了一段Java程序进行R710数据库数据循环插入,希望能测试出是否可以提高内存占用量。 
果然,结果是插入一段时间之后。MongoDB的内存占用已经到达36GB。理想中的结果。 
不过线上环境不能随便插入数据,所以使用python写了一段全表扫描数据的脚本执行。 
结果竟然无效。 
推论是插入会直接放入热点中,查询可能是需要经历一段时间和几次的命中才会。坑爹。 
目前能做的就是等待,等待MongoDB的热点内存占用提高,才能缓解所有问题。直到Mongos测试OK 

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

问题主因就是优化不足,还轻率的进行了数据库切换。 
MongoDB在R410时候运行,所有的热点数据在内存映射Mapping。而R710没有,需要再规则下重新进行映射。 
最坑爹的就是这里。这段时间需要很久。而数据库重启导致用户重连服务,暴起的连接数和请求数直接压垮数据库。 
甚至会导致数据库启动就宕机的危险。 

七、动作要谨慎。

在MongoDB 1.6.4的使用过程中,我们发现当文件系统cache用尽的时候MongoDB的写入性能会有非常大的波动。更为致命的是,偶尔还会发生持续20-30秒的写入阻塞。虽然MongoDB的设计非常先进,但是稳定性一直是我们头痛的一个问题。带着疑问我们参加了Mongo北京开发者聚会,会上10gen的工程师Alvin Richards建议测试一下MongoDB 1.8,据说在写锁上有所改进。
回到杭州后,我们在Redhat 6.0上重做了MongoDB 1.6.4和1.8.0-rc0的对比测试。测试的结果如下图所示:

MongoDB 性能测试数据分析 - 天涯草 - 天涯草
 

MongoDB 性能测试数据分析 - 天涯草 - 天涯草
 

这两张图的横坐标是时间轴(每个点代表10秒钟),纵坐标是插入速度(代表10秒内的平均速度)。
测试逻辑如下:
1、在zyy库下建立一个名为test的collection
2、在test的k字段上建立索引
3、开启测试程序并打点。该测试程序将开启10个线程对test进行并发写入。k由uuid调用生成,长度为37字节;v长度为1k。

从测试结果上看,MongoDB 1.8.0相对于1.6.4在写入性能上有所改进。首先,1.6.4除了预分配文件造成性能下降外,写入性能偶尔还会长时间降到0。而1.8.0基本没有出现写入性能降到0的情况,性能的最低点在于预分配文件。其次,从性能的稳定性上看,1.8.0的波动显然没有1.6.4那么夸张。在InnoDB做的类似测试也会出现类似波动,但是性能最低点不会降到MongoDB那么低。

总体而言,MongoDB 1.8.0-rc从功能和性能上都有所改进。期待release版本和新的存储引擎中。

  评论这张
 
阅读(738)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016