所以我决定今天对我使用 Django REST Framework 开发的 REST API 进行基准测试。我发送的请求是一个 GET 请求,它基本上从数据库中检索最新的 50 个帖子并以 JSON 格式返回。
使用 Apache Benchmark,统计数据为:
Server Software: nginx/1.4.6
Concurrency Level: 100
Time taken for tests: 18.394 seconds
Complete requests: 1000
Failed requests: 0
Non-2xx responses: 1000
Total transferred: 5628000 bytes
HTML transferred: 5447000 bytes
Requests per second: 54.36 [#/sec] (mean)
Time per request: 1839.442 [ms] (mean)
Time per request: 18.394 [ms] (mean, across all concurrent requests)
Transfer rate: 298.79 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 17 1137 1899.3 31 12366
Processing: 25 189 314.2 31 1418
Waiting: 24 184 309.4 29 1415
Total: 44 1326 1846.3 888 12407
Percentage of the requests served within a certain time (ms)
50% 888
66% 1178
75% 1775
80% 2286
90% 3434
95% 4576
98% 7859
99% 7922
100% 12407 (longest request)
这显然非常慢......但我不确定如何改进这一点。
PS:我是开发服务器的新手,想从中学习。在上面的 GET 请求中,我没有在服务器端进行任何类型的线程处理。它所做的只是:
user_id = str(request.QUERY_PARAMS.get("user_id", None))
cur = connection.cursor()
cur.execute("SELECT * FROM get_posts(%s)", [user_id]) # This is a Function in the SQL database
return Response(convertToDict(cursor))
我想提高那个 GET 请求的速度,那么我能做些什么来让它更快呢?
最佳答案
好吧,看到原始 SQL 查询(这是另一个节目)我有点惊讶,但你可以做各种各样的事情。
TL;DR
前期
进行性能测试很棒,定期进行基准测试并随着时间的推移记录这些结果是一种很好的做法,但是要正确执行基准测试可能会很棘手:您必须将软件和硬件考虑在内 - 您的测试结果将在很大程度上取决于它们之间的交互两件事情。尽力为这些东西复制您的生产环境并尝试不同的配置(您是 12factor,对吗?)以确定合适的配置。
旁注:我对 AB 不是很熟悉,但看起来您也在根据似乎不是预期行为的输出返回 HTML。
解决问题
首先要做的是以深思熟虑的方式评估您所做的事情。
使用像
django-debug-toolbar
这样的东西看看你是否有一些查询瓶颈 - 许多链接在一起的查询,长时间运行的查询等。如果你需要更细化,你的数据库可能有日志功能来记录长查询。假设您的数据非常规范化(在正常形式的意义上),这可能是引入非规范化的地方,因此您不必遍历尽可能多的关系。
您还可以引入原始 SQL(但您似乎已经这样做了)。
您应该努力确保您的业务逻辑被放置在请求、响应周期的正确部分。很多时候你把东西放在地方只是为了让它工作,也许你最初的决定是找到它的限制。
看起来您正在做一些非常简单的事情:获取表中的最后 50 个条目。如果您正在计算是否包含帖子,您可能应该将其留给数据库 - 它应该在涉及检索哪些数据时处理所有逻辑。
当你这样做的时候,试着做更多的性能测试,看看你的代码有哪些地方落后了。也许您可以做一些事情来改进您的代码(同时使其他人易于阅读和理解)并给您带来性能提升。列表推导、生成器、利用 prefetch_ 和 select_related、注意延迟评估查询 - 所有这些都值得实现,因为它们的功能有很好的文档和理解。也就是说,一定要为你 future 的自己和可能的其他人仔细记录这些决定。
我不太熟悉 View 代码的实现,因为它与 Django REST 框架相关,我可能会坚持使用它附带的 JSON 序列化程序。
另一个有用的技巧是做一些事情,比如实现 pagination策略(但最有可能使用 REST Framework),因此数据只会以小 block 的形式传输到客户端。这将在很大程度上取决于用例。
这是一个很好的介绍:
用软件解决问题
您可以使用 cache将数据保存在服务器的 RAM 中,以便 Django 快速访问它。
通常,哪种缓存效果最好取决于数据本身。使用搜索引擎存储您经常查询的文档可能是最有用的。但是,一个好的开始是Redis .您可以从各种来源阅读有关实现缓存的所有信息,但使用 Django 进行搜索的好地方是 Django Packages。 .
用硬件解决问题
速度也可能与硬件有关。您应该考虑软件的要求及其依赖项。进行一些测试,四处搜索并尝试适合您的方法。在一个问题上投入更多的硬件会导致边际 yield 严重递减。
关于python - 如何提高 REST API 的性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32389142/