我的数据库受cpu限制,我找不到问题的根本原因。我目前有两个应用程序服务器,每个服务器都有一个通过ruby-pg gem连接到PostgreSQL的Rails api。两个应用程序服务器都有sidekiq运行后台作业,我有一些支持服务器通过sidekiq处理来自国家feed的新帖子。如果我的内存耗尽,解决方案似乎很简单。为什么我受CPU约束的任何一般想法?
数据库规格:
可能出现的问题:
数据库有近10GB的索引。我要将我的数据库升级到PostgreSQL版本> = 9.2。在9.2版中,引入了仅索引扫描。
在postgresql.conf中,我将max connection设置为'500'。通常在一天中,只使用175个连接,但在高峰时段,sidekiq任务会将当前连接增加到350.建议使用8GB服务器实例连接多少个连接?
当我在psql控制台中查看pg_stat_activity时,我看到sidekiq留下了很多IDLE连接。这些连接会导致CPU通胀吗?该修复是否存在于api或sidekiq中?
也许没有错误。我可能只需要增加服务器实例。如果我受到记忆限制,这将更有意义。但是,app服务器和3个支持sidekiq服务器都是4gb性能层实例。实质上,与数据库交互的服务器组合了数据库资源的两倍以上。这甚至应该重要吗?
其他问题:
答案 0 :(得分:10)
您正在使用大量并发连接。 PostgreSQL将浪费大量时间用于管理和处理并发查询。所有并发工作都将争夺CPU和缓冲区空间,自旋锁存在很大的争用,而且它通常都是一团糟。
在8核计算机上,如果您主要受CPU限制,则可能不应该有超过20个正常工作的连接。如果你的I / O有限,你可以走得更高,但350就是荒谬的。
如果可能的话,将PgBouncer放在PostgreSQL实例前面的事务池模式中,这样查询就会排队并快速执行,而不是慢速并行执行。
请参阅number of database connections (Pg wiki)。
此外,PostGIS可能非常耗费CPU。它有时需要进行非常复杂的计算。我建议使用auto_explain
模块记录长时间运行的查询,并使用pg_stat_statements
/ pg_stat_plans
记录占用资源的内容。检查这些查询以确定它们是否需要改进。
您的idle in transaction
会话也必须处理。根据他们为什么闲置以及他们是否有交易ID,他们可能会导致严重的表格膨胀。他们还在PostgreSQL中创建了不必要的信令开销,因为它必须与积极做事的后端进行更多的协调。最后,自己开放交易的数量增加了一些内部管家操作的成本。
因此。如果减少连接数,将PgBouncer放在事务池模式中,并修复这些空闲连接,那么您的数据库可能会表现得更好。
答案 1 :(得分:2)
您很可能因为工作需要大量CPU而受CPU限制。 :)
9.1索引通常不是很糟糕。可能存在一些特定问题,因为所有版本可能正是这些问题,它们可能会在不同版本之间发生变化。
当您受IO限制时,仅索引扫描主要是一个好处。我不会抱太大希望这对你来说是一个神奇的子弹。
350个连接当然没有帮助,但可能也不是很有害。但是当它们有害时,它可能是彻头彻尾的灾难性的。正确的值更多地取决于核心数量,而不是RAM数量。如果很容易减少sidekiq连接,即使你无法证明它有帮助,也要这样做。
如果连接只是IDLE,而不是交易中的IDLE,那么它们可能不是很有害,但是在某些情况下它们可能也是如此。这与连接数几乎相同。
您在top
中显示的连接在事务中处于空闲状态。这种状态不应该占用太多CPU,因此这可能意味着它正在快速循环通过语句而top
恰好在它们之间捕获它。但你没有说top
中有多少相似的行,如果只是它表明你的代码没有同时运行,而且你的8个CPU中有7个被浪费了。
关于数据库服务器与其他服务器的关系,如果数据库基本上是限制,那么使用更大的锤子打它就不会有帮助。通常在计算完成的地方有一些灵活性。如果您可以让应用服务器进行更多当前在数据库上完成的计算并让数据库关注ACID问题,那就不错了。但是没有人,但你可以知道这是否可能。
我的第一站是使用pg_stat_statements来查看哪些SQL语句占用的时间最多。也许只是在最慢/最频繁的查询中添加索引会使问题神奇地消失。