Bo *_*ker 11 mongodb pymongo python-asyncio
我有一个用 python 和异步框架 Starlette ( https://www.starlette.io/ ) 编写的 Web 应用程序,我需要连接到 MongoDB,所以我安装了异步 pymongo 驱动程序: motor ( https://motor.readthedocs .io/en/stable/)版本 2.1.0
我有一些像这样的伪代码:
motor_client = motor.motor_asyncio.AsyncIOMotorClient(...)
pymongo_client = pymongo.MongoClient(...)
class BlogList(HTTPEndpoint):
async def get(self, request):
blog_list = [item async for item in motor_client.blog.find(condition)]
# blog_list = list(pymongo_client.blog.find(condition))
data = {
"request": request,
"blogs": blog_list,
}
return RenderPageResponse("index.html", data)
Run Code Online (Sandbox Code Playgroud)
对于blog_list这里的行,我用以下方法对其进行了基准测试wrk -t10 -d10 -c100 http://localhost:8080/blog:
motor_clientwith await,结果约为“1500 个请求/秒”pymongo_client(同步模式),结果约为“1900 个请求/秒”使用电机的异步模式不应该比使用 pymongo 的同步模式更快吗?我想知道为什么使用 motor(异步,1500 req/s)时的性能比 pymongo(sync,1900 req/s)差得多?
其他信息:我使用 运行我的 starlette 应用程序gunicorn -w 4 -k uvicorn.workers.UvicornWorker myblog:app,只需切换这两行即可进行wrk基准测试。
我进行了搜索,但找不到谈论此问题的帖子,所以我想知道我错过了什么吗?任何帮助将不胜感激,谢谢。
Nes*_*vij 11
也许问题是由于电机实际上不是异步驱动器。它只是在ThreadPoolExecutor中启动同步pymongo,因此性能下降。不幸的是,目前 python 上没有 mongo 的异步驱动程序:(
小智 9
我使用fastapi对此做了一些实验
首先将1515个文档添加到mongodb中的集合中
然后定义3个测试用例
测试用例1
使用pymongo从同步函数从数据库中获取文档
@app.get("/get_data")
def read_data():
cursor = coll.find({})
li = []
for rec in cursor:
li.append(rec)
length = len(li)
return {"length": length}
Run Code Online (Sandbox Code Playgroud)
测试用例 2
使用pymongo从异步函数中从数据库获取文档
@app.get("/get_data")
async def read_data():
cursor = coll.find({})
li = []
for rec in cursor:
li.append(rec)
length = len(li)
return {"length": length}
Run Code Online (Sandbox Code Playgroud)
测试用例 3
使用motor从异步函数中从数据库获取文档
@app.get("/get_data")
async def read_data():
cursor = coll.find({})
li = []
async for document in cursor:
li.append(document)
return {"length": len(li)}
Run Code Online (Sandbox Code Playgroud)
使用 uvicorn 运行具有 5 个工作人员的应用程序
uvicorn test:app --host 0.0.0.0 --port 8000 --workers 5
使用Locust来测试
代码:
class HelloWorldUser(HttpUser):
@task
def hello_world(self):
self.client.get("/get_data")
Run Code Online (Sandbox Code Playgroud)
配置:
模拟的总用户数= 50
生成率(每秒)= 10
结果
测试案例1
{
"Type":["GET"],
"Name":["/get_data"],
"Request Count":[1546],
"Failure Count":[0],
"Median Response Time":[1300],
"Average Response Time":["1409.07469337902"],
"Min Response Time":["213.365600000543"],
"Max Response Time":["6493.73753599866"],
"Average Content Size":[15],
"Requests/s":["32.9464475484361"],
"Failures/s":[0],
"50%":[1300],
"66%":[1500],
"75%":[1700],
"80%":[1900],
"90%":[2300],
"95%":[2700],
"98%":[3200],
"99%":[3600],
"99.9%":[5200],
"99.99%":[6500],
"100%":[6500]
}
Run Code Online (Sandbox Code Playgroud)
测试案例2
{
"Type":["GET"],
"Name":["/get_data"],
"Request Count":[1586],
"Failure Count":[0],
"Median Response Time":[2000],
"Average Response Time":["2108.97265052965"],
"Min Response Time":["261.412365001888"],
"Max Response Time":["5301.57826199866"],
"Average Content Size":[15],
"Requests/s":["22.4672730359705"],
"Failures/s":[0],
"50%":[2000],
"66%":[2400],
"75%":[2500],
"80%":[2700],
"90%":[2900],
"95%":[3300],
"98%":[3600],
"99%":[4100],
"99.9%":[5100],
"99.99%":[5300],
"100%":[5300]
}
Run Code Online (Sandbox Code Playgroud)
测试用例3
{
"Type":["GET"],
"Name":["/get_data"],
"Request Count":[1662],
"Failure Count":[0],
"Median Response Time":[1200],
"Average Response Time":["1388.38606281409"],
"Min Response Time":["116.913538000517"],
"Max Response Time":["7983.01199100024"],
"Average Content Size":[15],
"Requests/s":["33.5720588256683"],
"Failures/s":[0],
"50%":[1200],
"66%":[1500],
"75%":[1700],
"80%":[1900],
"90%":[2300],
"95%":[2700],
"98%":[3400],
"99%":[4100],
"99.9%":[6800],
"99.99%":[8000],
"100%":[8000]
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12771 次 |
| 最近记录: |