gpt4 book ai didi

python - 提高 SQLAlchemy 的性能?

转载 作者:太空宇宙 更新时间:2023-11-03 16:11:52 27 4
gpt4 key购买 nike

我目前正在为我正在为我的应用程序开发的 API 后端运行 Flask + SQLAlchemy + uWSGI + nginx 堆栈。我试图通过使用 ApacheBench 并向服务器上的端点发送不同数量的并发请求来查看我的服务器上可以拥有的最大并发连接量。

此端点将采用 JSON 请求正文,提取某些值,运行查询,然后根据查询结果返回 JSON 响应。

我对 10 个请求运行了 1 个并发请求的基本测试,平均响应时间为 60 毫秒。
运行另一项测试,其中 100 个请求的 10 个并发请求平均返回 150 毫秒,1000 个请求的100 个并发请求平均返回 1500 毫秒,500 个并发请求返回约 1500 毫秒。 7000-9000 毫秒。

Concurrency Level:      500
Time taken for tests: 38.710 seconds
Complete requests: 5000
Failed requests: 0
Total transferred: 1310000 bytes
Total body sent: 1105000
HTML transferred: 110000 bytes
Requests per second: 129.17 [#/sec] (mean)
Time per request: 3870.986 [ms] (mean)
Time per request: 7.742 [ms] (mean, across all concurrent requests)
Transfer rate: 33.05 [Kbytes/sec] received
27.88 kb/s sent
60.93 kb/s total

Connection Times (ms)
min mean[+/-sd] median max
Connect: 24 63 185.1 25 3025
Processing: 161 3737 2778.7 3316 26719
Waiting: 157 3737 2778.7 3316 26719
Total: 187 3800 2789.7 3366 26744

Percentage of the requests served within a certain time (ms)
50% 3366
66% 4135
75% 4862
80% 5711
90% 7449
95% 9158
98% 11794
99% 13373
100% 26744 (longest request)

延迟似乎呈线性增加,这是有道理的,但它似乎增加得太快了。经过大量修改和分析后,我发现瓶颈在于查询。

在基准测试开始时,查询将在 10-50 毫秒内快速处理和返回,但它很快就会增加,在某些情况下会出现 10000-15000 毫秒的延迟。

我无法弄清楚为什么数据库速度如此之慢,特别是因为它是空的(除非测试数据)。

我尝试在没有连接池的情况下运行应用程序,结果显示延迟下降了(7-9 秒到 5-6 秒)。我认为这是不可能的,因为我读到的所有内容都表明拥有连接池总是会让事情变得更快,因为您可以避免每次发出请求时建立新连接的开销。

我还尝试增加连接池大小(从默认的 5 到 50),这比无池设置(5-6 秒到 3-4 秒)更能减少延迟。

Concurrency Level:      500
Time taken for tests: 4.842 seconds
Complete requests: 836
Failed requests: 0
Non-2xx responses: 679
Total transferred: 272673 bytes
Total body sent: 294593
HTML transferred: 126353 bytes
Requests per second: 172.67 [#/sec] (mean)
Time per request: 2895.662 [ms] (mean)
Time per request: 5.791 [ms] (mean, across all concurrent requests)
Transfer rate: 55.00 [Kbytes/sec] received
59.42 kb/s sent
114.42 kb/s total

Connection Times (ms)
min mean[+/-sd] median max
Connect: 24 170 273.1 93 1039
Processing: 25 665 1095.2 149 4753
Waiting: 25 665 1095.2 149 4753
Total: 51 835 1123.9 279 4786

Percentage of the requests served within a certain time (ms)
50% 279
66% 487
75% 1050
80% 1059
90% 2935
95% 3658
98% 4176
99% 4337
100% 4786 (longest request)

延迟仍然非常高(从任何标准来看,API 的 3-4 秒似乎都是不合理的),我正在尝试找出如何进一步降低延迟的方法。答案只是更多的联系吗?

注意:我正在一台具有 4GB 内存和四核处理器的服务器上运行 4 个 uWSGI 进程,每个进程有 100 个线程。我使用 psycopg2-cffi 适配器进行连接,并且该应用程序在 PyPy 上运行。

最佳答案

如果数据库必须按顺序处理您的查询,则线性增加是非常正常的。本质上,所有并发请求同时开始,但一个接一个完成,因此,假设一个池具有单个连接,每个请求 60 毫秒,10 个并发请求,您将看到请求花费 60 毫秒、120 毫秒、180 毫秒, 240ms, 300ms, 360ms, 420ms, 480ms, 540ms, 600ms, 600ms, ..., 600ms, 540ms, 480ms, ... .给定 n 个请求和 m 个并发请求,我们可以计算平均请求花费的时间:

f(n, m) = 60ms * (((m + 1) * m / 2) * 2 + (n - 2m) * m) / n
f(100, 10) = 546ms
f(1000, 100) = 5406ms
f(1000, 500) = 15,030ms

这些数字与您所看到的类似。

现在是个大问题。为什么数据库几乎按顺序处理查询?我可以想到几个原因:

  • 锁定:每个启动的事务都需要独占锁定某些资源,以便一次只能运行一个(或几个)事务
  • CPU 密集型查询:每个事务都会占用大量 CPU 资源,因此其他事务必须等待 CPU 时间
  • 大型表扫描:数据库无法将整个表保留在内存中,因此每个事务都必须从磁盘读取

你如何解决这个问题?这是一个复杂的问题,但有一些潜在的解决方案:

  • 优化您的查询;要么对其进行优化,以便它们不会都争夺相同的资源,要么对其进行优化,以便它们不需要那么长时间
  • 批量查询,以便您需要运行的总量更少
  • 缓存您的响应,以便它们根本不会访问数据库

关于python - 提高 SQLAlchemy 的性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39218781/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com