您的位置:首页 > 数据库 > SQL

openfire mysql 转mongo 注册行为性能测试及其他

2014-05-08 12:11 543 查看
测试同学使用tsung测试openfire时发现注册并发数过低,同事经过测试认为数据库是最大瓶颈,建议将mysql数据库改造成mongo数据库。

首先尝试改造了ofUser表相关操作,使注册逻辑整体走mongo:

改造涉及文件如下:

在org.jivesoftware.database 包下仿照DefaultConnectionProvider、DbConnectionManager创建mongo的相关Provider和Manager

为了减轻字段映射压力,使用了morphia,因此,需要创建相应的pojo,如ofUser.java

改造所有涉及ofUser表的增删改查

由于原来为了适应多种数据库,所以在其中增加了很多判断,搞明白逻辑后可以去除这些判断。

mongo连接方面参考了以下文章:
http://www.linuxidc.com/Linux/2012-01/52150.htm http://www.cnblogs.com/huangfox/archive/2012/04/01/2428947.html http://blog.csdn.net/magicfoxhu/article/details/7568728
openfire数据库相关参考了下面的文章:
http://www.myexception.cn/database/1249683.html
mongo的api及文档:
http://api.mongodb.org/java/2.8.0/ http://docs.mongodb.org/manual/genindex/
java操作mongo:
http://www.cnblogs.com/hoojo/archive/2011/06/02/2068665.html http://tech.it168.com/a2011/0617/1206/000001206231_all.shtml http://blog.sina.com.cn/s/blog_5d3241cc0100q7yp.html http://www.2cto.com/database/201202/118157.html http://www.cnblogs.com/yuechaotian/archive/2013/02/04/2891416.html http://blog.csdn.net/mengxiangyue/article/details/8957085
使用morphia:
http://my.oschina.net/u/142072/blog/35714 http://wenku.baidu.com/view/83b56947a8956bec0975e357.html http://www.blogjava.net/watchzerg/archive/2012/09/20/388109.html http://www.cnblogs.com/hoojo/archive/2012/02/17/2355384.html
在寻找的时候还发现了个特好玩的morphia使用者:
https://github.com/turbidsoul/turbidsoul.github.io/commit/fe4bcdc7238b24ed06aaf327e3470ced676d1b27
在做pojo的时候特意研究了下objectid呀~发现了很多好东东哦~
http://www.cnblogs.com/xjk15082/archive/2011/09/18/2180792.html http://www.kuqin.com/database/20120317/319007.html http://blog.nosqlfan.com/html/3511.html
——————————————分割线————————————————————————————————————————————————————————

改造完成开始性能测试:

使用tsung测试:500请求/s 运行5分钟

数据库插入数/理论插入数,

mysql注册基本稳定在75%

mongo注册基本稳定在30%!!!!

震惊了我,mongo的性能怎么可能这么差!!

赶紧查查mongo性能提升相关的文档:
http://database.51cto.com/art/201109/293088.htm
第一条:是否建立索引,果然,我并没有建立索引,而在注册时需要先查一下此用户是否存在再进行插入,查询对索引需求大,建立索引,参考如下文档:
http://blog.sina.com.cn/s/blog_af52238c0101bhno.html
建立username索引,再次测试:

mongo注册率稳定在76%

松了一口气,但是只币mysql高1%,这可不行,开始监控mongo性能,参考:
http://www.361way.com/mongo-mem/1489.html http://www.cnblogs.com/shanyou/archive/2010/10/02/1841348.html http://blog.csdn.net/liubo2012/article/details/8203751
发现mongo一直处于非繁忙状态,高并发行为并没有对其产生压力。只有少数insert方法执行速度超过10ms,但是数量极少

怀疑代码或者测试工具有问题,修改代码:

(1)去除逻辑中的query妹纸保留insert,性能没有提升--》性能与query无关

(2)关闭性能监控,性能没有提升--》性能与性能监控无关

(3)删除索引,性能没有提升--》性能与索引无关

(4)不使用morphia方法使用driver自带方法--》性能没有提升,与morphia方法无关

(5)去除db重连逻辑--》性能没有提升,与此逻辑无关

(6)使用morphia save方法,每1000个注册请求,调用一次--》性能下降,原因:morphia.save并非调用批量方法,积攒1000个请求在使用此方法依旧是一个个插入,反而增大了压力。解决:改造成driver自带insert 批量插入方法,上升至76%,--》与批量无关,但是批量插入的确比单个效果更好,(貌似批量操作会有全局锁问题,需要查看http://blog.chinaunix.net/uid-26660567-id-4106642.html)

(7)增大客户端单机连接数,20改为400,性能无明显变化,查询资料:http://blog.csdn.net/jollyjumper/article/details/8553307,增加连接数反而可能使性能下降。

--依旧原因未知,实验mongo shell循环插入10w条。参考:
http://www.myexception.cn/other-database/383981.html
10w条用时40s,监控mongo性能,返现在使用mongo shell循环插入10w条时压力比tsung 500 并发高。再次确定mongo应对压力无问题。

无法,开始使用笨办法:查看数据库数据,希望能行数据中找到缺失规律,还真被我找到了!!--

插入6000条数据,前5335条插入无丢失,只丢失5336-6000的数据。推测一定不是并发造成的丢失。

在代码逻辑的insert语句前打印日志,与数据库数据进行对比,发现日志打印数与插入数据库数完全相同,再次确认与数据库无关,推测可能是自行修改的mongo逻辑和mysql逻辑不通导致,测试mysql逻辑,发现打印日志数与插入数据库数依旧相同---》确定数据库绝对无压力。

————————————————————————————我是无奈的分割线————————————————————————————————

忽然被告知,测试同学配置的tsung有问题。啊啊啊啊啊啊啊==。。。明天使用同事自己做的压测工具。。

其他参考文档:


关于Mysql和Mongo的性能测试

http://blog.sina.com.cn/s/blog_591888d50101jx67.html

Openfire 性能优化 /article/7906676.html

java链接mongo /article/7724673.html

________第二天的分割线——————————————————————————————

使用了asmack组件提供的接口,瞬间创建多线程施压测试,测试环境(Intel(R) Xeon(R) CPU 2.13GHz ,内存:4139668 kB,64位)

mongo最长消耗时间是mysql最长消耗时间的2/5左右。

mongo在高并发注册情况下,成功率远高于mysql,具体数据如下:

数据库类型方式总发送请求数失败数请求完成时长成功数总实时长每秒完成数备注
Mongo10000线程,每个线程发送2次请求20000048001200008650492416.6579863
Mongo20000线程,每个线程发送1次请求20000049708200006905026402.3497224
Mongo30000线程,每个线程发送1次请求300000729083000012203271411.4774785
Mongo38000线程,每个线程发送1次请求380001391998583660920398798366.610587
Mongo38000线程,每个线程发送1次请求380000886373800012488874428.7148708
Mongo385线程,每个线程发送100次请求385000885973850032518607434.55196
Mongo385线程,每个线程发送100次请求385000898023850032518607428.7209639
Mongo3850线程,每个线程发送10次请求385001878991423662236155249369.3893607
Mongo3850线程,每个线程发送10次请求385000854273850029957272450.6771864
Mongo38500线程,每个线程发送1次请求385000902673850015107830426.5124575
Mongo38500线程,每个线程发送1次请求385000895313850012403008430.0186528
415.0619297平均值
所有mongo请求不成功问题都是由于以下问题造成的

错误:

Nested Exception:

java.net.NoRouteToHostException: Cannot assign requested address

at java.net.PlainSocketImpl.socketConnect(Native Method)

at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)

at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)

at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)

at java.net.Socket.connect(Socket.java:529)

at java.net.Socket.connect(Socket.java:478)

at org.jivesoftware.smack.proxy.DirectSocketFactory.createSocket(DirectSocketFactory.java:28)

at org.jivesoftware.smack.XMPPConnection.connectUsingConfiguration(XMPPConnection.java:555)

at org.jivesoftware.smack.XMPPConnection.connect(XMPPConnection.java:999)

at Main.runRegisterTest(Main.java:54)

at Main$3.run(Main.java:402)

原因:由于快速创建连接,端口被占用满,产生TIME_WAIT 端口

解决方案:http://bbs.chinaunix.net/thread-3842444-1-1.html

不能确定影响范围,暂时不进行解决

第二解决方案:

研究发现,Linux对外的随机分配端口是由一定限制的,理论上单机对外的端口最大值为65535,除去一些保留端口和被占用端口外,也应该在6W左右,但实际上单机建立对外连接时,默认不超过28232个连接。

执行以下命令就很清楚原因了:

$ cat /proc/sys/net/ipv4/ip_local_port_range

输出结果为:

32768 61000

这就是Linux随机分配端口的范围,如果在该范围内有被占用的端口,那么连接数肯定小于28232.如果想更改这个范围,可以执行以下命令:

# echo "10000 65535" > /proc/sys/net/ipv4/ip_local_port_range

检测发现Mongo性能情况一直良好,基本无等待队列产生
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: