【发布时间】: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 有问题的想法,将精力集中在调整您的应用程序上。哪些查询需要调整?可以清除旧数据吗?应用程序的哪些部分适合缓存?查看单个用户的会话,确定可以缓存哪些数据,然后查看可以缓存哪些数据并在多个用户之间共享。 (例如,应用程序的某些部分对每个人来说都是一样的,并且可以缓存)
标签: ruby-on-rails performance postgresql database-design heroku