如果使用Python做大型海量数据批量任务时,并且backend用mongodb做数据储存时,常常面临大量读写数据库的情况。尤其是大量更新任务,由于不能批量操作,我们知道pymongo是同步任务机制,相当耗时。
如果采用多线程、多进程的方案确实有效,但编写麻烦、消耗系统资源大(pymongo还不允许fork线程中共用连接)。这里主要瓶颈在于IO,使用单线程异步操作就会效果很好。
Motor是一个异步mongodb driver,支持异步读写mongodb。它通常用在基于Tornado的异步web服务器中。
我们来测试一下效率,使用传统pymongo来进行批量读写 mongo_test.py:
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
| host = '127.0.0.1' port = 27017 database = 'LiePin'
import time
start = time.clock()
from pymongo import MongoClient
connection = MongoClient( host, port ) db = connection[database]
for doc in db.LiePin_Analysis1.find({}, ['_id', 'JobTitle', 'is_end']): db.LiePin_Analysis1.update_one({'_id': doc.get('_id')}, { '$set': { 'is_end': 1 } })
elapsed = (time.clock() - start) print("Time used:",elapsed)
|
运行一下,发现用了4秒左右
再使用motor以异步的形式来编写脚本motor_test.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| 主机= '127.0.0.1' 端口= 27017 数据库= '劣品'
进口时间
开始= 时间。时钟()
从电机导入asyncio 。motor_asyncio 导入AsyncIOMotorClient
connection = AsyncIOMotorClient ( host , 港口 ) db = connection [ 数据库]
异步DEF 运行(): 异步用于文档的数据库。LiePin_Analysis1 。找到({},[ '_id' ,'JOBTITLE' ,'is_end' ]): 分贝。LiePin_Analysis1 。update_one ({ '_id' :DOC ,得到('_id' )},{ '$集' :{ 'is_end' :0 }})
asyncio 。get_event_loop ()。run_until_complete (run ())
经过= (时间,时钟()- 启动)打印(“使用时间” ,经过)
|
仅仅1秒左右就完成了任务
效率由此可见一般
Author:
Wenng
Slogan:
Do you believe in DESTINY?