如何准备应对技术紧缩

发布于 2024-07-15 18:42:11 字数 288 浏览 12 评论 0原文

未来几天我们很可能会遇到技术难题。 不幸的是,我们还没有上线,所以我们无法很好地估计我们的系统如何处理制作观众。

我们的生产设置由 2 个 EngineYard 切片组成,每个切片都有 3 个混合实例,使用 Postgres 作为数据库服务器。

显然,我们的应用程序的运行方式很大一部分与我们的实际代码和查询等有关。但是,最好看看是否有任何关于预期负载类型的提示/指示或来自具有以下经验的人的经验经历过它。 6 个杂种实例(如果服务器可以承受的话可能是 8 个)听起来是否可以处理负载,或者至少可以处理大部分负载?

There is a good chance that we will be tech crunched in the next few days. Unfortunately, we have not gone live yet so we don't have a good estimation of how our system handles a production audience.

Our production setup consists of 2 EngineYard slices each with 3 mongrel instances, using Postgres as the database server.

Obviously a huge portion of how our app will hold up is to do with our actual code and queries etc. However, it would be good to see if there are any tips/pointers on what kind of load to expect or experiences from people who have been through it. Does 6 mongrel instances (possibly 8 if the servers can take it) sound like it will handle the load, or are at least most of it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

暮年慕年 2024-07-22 18:42:12

查看一些负载测试软件,例如 WEBLoad,或者如果您有钱,可以使用 Quick Test Pro。 这将有助于给您一些想法。 WEBLoad 可能是适合您情况的最佳测试。

您可以生成数千个访问您站点的虚拟节点,并且可以从该负载中检查服务器的性能。

Look into some load testing software like WEBLoad or if you have money, Quick Test Pro. This will help give you some idea. WEBLoad might be the best test in your situation.

You can generate thousands of virtual nodes hitting your site and you can inspect the performance of your servers from that load.

为人所爱 2024-07-22 18:42:12

根据我的经验,观察我们的一些客户吸收了嘎吱嘎吱的声音,流量相当适中,而不是人们所期望的碎骨峰值。 现在,如果你联合起来并在雅虎的页面或其他东西上制作,事情可能会有所不同。

如果您想了解他们如何处理它(雅虎 FP),请搜索 Facestat.com 的经验。

我的建议是,如果您的服务器变得太热,请准备好关闭注册或转到更静态的网站版本。 使用监控/分析工具也是一个好主意,我喜欢 FiveRuns Manage 工具,因为它易于设置。

In my experience having watched some of our customers absorb a crunching, the traffic was fairly modest- not the bone crushing spike people seem to expect. Now, if you get syndicated and make on Yahoo's page or something, things may be different.

Search for the experiences of Facestat.com if you want to read about how they handled it (the Yahoo FP.)

My advise is just be prepared to turn off signups or go to a more static version of your site if your servers get too hot. Using a monitoring/profiling tool is a good idea as well, I like FiveRuns Manage tool for ease of setup.

四叶草在未来唯美盛开 2024-07-22 18:42:12

由于您使用的是 EngineYard,因此您应该能够在必要时分配更多机器来处理负载

Since you're using EngineYard, you should be able to allocate more machines to handle the load if necessary

深陷 2024-07-22 18:42:12

您的大问题可能不是传入请求的数量,而是数据库中的数据量,显示您的查询没有使用您期望的索引,或者返回太多数据,例如“用户列表”页面有效有 10 个用户,但是当您尝试在该页面上显示 10,000 个用户时,它会死掉,因为您没有添加分页(will_paginate 插件几乎是您的朋友 - 请注意为您生成的“select count(*)”查询)

所以需要注意的两件事:

  1. 缺少索引
  2. 每页数据太多

对于#1,有一个插件可以在每次查询后运行“解释...”查询,以便您可以手动检查索引使用情况

有一个插件可以为您生成数据各种类型的数据也可以帮助您填充数据库以测试这些查询。

对于#2,使用 will_paginate 插件或其他方式来减少每页数据。

Your big problems will probably not be the number of incoming requests, but will be the amount of data in your database showing you where your queries aren't using the indexes your expecting, or are returning too much data, e.g. The User List page works with 10 users, but dies when you try to show 10,000 users on that one page because you didn't add pagination (will_paginate plugin is almost your friend - watch out for 'select count(*)' queries that are generated for you)

So the two things to watch:

  1. Missing indexes
  2. Too much data per page

For #1, there's a plugin that runs an 'explain ...' query after every query so you can check index usage manually

There is a plugin that can generate data for you for various types of data that may help you fill your database up to test these queries too.

For #2, use will_paginate plugin or some other way to reduce data per page.

剧终人散尽 2024-07-22 18:42:12

我们的设置与您基本相同,在 EY 有 2 个 prod 切片和一个 staging 切片。 我们发现 ab 是一个很棒的负载测试工具 - 只需使用您希望命中的 url 编写一个 bash 脚本并将其指向您的切片即可。 观看 NewRelic 统计数据,它应该能让您了解您的应用程序可以处理的负载以及您可能需要优化的地方。

我们还发现 query_reviewer 也非常有用。 它非常适合查找那些未索引的表和 n+1 查询。

We've got basically the same setup as you, 2 prod slices and a staging slice at EY. We found ab to be a great load testing tool - just write a bash script with the urls that you expect to get hit and point it at your slice. Watch NewRelic stats and it should give you some idea of the load your app can handle and where you might need to optimise.

We also found query_reviewer to be very useful as well. It is great for finding those un-indexed tables and n+1 queries.

梦毁影碎の 2024-07-22 18:42:11

我曾开发过几个 Rails 应用程序,这些应用程序由于 Facebook 上的病毒式增长而经历了高负载。

你的杂种数量应该基于几个因素。 如果您的杂种进行 API 调用或发送电子邮件并且必须等待响应,那么您应该运行尽可能多的。 否则,尝试为每个 CPU 核心维护一个杂种,也许还剩下几个。

确保您的服务器使用公平代理平衡器(而不是循环)。 这是执行此操作的 nginx 模块: http://github.com/gnosek /nginx-upstream-fair/tree/master

以下是一些有关改进和基准测试应用程序性能以处理负载的其他技巧:

ActiveRecord

Rails 应用程序面临的最常见问题是使用率低ActiveRecord 对象。 当只需要一个查询时,进行数百个查询是很容易的。 确定这是否是您的应用程序的问题的最简单方法是设置 New Relic。 对站点上的每个主要页面发出请求后,请查看 newrelic SQL 概述。 如果您连续看到大量非常相似的查询(select * from posts where id = 1、select * from posts where id = 2、select * from posts...),这可能表明您需要使用:包含在您的 ActiveRecord 调用之一中。

其他一些基本的 ActiveRecord 技巧(这些只是我能立即想到的):

  1. 如果您还没有这样做,请确保在您的数据库表。

  2. 避免在视图中进行数据库调用,尤其是部分视图,很容易忘记在视图中进行数据库查询的次数。 将所有查询和计算推送到模型或控制器中。

  3. 避免在迭代器中进行查询。 通常这可以通过使用 :include 来完成。

  4. 尽可能避免让rails为大型数据集构建ActiveRecord对象。 当您进行像 Post.find(:all).size 这样的调用时,将为数据库中的每个 Post 实例化一个新类(它也可能是一个大型查询)。 在这种情况下,您需要使用 Post.count(:all),它将进行一次快速查询并返回一个整数,而无需实例化任何对象。

  5. User..has_many :objects 这样的关联会创建 user.objectsuser.object_ids 方法。 后者跳过 ActiveRecord 对象的实例化,并且速度要快得多。 特别是在处理大量对象时,这是加快速度的好方法。

  6. 尽可能学习和使用named_scope。 它将帮助您保持代码小巧,并更轻松地进行高效查询。

外部 API 和 ActionMailer

在处理请求时,请尽可能不要对外部服务进行 API 调用。 您的服务器将停止执行代码,直到收到响应。 这不仅会增加加载时间,而且你的杂种将无法处理新的请求。

如果您绝对必须在请求期间进行外部调用,则需要运行尽可能多的杂种,因为您可能会遇到其中许多杂种正在等待 API 响应而不执行任何其他操作的情况。 (这是构建 Facebook 应用程序时非常常见的问题)

在某些情况下发送电子邮件也是如此。 如果您预计许多用户会在短时间内注册,请务必对 ActionMailer 发送消息所需的时间进行基准测试。 如果它几乎不是即时的,那么您应该考虑将电子邮件存储在数据库中,并使用单独的脚本来发送它们。

BackgroundRB 这样的工具已经被创建来解决这个问题。

缓存

这里是关于 Rails 中不同缓存方法的很好的指南。

基准测试(定位性能问题)
如果您怀疑某个方法可能很慢,请尝试在控制台中对其进行基准测试。 下面是一个示例:

>> Benchmark.measure { User.find(4).pending_invitations }
=> #<Benchmark::Tms:0x77934b4 @cutime=0.0, @label="", @total=0.0, @stime=0.0, @real=0.00199985504150391, @utime=0.0, @cstime=0.0>

跟踪应用程序中速度缓慢的方法。 这些是您希望避免频繁执行的操作。 在某些情况下,只有第一次调用会很慢,因为 Rails 有查询缓存。 您还可以使用 自己缓存该方法记忆

NewRelic 还将很好地概述方法和 SQL 调用的执行时间。

祝你好运!

I have worked on several rails applications that experienced high load due to viral growth on Facebook.

Your mongrel count should be based on several factors. If your mongrels make API calls or deliver email and must wait for responses, then you should run as many as possible. Otherwise, try to maintain one mongrel per CPU core, with maybe a couple extra left over.

Make sure your server is using a Fair Proxy Balancer (not round robin). Here is the nginx module that does this: http://github.com/gnosek/nginx-upstream-fair/tree/master

And here are some other tips on improving and benchmarking your application performance to handle the load:

ActiveRecord

The most common problem Rails applications face is poor usage of ActiveRecord objects. It can be quite easy to make 100's of queries when only one is necessary. The easiest way to determine if this could be a problem with your application is to set up New Relic. After making a request to each major page on your site, take a look at the newrelic SQL overview. If you see a large number of very similar queries sequentially (select * from posts where id = 1, select * from posts where id = 2, select * from posts...) this may be a sign that you need to use a :include in one of your ActiveRecord calls.

Some other basic ActiveRecord tips (These are just the ones I can think of off the top of my head):

  1. If you're not doing it already, make sure to correctly use indexes on your database tables.

  2. Avoid making database calls in views, especially partials, it can be very easy to lose track of how much you are making database queries in views. Push all queries and calculations into your models or controllers.

  3. Avoid making queries in iterators. Usually this can be done by using an :include.

  4. Avoid having rails build ActiveRecord objects for large datasets as much as possible. When you make a call like Post.find(:all).size, a new class is instantiated for every Post in your database (and it could be a large query too). In this case you would want to use Post.count(:all), which will make a single fast query and return an integer without instantiating any objects.

  5. Associations like User..has_many :objects create both a user.objects and user.object_ids method. The latter skips instantiation of ActiveRecord objects and can be much faster. Especially when dealing with large numbers of objects this is a good way to speed things up.

  6. Learn and use named_scope whenever possible. It will help you keep your code tiny and makes it much easier to have efficient queries.

External APIs & ActionMailer

As much as you can, do not make API calls to external services while handling a request. Your server will stop executing code until a response is received. Not only will this add to load times, but your mongrel will not be able to handle new requests.

If you absolutely must make external calls during a request, you will need to run as many mongrels as possible since you may run into a situation where many of them are waiting for an API response and not doing anything else. (This is a very common problem when building Facebook applications)

The same applies to sending emails in some cases. If you expect many users to sign up in a short period of time, be sure to benchmark the time it takes for ActionMailer to deliver a message. If it's not almost instantaneous then you should consider storing emails in your database an using a separate script to deliver them.

Tools like BackgroundRB have been created to solve this problem.

Caching

Here's a good guide on the different methods of caching in rails.

Benchmarking (Locating performance problems)
If you suspect a method may be slow, try benchmarking it in console. Here's an example:

>> Benchmark.measure { User.find(4).pending_invitations }
=> #<Benchmark::Tms:0x77934b4 @cutime=0.0, @label="", @total=0.0, @stime=0.0, @real=0.00199985504150391, @utime=0.0, @cstime=0.0>

Keep track of methods that are slow in your application. Those are the ones you want to avoid executing frequently. In some cases only the first call will be slow since Rails has a query cache. You can also cache the method yourself using Memoization.

NewRelic will also provide a nice overview of how long methods and SQL calls take to execute.

Good luck!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文