【发布时间】:2014-04-30 02:12:03
【问题描述】:
我工作的公司决定将他们的整个堆栈转移到 Heroku。主要动机是它的易用性:没有系统管理员,没有哭泣。不过我还是有一些疑问...
我正在对应用程序平台和 Postgres 服务进行一些负载和压力测试。我使用blitz 作为 Heroku 的插件。我攻击了用户数量在 1 到 250 之间的网站。我得到了一些非常有趣的结果,我需要帮助来评估它们。
测试堆栈:
应用规范
它并没有什么特别之处。
- Rails 4.0.4
- 独角兽
-
database.yml设置为连接到 Heroku postgres。 - 不使用缓存。
数据库
这是一个Standard Tengu(Heroku 的命名约定总有一天会害死我的 :) 正确连接到应用程序。
Heroku 配置
按照“Deploying Rails Applications With Unicorn”文章中的说明,我在unicorn.rb 上应用了所有内容。我有 2 个常规网络测功机。
WEB_CONCURRENCY : 2
DB_POOL : 5
数据
-
episodes桌数100.000~ -
episode_urls表数 300.000~ -
episode_images桌数 75.000~
代码
episodes_controller.rb
def index
@episodes = Episode.joins(:program).where(programs: {channel_id: 1}).limit(100).includes(:episode_image, :episode_urls)
end
episodes/index.html.erb
<% @episodes.each do |t| %>
<% if !t.episode_image.blank? %>
<li><%= image_tag(t.episode_image.image(:thumb)) %></li>
<% end %>
<li><%= t.episode_urls.first.mas_path if !t.episode_urls.first.blank?%></li>
<li><%= t.title %></li>
<% end %>
场景 #1:
Web dynos : 2
Duration : 30 seconds
Timeout : 8000 ms
Start users : 10
End users : 10
结果:
HITS 100.00% (484)
ERRORS 0.00% (0)
TIMEOUTS 0.00% (0)
这次冲刺在 30.00 秒内产生了 218 次成功命中,我们 将 6.04 MB 的数据传入和传出您的应用程序。平均命中 7.27/秒的速率转化为大约 627,840 次点击/天。
场景 #2:
Web dynos : 2
Duration : 30 seconds
Timeout : 8000 ms
Start users : 20
End users : 20
结果:
HITS 100.00% (484)
ERRORS 0.00% (0)
TIMEOUTS 0.00% (0)
这次冲刺在 30.00 秒内产生了 365 次成功命中,我们 将 10.12 MB 的数据传入和传出您的应用程序。平均命中 12.17/秒的速率转化为大约 1,051,200 次点击/天。这 平均响应时间为 622 毫秒。
场景#3:
Web dynos : 2
Duration : 30 seconds
Timeout : 8000 ms
Start users : 50
End users : 50
结果:
HITS 100.00% (484)
ERRORS 0.00% (0)
TIMEOUTS 0.00% (0)
这次冲刺在 30.00 秒内产生了 371 次成功命中,我们 将 10.29 MB 的数据传入和传出您的应用程序。平均命中 12.37/秒的速率转化为大约 1,068,480 次点击/天。这 平均响应时间为 2,631 毫秒。
场景 #4:
Web dynos : 4
Duration : 30 seconds
Timeout : 8000 ms
Start users : 50
End users : 50
结果:
HITS 100.00% (484)
ERRORS 0.00% (0)
TIMEOUTS 0.00% (0)
这次冲刺在 30.00 秒内产生了 484 次成功命中,我们 将 13.43 MB 的数据传入和传出您的应用程序。平均命中 16.13/秒的速率转化为大约 1,393,920 次点击/天。这 平均响应时间为 1,856 毫秒。
场景#5:
Web dynos : 4
Duration : 30 seconds
Timeout : 8000 ms
Start users : 150
End users : 150
结果:
HITS 71.22% (386)
ERRORS 0.00% (0)
TIMEOUTS 28.78% (156)
这次冲刺在 30.00 秒内产生了 386 次成功命中,我们 将 10.76 MB 的数据传入和传出您的应用程序。平均命中 12.87/秒的速率转化为大约 1,111,680 次点击/天。这 平均响应时间为 5,446 毫秒。
场景 #6:
Web dynos : 10
Duration : 30 seconds
Timeout : 8000 ms
Start users : 150
End users : 150
结果:
HITS 73.79% (428)
ERRORS 0.17% (1)
TIMEOUTS 26.03% (151)
这次冲刺在 30.00 秒内产生了 428 次成功命中,我们 将 11.92 MB 的数据传入和传出您的应用程序。平均命中 14.27/秒的速率转化为大约 1,232,640 次点击/天。这 平均响应时间为 4,793 毫秒。你有更大的问题, 但是:26.21% 的用户在这个高峰期间经历了超时或 错误!
一般总结:
- 即使有 150 个用户向应用程序发送请求,“命中率”也不会超过 15 个。
- 越来越多的网络测功机无助于处理请求。
问题:
当我使用缓存和 memcached(Heroku 的 Memcachier 插件)时,即使是 2 个网络测功机也可以每秒处理 >180 次点击。我只是想了解 dynos 和 postgres 服务在没有缓存的情况下可以做什么。通过这种方式,我试图了解如何调整它们。怎么办?
据说标准 Tengu 有 200 个并发连接。那么为什么它从来没有达到这个数字呢?
如果拥有生产级别的数据库和增加 Web dynos 无助于扩展我的应用程序,那么使用 Heroku 有什么意义?
可能是最重要的问题:我做错了什么? :)
感谢您阅读这个疯狂的问题!
【问题讨论】:
-
大多数常用的 PostgreSQL 调优和诊断工具,如
pg_stat_statements、pg_stat_plans、auto_explain、pgbadger等都不适用于 Heroku。即使你愿意,你也没有太多可以在 Heroku 上调音的东西。也就是说:您如何确定数据库永远不会达到 200 个连接?另外,你为什么要它,除非它有 200 个 CPU 和一个高度并行的 I/O 子系统? -
我在 sql 控制台中使用
SELECT COUNT(*) from pg_stat_activity;命令,因此我可以看到活动连接。这就是我确定连接数的方式。当有 150 个请求进入我的应用程序时,我不应该假设有超过 15 个连接吗? -
不,不一定。除非数据库服务器 非常 大,否则最好使用更少的连接来更快地处理请求。见wiki.postgresql.org/wiki/Number_Of_Database_Connections
-
pg_stat_statements在 9.2+ 上默认可用并包含在内。
标签: ruby-on-rails postgresql heroku stress-testing