Tornado 中 PyMongo Motor MongoEngine 的性能测试
最近在使用 Tornado 开发 API,数据库选择了 MongoDB,因为想使用 Geo 搜索的特性。Python 可供选择的 MongoDB Drivers 可以在官网查找。
在这些 Drivers 中,GitHub 上 Star 数最多的有 3 个:
- PyMongo
- Motor (适用于 Tornado 的异步 driver)
- MongoEngine (ORM-like Layers)
Motor 和 MongoEngine 都是基于 PyMongo,Motor 的最新版是基于 PyMongo 2.8,Motor 的优势就在于异步,而 PyMongo 在 2.2 以后的版本,就开始支持 gevent。
MongoEngine 借鉴了 Django 的 ORM,提供了一个 ORM-like layer,官方称作 Document-Object Mapper,可以像使用 Django 的 ORM 一样,简单的操作和处理数据。
面对这么多选择,就想探究这些选择都有哪些特点,性能如何,所以有了这篇文章。你可以在这里找到所有的测试代码和测试数据
https://github.com/restran/tornado-mongodb-performance-test
HTTP 性能测试工具
HTTP 性能测试工具可以选择:
- pylot (由 Python 开发)
- ab - Apache HTTP server benchmarking tool
这里的测试使用 ab,安装方法
sudo apt-get install apache2-utils
测试配置
测试的配置如下
- Tornado 程序位于一台 Ubuntu 14.04 x86_64 的虚拟机,2 GB 内存,2 核心 CPU,2.59 GHz。
- MongoDB 3.06 x86_64 Windows 版,在一台 Windows 2008 R2 的虚拟机,4 GB 内存,2 核心 CPU,2.39 GHz。
- MongoDB 数据库中已经预先插入 100W 条数据,以下所有的实验都是测试从数据库中读数据的性能。
- Tornado 使用最新的 4.2.1 版。
数据库中的数据是这个样子的
{
"_id": {
"$oid": "5630cd05f7732b28a81f57fa"
},
"title": "Post title",
"created": {
"$date": "2015-10-28T21:26:29.271+0000"
}
}
Tornado 中查询数据的 Handler 是这个样子的,以 PyMongo 3.0 为例。
class QueryHandler(APIHandler):
def get(self):
cursor = self.database.post.find(limit=30)
json_data = []
for t in cursor:
j = {
'_id': text_type(t['_id']),
'title': t['title'],
'created': t['created'].strftime('%Y-%m-%d %H:%M:%S')
if t['created'] else None
}
json_data.append(j)
self.success(json_data)
测试说明
在实际测试的时候,发现在 PyMongo 2.8 的环境下,PyMongo 2.8 和 MongoEngine 性能都很差,因此设置了两组测试。
测试 1
总共 10000 个请求,每次并发 100 个(同时发送 100 个),使用如下命令
ab -n 10000 -c 100 http://127.0.0.1:8500/api/posts/query/
实验对象:
- Motor(Mortor 最新版是基于 PyMongo 2.8)
- PyMongo 3.0
- PyMongo 3.0 + gevent(PyMongo 支持 gevent)
- MongoEngine + PyMongo 3.0
PyMongo 开启 gevent 的方法,可以参考
https://api.mongodb.org/python/current/examples/gevent.html
测试 2
总共 100 个请求,每次并发 10 个(同时发送 10 个),使用如下命令
ab -n 100 -c 10 http://127.0.0.1:8500/api/posts/query/
实验对象:
- PyMongo 2.8
- PyMongo 2.8 + gevent
- MongoEngine + PyMongo 2.8
Virtualenv
由于要使用不同版本的 PyMongo,因此使用了 Virtualenv 来创建不同的环境。
Windows 环境下的 virtualenv,命令会有些不一样,这里的命令适用于 Linux。
安装
sudo pip install virtualenv
创建一个虚拟的 Python 环境
virtualenv env_name
创建测试需要的两个环境
virtualenv pymongo2.8
virtualenv pymongo3.0
激活虚拟环境,安装相应的包
cd pymongo2.8
source bin/activate
pip install pymongo==2.8.0 tornado mongoengine motor gevent
对虚拟环境 pymongo3.0 执行相应的操作
cd pymongo3.0
source bin/activate
pip install pymongo==3.0.6 tornado mongoengine gevent
用虚拟环境中的 Python 启动 Tornado 程序
/path/to/pymongo2.8/bin/python pymongo2.8_app.py
测试结果
先给出两组测试结果的数据:完成所有请求的耗时,吞吐量(每秒处理的请求数)
从测试的结果来看,Motor 的性能确实很好,gevent 几乎没有性能提升,PyMongo 2.8 的性能很差,MongoEngine 是在 PyMongo 的基础上有封装了一层,但是两者性能相差不大。
Tornado 的单线程的,同步的数据库 Driver 会将 Tornado 阻塞住,导致无法处理其他的请求。
最后给出一组数据,百分比请求的最大响应时间。下面这张图,左边坐标的单位是毫秒。例如 Motor 有 50% 的请求是在 376 毫秒内完成的。
PyMongo 2.8,PyMongo 2.8 + gevent,MongoEngine + PyMongo 2.8 三条线重叠在了一起,它们之间的性能相当。
Tornado 中 PyMongo Motor MongoEngine 的性能测试的更多相关文章
- 在 tornado 中异步无阻塞的执行耗时任务
在 tornado 中异步无阻塞的执行耗时任务 在 linux 上 tornado 是基于 epoll 的事件驱动框架,在网络事件上是无阻塞的.但是因为 tornado 自身是单线程的,所以如果我们在 ...
- Tornado 中的 get() 或 post() 方法
---恢复内容开始--- Tornado 中的 get() 或 post() 方法 请求处理程序和请求参数 Tornado 的 Web 程序会将 URL 或者 URL 范式映射到 tornado.we ...
- tornado中使用torndb,连接数过高的问题
问题背景 最近新的产品开发中,使用了到了Tornado和mysql数据库.但在基本框架完成之后,我在开发时候发现了一个很奇怪的现象,我在测试时,发现数据库返回不了结果,于是我在mysql中输入show ...
- 在tornado中使用celery实现异步任务处理之中的一个
一.简单介绍 tornado-celery是用于Tornado web框架的非堵塞 celeryclient. 通过tornado-celery能够将耗时任务增加到任务队列中处理, 在celery中创 ...
- 深入tornado中的协程
tornado使用了单进程(当然也可以多进程) + 协程 + I/O多路复用的机制,解决了C10K中因为过多的线程(进程)的上下文切换 而导致的cpu资源的浪费. tornado中的I/O多路复用前面 ...
- 深入tornado中的TCPServer
1 梳理: 应用层的下一层是传输层,而http协议一般是使用tcp的,所以实现tcp的重要性就不言而喻. 由于tornado中实现了ioloop这个反应器以及iostream这个对连接的异步读写,所以 ...
- 深入tornado中的http1connection
前言 tornado中http1connection文件的作用极其重要,他实现了http1.x协议. 本模块基于gen模块和iostream模块实现异步的处理请求或者响应. 阅读本文需要一些基础的ht ...
- 基于python3.x,使用Tornado中的torndb模块操作数据库
目前Tornado中的torndb模块是不支持python3.x,所以需要修改部分torndb源码即可正常使用 1.开发环境介绍 操作系统:win8(64位),python版本:python3.6(3 ...
- Python设计模式中单例模式的实现及在Tornado中的应用
单例模式的实现方式 将类实例绑定到类变量上 class Singleton(object): _instance = None def new(cls, *args): if not isinstan ...
随机推荐
- [题解] CodeM美团点评编程竞赛资格赛题
最近看到牛课网美团一个编程竞赛,想着做做看,结果一写就是两天..真是写不动了啊.话不多说,下面开始我的题解. 题目大致还是比较考察思维和代码能力(因为自己代码能力较弱,才会觉得比较考察代码能力吧= = ...
- test20180921 量子纠缠
题意 问题描述 万能的红太阳J 君正在研究量子信息的纠缠. 具体来说,J 君有一个初始为空的信息集.她会进行m 次操作,有时,她会向信息集内加入一个长度不超过L 的的数字串(一个数字串为一个仅由0 到 ...
- 自己一下午练习Js的代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- MVC5 + EF6 + Bootstrap3系列教程
本系列教程以ASP.NET MVC5为核心框架,使用Entity Framewok6访问数据,并使用Bootstrap3作为前端UI框架.帮助大家开发出一套高效.美观.稳定.实用的软件系统. MVC5 ...
- JS 网页快捷键设置
我们希望能用快捷键代替鼠标点击做一些事情,例如一个典型的应用就是论坛上常用的Ctrl + Enter 快捷发帖子.就以Ctrl+Enter快捷发帖子为例,实质上呢,就是通过JS脚本,捕获系统的onke ...
- spring 注解列表
table th:first-of-type { width: 15%; } table th:nth-of-type(2) { } 注解 作用 例子 @SuppressWarnings 忽略警告 类 ...
- druid:阿里巴巴开源,数据库连接池管理
官方地址:https://github.com/alibaba/druid
- DBA的规范
DBA操作规范 1.涉及业务上的修改/删除数据,在得到业务方.CTO的邮件批准后方可执行,执行前提前做好备份,必要时可逆. 2.所有上线需求必须走工单系统,口头通知视为无效. 3.在对大表做表 ...
- innotop监控mysql
InnoTop 是一个系统活动报告,类似于Linux性能工具,它与Linux的top命令相仿,并参考mytop工具而设计. 它专门用后监控InnoDB性能和MySQL服务器.主要用于监控事务,死锁,外 ...
- Modbus tcp 格式说明 通讯机制 附C#测试工具用于学习,测试
前言: 之前的博客介绍了如何用C#来读写modbus tcp服务器的数据,文章:http://www.cnblogs.com/dathlin/p/7885368.html 当然也有如何创建一个服务器文 ...