主题:比较异步框架和同步框架在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是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 是当下火热的异步框架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中异步编程的原理和使用。