需要 Heroku 数据库性能经验吗?
Posted
技术标签:
【中文标题】需要 Heroku 数据库性能经验吗?【英文标题】:Heroku database performance experience needed? 【发布时间】:2012-01-09 23:09:50 【问题描述】:我们的智能搜索引擎/聚合器正面临一些严重的扩展挑战。我们的数据库包含大约 200k 个对象。从 profiling 和 newrelic 看来,我们的大部分麻烦可能来自数据库。我们使用的是 Heroku 提供的最小的专用数据库(Ronin)。
我们一直在研究索引和缓存。到目前为止,我们设法通过减少数据库调用和智能缓存内容来解决我们的问题,但现在这似乎已经结束。我们不断地问自己,我们的代码/配置是否足够好,或者我们是否只是没有使用足够的“硬件”。
我们怀疑我们从 Heroku 购买的数据库解决方案可能性能不足。例如,仅对 200k 个项目进行简单计数(无连接,无任何操作)大约需要 250 毫秒。这似乎是一个很长的时间,尽管 postgres 以其在计数上的糟糕表现而闻名?
我们还开始使用基于纬度/经度的地理位置查找。两列都是索引浮点数。进行距离计算涉及相当复杂的数学运算,但我们使用的是非常推荐的 geocoder
gem,它被怀疑运行 非常 优化的查询。即使地理编码器仍然需要 4-10 秒来执行查找,例如 40.000 个对象,只返回第一个最近的 10 个限制。这听起来又像很长一段时间,我们所有有经验的人咨询说这听起来很奇怪,再次暗示数据库性能。
所以基本上我们想知道:我们可以从数据库中得到什么?会不会有问题?如果我们决定升级,我们可以期待什么?
我的另一个问题是:我读到here,我们可以通过将整个数据库加载到内存中来提高性能。我们应该自己配置吗?如果可以,如何配置?
关于最后一个问题的更新: 我从 Heroku 支持的乐于助人的人那里得到这个:
“这意味着有足够的内存(足够大的专用 数据库)将您的热数据集存储在内存中。这不是什么 您必须手动执行,Postgres 配置为自动使用所有 我们专用数据库上的可用内存。
我查看了您的数据库,看起来您目前正在 使用大约 1.25 GB 的 RAM,因此您还没有达到最大内存使用量 还没有。”
数字和数据更新
好的,现在我有时间研究数字和数字,我将尝试回答以下问题:
首先,数据库由大约 29 个具有很多关系的表组成。但实际上大多数查询都是在单个表上完成的(加入了一些额外的资源,以提供视图所需的所有信息)。 该表有 130 列。 目前它拥有大约 200k 条记录,但只有 70k 条处于活动状态 - 因此所有索引都作为此“状态”的部分索引。 我们搜索的所有列均已正确编入索引,并且没有一个属于文本类型,而且许多只是布尔值。问题解答:
-
嗯,基线性能很难说,我们有太多不同的选择。它所花费的时间通常从 90 毫秒到 250 毫秒不等,选择 20 行的限制。我们在同一张桌子上有很多计数,从 250 毫秒到 800 毫秒不等。
嗯嗯,这很难说,因为他们不会试一试。
我们有大约 8-10 个用户/客户端同时运行请求。
我们的查询负载:在 new relic 的数据库报告中,它说明了过去 24 小时:
throughput: 9.0 cpm, total time: 0.234 s, avg time: 25.9 ms
是的,我们已经检查了长期运行查询的查询计划。计数查询特别慢,通常超过 500 毫秒,对于在索引列上完成的 70k 记录进行非常简单的计数,结果约为 300
【问题讨论】:
我在 Heroku 上创建了几个应用程序,使用与我的生产应用程序完全相同的配置和代码,最终无缘无故地慢得要命。我会从简单开始,并认为它可能只是在一台坏机器上。 那么您使用的是什么主机呢?你有没有直接在 postgres db 性能上的 cmets? 您是否也在临时环境中运行系统?如果是这样,它是否以同样的慢速运行?比较彼此相同的暂存环境和生产环境可能是值得的,以便检查一下问题是代码还是主机。 是的,你是对的 - 我也在本地 macbook pro(最新型号)开发人员机器上运行它,而且速度几乎相同 - 我希望我在主机上的生产设置能够更快 - 对吧? 这是一条关键信息:当您在另一个环境中运行应用程序时,您会获得类似的性能。这是个好消息!您可能可以抛开 Heroku 有问题的想法,将精力集中在调整您的应用程序上。哪些查询需要调整?可以清除旧数据吗?应用程序的哪些部分适合缓存?查看单个用户的会话,确定可以缓存哪些数据,然后查看可以缓存哪些数据并在多个用户之间共享。 (例如,应用程序的某些部分对每个人来说都是一样的,并且可以缓存) 【参考方案1】:我已经调整了一些托管在 Heroku 上的 Rails 应用程序,也托管在其他平台上,通常问题分为几个基本类别:
-
在 ruby 中做的太多,可以在 db 级别完成(排序、过滤、连接数据等)
查询缓慢
索引使用效率低(不足或过多)
试图在 db 中完成所有操作(这在 Rails 中并不常见,但确实会发生)
未优化可缓存数据
没有有效地使用后台处理
现在很难为您提供帮助,因为您的问题不包含任何细节。我认为,如果您指出您需要帮助的最大问题然后提出来,您会得到更好的答复。
一些有助于我们帮助您的信息:
-
您的操作的平均响应时间是多少? (来自 new relic、request-log-analyzer、logs)
您需要帮助的最慢请求是什么?
该请求中的查询和代码是什么?
在本地与 heroku 相比,站点的性能是否有所不同?
最后,我认为您会发现这不是 Heroku 特有的问题,如果您将应用程序部署在 amazon、engineyard 等上,您将获得相同的性能。好消息是,我认为您的问题很常见,一旦您进行了一些基准测试和分析,应该不会很难解决。
-约翰·麦卡弗里
【讨论】:
过去几个月我在这个话题上学到了很多,你的回答是最有建设性的,最接近我所做的和对我有用的。谢谢大佬,希望对其他人有所帮助。 @J_McCaffrey 这是对人们应该研究的事情的精彩概述,以便对他们的程序行为有一个基本的了解。很好的答案! :)【参考方案2】:我们一直在问...
...这似乎很多...
...这是怀疑...
...我们可以期待什么...
好消息!您可以通过测量的魔力来结束看起来、怀疑和期待!!!
说真的,您没有提到任何获得有用答案所需的基本要点:
-
运行顺序扫描和单行索引提取的数据库的基准性能是多少?你说 Heroku 说你的数据库适合 RAM,所以你在测量时不应该看到磁盘 I/O 问题。
这种性能是否符合 Heroku 所说的性能?
有多少并发客户端?
您的查询负载是多少 - 什么查询以及多久一次?
您是否针对任何可疑的长时间运行的查询检查了查询计划?
一旦你得到了这类信息,也许有人可以说些有用的话。就目前而言,您在此处阅读的任何内容都只是猜测。
【讨论】:
嗯 - 确实如此 - 我想我可以回答你几乎所有的问题,因为我一直在研究其中的大部分 - 只需要一点时间来挖掘所有的数字 - 是对的返回 :-)【参考方案3】:首先:您应该检查您的 postgres 配置。 (从 psql 或其他客户端显示全部,或者只查看数据目录中的 postgres.conf)对性能影响最大的参数是 effective_cache_size
,应设置为 about (total_physical_ram - memory_in_use_by_kernel_and_all_processes)。对于 4GB 的机器,这通常是 3GB (4-1) 左右。 (这是非常自然的调整,但会在第一步得到最好的结果)
第二:为什么你想要所有的计数?更好地使用典型查询:只询问需要什么,而不是可用什么。 (原因:对于 COUNT(*) 没有可能的优化:要么需要扫描整个表,要么需要扫描整个索引)
第三:开始收集和分析一些查询计划(针对表现不佳的典型查询)。您可以通过将EXPLAIN ANALYZE
放在实际查询之前来获得查询计划。 (另一种方法是提高日志记录级别,并从日志文件中获取它们)错误的查询计划可能会导致您缺少统计信息或索引,甚至是错误的数据建模。
【讨论】:
【参考方案4】:Newrelic 监控可以作为 Heroku (http://devcenter.heroku.com/articles/newrelic) 的附加组件包含在内。至少,这应该能让您深入了解幕后发生的事情,并可能帮助您查明一些问题。
【讨论】:
是的,正如我所写,我已经集成了它,它也告诉我我的应用程序不够快 - 但另一方面,我不知道会发生什么,所以我对这些数字感到非常困惑 - 我只是应该增加(非常)昂贵的卷(读取数据库产品),还是我要在我的代码中做更多的调试/优化(很难看到我仍然在哪里可以),还是我只是坚持使用性能缓慢的托管设施? 啊,错过了。你说得对,表演令人怀疑。您可以联系 heroku 支持并要求他们为您调查此问题。您可以通过heroku pg:info
来查看您的数据库有多大,可能接近限制(基本数据库为 5GB),这可能会导致一些问题。以上是关于需要 Heroku 数据库性能经验吗?的主要内容,如果未能解决你的问题,请参考以下文章