Python異步讀寫Mongodb(motor+asyncio)

使用Python做大型計(jì)算任務(wù)時(shí),并且用mongodb做數(shù)據(jù)儲(chǔ)存時(shí),常常面臨大量讀寫數(shù)據(jù)庫的情況。尤其是大量更新任務(wù),由于不能批量操作,使用pymongo同步操作的話,相當(dāng)耗時(shí)。

使用多線程、多進(jìn)程確實(shí)有效,但編寫麻煩、消耗系統(tǒng)資源大(pymongo還不允許fork線程中共用連接)。這里主要瓶頸在于IO,使用單線程異步操作就會(huì)效果很好。

Motor是一個(gè)異步mongodb driver,支持異步讀寫mongodb。它通常用在基于Tornado的異步web服務(wù)器中。
Motor同時(shí)支持使用asyncio(Python3.4以上標(biāo)準(zhǔn)庫)作為異步模型,使用起來十分方便。

下面是一個(gè)對(duì)比例子。從某個(gè)mongodb集合中,遍歷讀取所有數(shù)據(jù),并update回去。update速度是主要瓶頸。
這里我們事先定義好,數(shù)據(jù)庫位于127.0.0.1:27017,數(shù)據(jù)庫名為testdb,集合名為test。我們處理其中title和content兩個(gè)較大的字段。

host = '127.0.0.1'
port = 27017
database = 'testdb'

下面是使用pymongo同步處理的例子:

from pymongo import MongoClient

connection = MongoClient(
    host,
    port
)
db = connection[database]

for doc in db.post.find({}, ['item_id', 'title', 'content']):
    db.post.update({'item_id': doc.get('item_id')}, {
        '$set': {
            'title': doc.get('title'),
            'content': doc.get('title')
        }
    })

以下是使用了asyncio和motor的例子:

import asyncio
from motor.motor_asyncio import AsyncIOMotorClient

connection = AsyncIOMotorClient(
    host,
    port
)
db = connection[database]

async def run():
    async for doc in db.post.find({}, ['item_id', 'title', 'content']):
        db.post.update({'item_id': doc.get('item_id')}, {
            '$set': {
                'title': doc.get('title'),
                'content': doc.get('content'),
            }
        })

asyncio.get_event_loop().run_until_complete(run())

這里測試異步讀寫速度是同步的200倍左右(實(shí)際情況受IO時(shí)間影響,不一定是這個(gè)比例)。

可見,使用motor+asyncio做快速mongodb讀寫,方便有效。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容