Mongodb千万级数据在python下的综合压力测试及应用探讨

简介:



曾经在收集数据的项目中,用过mongodb的数据存储,但是当数据很大的时候,还是比较的吃力。很可能当时的应用水平不高,也可以是当时的服务器不是很强。 所以这次能力比以前高点了,然后服务器比以前也高端了很多,好嘞 ~再测试下。

(更多的是单机测试,没有用复制分片的测试 ~)!


相比较MySQLMongoDB数据库更适合那些读作业较重的任务模型MongoDB能充分利用机器的内存资源。如果机器的内存资源丰富的话,MongoDB的查询效率会快很多。


这次测试的服务器是dell 的 r510!

235621353.jpg

内存还行,是48G的,本来想让同事给加满,但是最终还是没有说出口 ~  

235739466.jpg磁盘是10个2T的,但是因为格式化的时间太久了,哥们直接把其他的硬盘给拔出来了,就用了三个盘。。。data目录没有做raid,是为了让他们体现更好的硬盘速度。

235930831.jpg


既然说好了是在python下的应用测试,那就需要安装mongodb python下的模块 !

对了,不知道mongodb-server的安装要不要说下?

1
2
3
4
5
cat /etc/yum.repos.d/ 10 .repo
[10gen]
name=10gen Repository
baseurl=http: //downloads-distro.mongodb.org/repo/redhat/os/x86_64
gpgcheck= 0


000408806.jpg

Pymongo的基本用法


1
2
3
4
5
6
7
8
9
10
11
12
13
from pymongo  import  * # 导包
con = Connection(...) # 链接
db = con.database # 链接数据库
db.authenticate( 'username' 'password' ) # 登录
db.drop_collection( 'users' ) #删除表
db.logout() # 退出
db.collection_names() # 查看所有表
db.users.count() # 查询数量
db.users.find_one({ 'name'  'xiaoming' }) # 单个对象
db.users.find({ 'age'  18 }) # 所有对象
db.users.find({ 'id' : 64 }, { 'age' : 1 , '_id' : 0 }) # 返回一些字段 默认_id总是返回的  0 不返回  1 返回
db.users.find({}).sort({ 'age' 1 }) # 排序
db.users.find({}).skip( 2 ).limit( 5 ) # 切片


测试的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/usr/bin/env python
from pymongo  import  Connection
import  time,datetime
import  os,sys
connection = Connection( '127.0.0.1' 27017 )
db = connection[ 'xiaorui' ]
def func_time(func):
     def _wrapper(*args,**kwargs):
         start = time.time()
         func(*args,**kwargs)
         print func.__name__, 'run:' ,time.time()-start
     return  _wrapper
@func_time
def ainsert(num):
     posts = db.userinfo
     for  in  range(num):
         post = { "_id"  : str(x),
         "author" : str(x)+ "Mike" ,
         "text" "My first blog post!" ,
         "tags" : [ "xiaorui" "xiaorui.cc" "rfyiamcool.51cto" ],
         "date" : datetime.datetime.utcnow()}
         posts.insert(post)
if  __name__ ==  "__main__" :
     num = sys.argv[ 1 ]
     ainsert( int (num))

咱们就先来个百万的数据做做测试~

综合点的数据:

002508131.jpg

在top下看到的程序占用资源的情况 ~ 我们看到的是有两个进程的很突出,对头 ! 正是mongodb的服务和我们正在跑的python脚本 !

002605855.jpg


看下服务的io的情况 ~

002741677.jpg


脚本运行完毕,总结下运行的时间 ~

002816300.jpg


查看mongodb的状态~

他的insert也不到5k ~ 插入量也就800k左右 ~

它的输出有以下几列:


inserts/s 每秒插入次数

query/s 每秒查询次数

update/s 每秒更新次数

delete/s 每秒删除次数

getmore/s 每秒执行getmore次数

command/s 每秒的命令数,比以上插入、查找、更新、删除的综合还多,还统计了别的命令

flushs/s 每秒执行fsync将数据写入硬盘的次数。

mapped/s 所有的被mmap的数据量,单位是MB,

vsize 虚拟内存使用量,单位MB

res 物理内存使用量,单位MB

faults/s 每秒访问失败数(只有Linux有),数据被交换出物理内存,放到swap。不要超过100,否则就是机器内存太小,造成频繁swap写入。此时要升级内存或者扩展

locked % 被锁的时间百分比,尽量控制在50%以下吧

idx miss % 索引不命中所占百分比。如果太高的话就要考虑索引是不是少了

q t|r|w 当Mongodb接收到太多的命令而数据库被锁住无法执行完成,它会将命令加入队列。这一栏显示了总共、读、写3个队列的长度,都为0的话表示mongo毫无压力。高并发时,一般队列值会升高。

conn 当前连接数

time 时间戳

瞅下面的监控数据 !

003310317.jpg

然后我们在测试下在一千万的数据下的消耗时间情况 ~

共用了2294秒,每秒插入 4359个数据 ~

010140526.jpg看看他的内存的使用情况:

虚拟内存在8gb左右,真实内存在2gb左右

010245223.jpg

再换成多线程的模式跑跑 ~  个人不太喜欢用多线程,这东西属于管你忙不忙,老大说了要公平,我就算抢到了,但是没事干,我也不让给你。。。属于那种蛮干的机制 ~


nima,要比单个跑的慢呀 ~  线程这东西咋会这么不靠谱呀 ~

应该是没有做线程池pool,拉取队列。导致线程过多导致的。不然不可能比单进程都要慢~

还有就是像这些涉及到IO的东西,交给协程的事件框架更加合理点 !!!


1
2
3
4
5
6
7
8
9
10
11
12
def goodinsert(a):
     posts.insert(a)
def ainsert(num):
     for  in  range(num):
         post = { "_id"  : str(x),
         "author" : str(x)+ "Mike" ,
         "text" "My first blog post!" ,
         "tags" : [ "mongodb" "python" "pymongo" ],
         "date" : datetime.datetime.utcnow()}
#       goodinsert(post)
         a=threading.Thread(target=goodinsert,args=(post,))
         a.start()


023536618.jpg


python毕竟有gil的限制,虽然multiprocess号称可以解决多进程的。但是用过的朋友知道,这个东西更不靠谱 ~  属于坑人的东西 ~

要是有朋友怀疑是python的单进程的性能问题,那咱们就用supervisord跑了几个后台的python压力脚本 ~ supervisord的配置我就不说了,我以前的文章里面有详述的 ~

015034609.jpg

cpu方面是跑的有点均匀了,但是mongodb那边的压力总是上不去

当加大到16个后台进程做压力测试的时候 ~ 大家会发现insert很不稳定。 看来他的极限也就是2MB左右的数据 ~

015448335.jpg

当减少到8个压力进程的时候 ~ 我们发现他的insert慢慢的提供到正常了,也就是说  他真的是2MB的极限 ~

015559242.jpg

脚本里面是有做有序的id插入的,我们试试把id的插入给去掉,看看有没有提升~

结果和不插入id差不多的结果 ~

085221687.jpg

调优之后~ 再度测试

ulimit的优化

1
2
3
cat /etc/security/limits.conf
*       soft   nofile        102400
*       hard   nofile        102400


内核的tcp优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
cat /etc/sysctl.conf
net.ipv4.tcp_syncookies =  1
net.ipv4.tcp_tw_reuse =  1
net.ipv4.tcp_tw_recycle =  1
net.ipv4.tcp_timestsmps =  0
net.ipv4.tcp_synack_retries =  2
net.ipv4.tcp_syn_retries =  2
net.ipv4.tcp_wmem =  8192  436600  873200
net.ipv4.tcp_rmem =  32768  436600  873200
net.ipv4.tcp_mem =  94500000  91500000  92700000
net.ipv4.tcp_max_orphans =  3276800
net.ipv4.tcp_fin_timeout =  30
#直接生效
/sbin/sysctl -p

启动的时候,加上多核的优化参数

1
多核问题可以在启动时加入启动参数: numactl --interleave=all


insert的频率已经到了2w左右 ~  内存占用了8G左右 ~


143629965.png

143630829.png



我想到的一个方案:

当然不用非要celery,就算咱们用socket写分发,和zeromq的pub sub也可以实现这些的。这是celery的调度更加专业点。

021114653.jpg

刚才我们测试的都是insert,现在我们再来测试下在千万级别数据量下的查询如何:

查询正则的,以2开头的字符

1
2
3
posts = db.userinfo
for  in  posts.find({ "author" :re.compile( '^2.Mike' )}):
     print i


013606877.jpg

精确的查询:

查询在5s左右 ~

013944841.jpg


225244177.jpg225244313.jpg


225244670.jpg

225244798.jpg


总结:

典型的高读低写数据库 !






 本文转自 rfyiamcool 51CTO博客,原文链接:http://blog.51cto.com/rfyiamcool/1329351,如需转载请自行联系原作者




相关文章
|
11月前
|
监控 安全 Shell
管道符在渗透测试与网络安全中的全面应用指南
管道符是渗透测试与网络安全中的关键工具,既可用于高效系统管理,也可能被攻击者利用实施命令注入、权限提升、数据外泄等攻击。本文全面解析管道符的基础原理、实战应用与防御策略,涵盖Windows与Linux系统差异、攻击技术示例及检测手段,帮助安全人员掌握其利用方式与防护措施,提升系统安全性。
466 6
|
9月前
|
安全 数据管理 测试技术
告别蛮力:让测试数据生成变得智能而高效
告别蛮力:让测试数据生成变得智能而高效
686 120
|
存储 人工智能 测试技术
HarmonyOS Next~HarmonyOS应用测试全流程解析:从一级类目上架到二级类目专项测试
本文深入解析HarmonyOS应用测试全流程,涵盖从一级类目通用测试到二级类目专项测试的技术方案。针对兼容性、性能、安全测试及分布式能力验证等关键环节,提供详细实践指导与代码示例。同时,结合典型案例分析常见问题及优化策略,帮助开发者满足华为严苛的质量标准,顺利上架应用。文章强调测试在开发中的核心地位,助力打造高品质HarmonyOS应用。
719 2
|
存储 NoSQL MongoDB
【赵渝强老师】MongoDB写入数据的过程
在MongoDB数据更新时,WiredTiger存储引擎通过预写日志(Journal)机制先将更新写入日志文件,再通过检查点操作将日志中的操作刷新到数据文件,确保数据持久化和一致性。检查点定期创建,缩短恢复时间,并保证异常终止后可从上一个有效检查点恢复数据。视频讲解及图示详细说明了这一过程。
435 23
【赵渝强老师】MongoDB写入数据的过程
|
10月前
|
人工智能 数据可视化 测试技术
AI 时代 API 自动化测试实战:Postman 断言的核心技巧与实战应用
AI 时代 API 自动化测试实战:Postman 断言的核心技巧与实战应用
1186 11
|
人工智能 缓存 自然语言处理
别再手搓测试数据了!AE测试数据智造系统揭秘
本文介绍如何通过构建基于大语言模型的测试数据智造Agent,解决AliExpress跨境电商测试中数据构造复杂、低效的问题,推动测试效率提升与智能化转型。
别再手搓测试数据了!AE测试数据智造系统揭秘
|
10月前
|
存储 测试技术 API
数据驱动开发软件测试脚本
今天刚提交了我的新作《带着ChatGPT玩转软件开发》给出版社,在写作期间跟着ChatGPT学到许多新知识。下面分享数据驱动开发软件测试脚本。
403 0
|
安全 测试技术 Linux
Flawnter 5.9.1 (macOS, Linux, Windows) - 应用程序安全测试软件
Flawnter 5.9.1 (macOS, Linux, Windows) - 应用程序安全测试软件
432 2
Flawnter 5.9.1 (macOS, Linux, Windows) - 应用程序安全测试软件
|
11月前
|
机器学习/深度学习 存储 分布式计算
Java 大视界 --Java 大数据机器学习模型在金融风险压力测试中的应用与验证(211)
本文探讨了Java大数据与机器学习模型在金融风险压力测试中的创新应用。通过多源数据采集、模型构建与优化,结合随机森林、LSTM等算法,实现信用风险动态评估、市场极端场景模拟与操作风险预警。案例分析展示了花旗银行与蚂蚁集团的智能风控实践,验证了技术在提升风险识别效率与降低金融风险损失方面的显著成效。
|
11月前
|
人工智能 IDE 测试技术
Browser-Use在UI自动化测试中的应用
Browser-Use是一款浏览器自动化工具,具备视觉与HTML解析、多标签管理、操作记录与复现、自定义操作、自我纠正及并行执行等功能,助力AI智能体高效完成网页任务。
1488 0