測試基本信息
主題:比較異步框架和同步框架在RedisIO操作的性能差異
python版本:python 3.8
數據庫:redis 5.0.7
壓測工具:locust
web框架:同步:flask 異步:starlette
請求併發量: 模擬10個用戶
服務器配置: Intel(R) i7-12700F
客戶端配置:Intel(R) i7-8700 3.20GHz
flask 同步框架
flask是python中輕量級web框架,特點是靈活、輕量級、擴展性高。同時flask是一個同步框架,操作Redis使用的是官方最推薦的包redis-py。redis-py早期版本只支持同步模式,高版本中已經支持異步模式。接口功能非常簡單,連接Redis從中讀取一個key,已經提前寫入redis。
from flask import Flask
from redis import StrictRedis
app = Flask(__name__)
@app.route('/user')
def user_list():
redis_conn = StrictRedis(host="127.0.0.1", port=6379, decode_responses=True)
res = redis_conn.get("name")
return res
if __name__ == '__main__':
app.run(port=8090, host="0.0.0.0")
壓測結果
併發量:342
starlette 異步框架
starlette 是當下火熱的異步框架fastapi依賴的唯二模塊之一,主要用於異步請求的處理。redis-py 既支持同步模式又支持異步模式,所以在starlette這個異步框架中就使用其異步模式。
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Route
from uvicorn.main import run
from redis.asyncio import StrictRedis
async def user(request):
redis_conn = StrictRedis(host="127.0.0.1", port=6379, decode_responses=True)
res = await redis_conn.get("name")
await redis_conn.close()
return JSONResponse(res)
app = Starlette(debug=True, routes=[Route('/user', user),])
if __name__ == "__main__":
run(app, host="0.0.0.0")
壓測結果
併發量:1361
對比
併發曲線圖對比:
參數對比:
框架 | Redis IO | 純框架無IO | 文件IO | 數據庫IO |
---|---|---|---|---|
flask | 315 | 463 | 453 | 225 |
starlette | 1361 | 1539 | 1538 | 1496 |
性能比(異步/同步) | 4.3 | 3.3 | 3.4 | 6.6 |
總結
在Redis IO方面,異步框架的性能是同步框架的4.3倍左右,和文件IO、數據庫IO大體一致。橫向和數據庫IO比較略有下降,多次測試確實如此,猜測和redis-py模塊的異步模式有關。
本篇是對比系列最後一篇。從異步密切相關的IO任務對比中可以切實看出異步編程的併發量比較高,後續篇幅中將講解python中異步編程的原理和使用。