用户摘要页面加载时间长,数据库缓慢

您好,

我们在访问用户摘要页面时遇到了严重的加载延迟问题。似乎用户在我们网站上的活动越频繁,加载摘要所需的时间就越长。这听起来似乎显而易见,但我们网站上的加载时间差异巨大。

例如,加载一个“新”用户(仅几周活动记录)的摘要页面大约需要 1 秒,而加载一个多年每日活跃用户的页面则可能需要 30 到 40 秒。

我们检查了数据库,对 topic_views 表的规模(包括索引)感到震惊,其大小达到了 62 GB。

以下是我们最大的 7 个表:

relation total_size table_size index_size reltuples
topic_views 62 GB 17 GB 45 GB 399215000
posts 27 GB 22 GB 5022 MB 9123860
top_topics 15 GB 708 MB 15 GB 1602180
post_search_data 15 GB 12 GB 2849 MB 8181010
incoming_links 12 GB 5330 MB 6647 MB 90008900
user_actions 3184 MB 877 MB 2307 MB 11872800
topics 2117 MB 1035 MB 1082 MB 1613070

为了测试这一点,我们选取了一个已知摘要加载时间极长的用户 ID,并在 topic_views 表上针对该 ID 执行了计数查询。该查询耗时几乎与加载该用户摘要的耗时相同。因此,“查看过的主题”部分是导致延迟的原因。

正如在 早期主题 中所述,我们将一个旧版本(v1.2.4 + 修改)的基于 Discourse 的网站升级到了 v2.4.0-beta.2,目前运行的是 Discourse v2.4.0-beta6。因此,可能存在一些遗留数据。但我们不知道可以删除哪些数据。

目前我们非常不确定下一步该做什么或进行哪些调整。我们的安装完全运行在 Azure 上,使用外部的 Azure PostgreSQL 数据库实例,并且已应用了您 postgres.10.template.yml 中描述的配置。我们甚至不确定 topic_views 表的大小(尤其是索引)相对于其他表是否“过大”,或者这是否属于正常范围。

任何提示、想法或建议都将不胜感激。

此致
Sascha Hofmann

附注:
我忘了提到,因此我们在加载 /u/<username>/summary.json 时出现了多个 502 错误(这些错误直接显示在网站上,并非来自 nginx 错误页面或应用网关)。

您是作为管理员/员工还是匿名用户查看?员工视图的费用要高得多。

无论我以管理员/员工身份还是普通用户身份访问 /u/<username>/summary,结果都没有区别。我们还启用了“隐藏用户资料对公众可见”选项,因此匿名用户无法查看用户资料(为测试已禁用该选项,但无影响,因为“查看的主题”同样出现在摘要中)。

你是否反复迁移、修改或重建过同一个数据库?也许你的数据库需要进行 VACUUM 操作以更新统计信息。30 秒的查询时间远远超出了我们在 Discourse 安装中看到的正常范围(尽管不得不承认你的数据库规模较大。)

如果你能接受一些停机时间,可以尝试执行 VACUUM FULL

另外,您的数据库是否部署在高速 SSD 存储上并配备大量内存?这一点至关重要。

为了准确了解问题所在:

  1. 编辑 app.yml 文件,将您的管理员用户邮箱添加到 DISCOURSE_DEVELOPER_EMAILS

  2. 重新构建

  3. 使用步骤 1 中设置的用户登录,并加载缓慢的页面。

  4. 分享 mini-profiler 的结果

请分享此内容以及展开窗口的内容:

我们已经测试了几次,但每次都使用旧数据集的全新副本。几周后,一旦我们确认成功回滚了前所有者的更改,我们就执行了一次升级和迁移。

这确实值得一试,但我不太确定这需要多长时间。不过,是的,我们应该考虑执行完整的 VACUUM。特别是我们之前在那台旧数据库上已经遇到过一些问题 参见

是的。所有数据都存储在服务器的 SSD 上,并配有 40GB 内存(其中约 60% 被占用,即使在更高负载下也没有达到 100% 的峰值)。

感谢这条建议,我会尝试一下。
由于我们使用的是自己的 Docker 镜像,其中缺少 app.yml,我们应该通过在 discourse.conf 中将邮箱地址添加到 developer_emails 来实现相同的行为。

您可以进入 Rails 控制台,并使用 Developers.create!(user_id: 123),其中 123 是您的用户 ID。

不幸的是,它不起作用(是的,我之前已经替换了 123::slight_smile:):

discourse@2d5c3bf04550:~$ rails console --environment=production
正在加载生产环境 (Rails 6.0.0)
irb(main):001:0> Developers.create!(user_id: 123)
回溯 (最近一次调用最后):
        1: from (irb):1
NameError (未初始化的常量 Developers)

另一种方法:

discourse@2d5c3bf04550:~$ rails runner --environment=production make_me_dev.rb
回溯 (最近一次调用最后):
/var/www/discourse/bin/rails: Bootsnap::LoadPathCache::FallbackScan
	19: from /var/www/discourse/bin/rails:17:in `<main>'
	18: from /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/dependencies.rb:325:in `require'
	17: from /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/dependencies.rb:291:in `load_dependency'
	16: from /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/dependencies.rb:325:in `block in require'
	15: from /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
	14: from /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:21:in `require_with_bootsnap_lfi'
	13: from /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.4/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
	12: from /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `block in require_with_bootsnap_lfi'
	11: from /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require'
	10: from /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.0/lib/rails/commands.rb:18:in `<main>'
	 9: from /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.0/lib/rails/command.rb:46:in `invoke'
	 8: from /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.0/lib/rails/command/base.rb:65:in `perform'
	 7: from /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/thor-0.20.3/lib/thor.rb:387:in `dispatch'
	 6: from /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/thor-0.20.3/lib/thor/invocation.rb:126:in `invoke_command'
	 5: from /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/thor-0.20.3/lib/thor/command.rb:27:in `run'
	 4: from /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.0/lib/rails/commands/runner/runner_command.rb:42:in `perform'
	 3: from /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:52:in `load'
	 2: from /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:69:in `rescue in load'
	 1: from /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:69:in `load'
make_me_dev.rb:1:in `<main>': uninitialized constant Developers (NameError)
discourse@2d5c3bf04550:~$ cat make_me_dev.rb
Developers.create!(user_id: 123)

我将尝试 discourse.conf 方法,并尽快提供所需数据。

感谢您到目前为止的建议!

这就是为什么我们总是建议人们使用官方支持的方法来安装 Discourse,这样在需要帮助时,我们可以使用标准工具提供帮助。

是的,可能是因为我们使用 supervisord 来启动所有进程。

无论如何,这是您请求的输出(压缩的 HTML 内容):
_u_x_strom_summary.json-13498.2ms-ProfilingResults.zip|附件 (94.5 KB)

此请求耗时 13 秒,但我不得不加载该站点两次。第一次尝试耗时过长,导致出现 502 错误。因此,可能某些内容已经被缓存了。

It took more than 13 seconds to run 51 SQL queries. Your database is seriously either misconfigured or underpowered.

Big offenders
SELECT "posts"."id" AS t0_r0, "posts"."user_id" AS t0_r1, "posts"."topic_id" AS t0_r2, "posts"."post_number" AS t0_r3, "posts"."raw" AS t0_r4, "posts"."cooked" AS t0_r5, "posts"."created_at" AS t0_r6, "posts"."updated_at" AS t0_r7, "posts"."reply_to_post_number" AS t0_r8, "posts"."reply_count" AS t0_r9, "posts"."quote_count" AS t0_r10, "posts"."deleted_at" AS t0_r11, "posts"."off_topic_count" AS t0_r12, "posts"."like_count" AS t0_r13, "posts"."incoming_link_count" AS t0_r14, "posts"."bookmark_count" AS t0_r15, "posts"."avg_time" AS t0_r16, "posts"."score" AS t0_r17, "posts"."reads" AS t0_r18, "posts"."post_type" AS t0_r19, "posts"."sort_order" AS t0_r20, "posts"."last_editor_id" AS t0_r21, "posts"."hidden" AS t0_r22, "posts"."hidden_reason_id" AS t0_r23, "posts"."notify_moderators_count" AS t0_r24, "posts"."spam_count" AS t0_r25, "posts"."illegal_count" AS t0_r26, "posts"."inappropriate_count" AS t0_r27, "posts"."last_version_at" AS t0_r28, "posts"."user_deleted" AS t0_r29, "posts"."reply_to_user_id" AS t0_r30, "posts"."percent_rank" AS t0_r31, "posts"."notify_user_count" AS t0_r32, "posts"."like_score" AS t0_r33, "posts"."deleted_by_id" AS t0_r34, "posts"."edit_reason" AS t0_r35, "posts"."word_count" AS t0_r36, "posts"."version" AS t0_r37, "posts"."cook_method" AS t0_r38, "posts"."wiki" AS t0_r39, "posts"."baked_at" AS t0_r40, "posts"."baked_version" AS t0_r41, "posts"."hidden_at" AS t0_r42, "posts"."self_edits" AS t0_r43, "posts"."reply_quoted" AS t0_r44, "posts"."via_email" AS t0_r45, "posts"."raw_email" AS t0_r46, "posts"."public_version" AS t0_r47, "posts"."action_code" AS t0_r48, "posts"."image_url" AS t0_r49, "posts"."locked_by_id" AS t0_r50, "topics"."id" AS t1_r0, "topics"."title" AS t1_r1, "topics"."last_posted_at" AS t1_r2, "topics"."created_at" AS t1_r3, "topics"."updated_at" AS t1_r4, "topics"."views" AS t1_r5, "topics"."posts_count" AS t1_r6, "topics"."user_id" AS t1_r7, "topics"."last_post_user_id" AS t1_r8, "topics"."reply_count" AS t1_r9, "topics"."featured_user1_id" AS t1_r10, "topics"."featured_user2_id" AS t1_r11, "topics"."featured_user3_id" AS t1_r12, "topics"."avg_time" AS t1_r13, "topics"."deleted_at" AS t1_r14, "topics"."highest_post_number" AS t1_r15, "topics"."image_url" AS t1_r16, "topics"."like_count" AS t1_r17, "topics"."incoming_link_count" AS t1_r18, "topics"."category_id" AS t1_r19, "topics"."visible" AS t1_r20, "topics"."moderator_posts_count" AS t1_r21, "topics"."closed" AS t1_r22, "topics"."archived" AS t1_r23, "topics"."bumped_at" AS t1_r24, "topics"."has_summary" AS t1_r25, "topics"."archetype" AS t1_r26, "topics"."featured_user4_id" AS t1_r27, "topics"."notify_moderators_count" AS t1_r28, "topics"."spam_count" AS t1_r29, "topics"."pinned_at" AS t1_r30, "topics"."score" AS t1_r31, "topics"."percent_rank" AS t1_r32, "topics"."subtype" AS t1_r33, "topics"."slug" AS t1_r34, "topics"."deleted_by_id" AS t1_r35, "topics"."participant_count" AS t1_r36, "topics"."word_count" AS t1_r37, "topics"."excerpt" AS t1_r38, "topics"."pinned_globally" AS t1_r39, "topics"."pinned_until" AS t1_r40, "topics"."fancy_title" AS t1_r41, "topics"."highest_staff_post_number" AS t1_r42, "topics"."featured_link" AS t1_r43, "topics"."reviewable_score" AS t1_r44 FROM "posts" INNER JOIN "topics" ON ("topics"."deleted_at" IS NULL) AND "topics"."id" = "posts"."topic_id" WHERE ("posts"."deleted_at" IS NULL) AND (posts.post_type IN (1,2,3,4)) AND ("topics"."deleted_at" IS NULL) AND (topics.archetype <> 'private_message') AND "topics"."visible" = TRUE AND (topics.category_id IS NULL OR topics.category_id IN (SELECT id FROM categories WHERE NOT read_restricted OR id IN (1,3,6,100,141,202,229,233,235,248,262,594,595,609))) AND "posts"."user_id" = 643476 AND (post_number > 1) ORDER BY posts.like_count DESC, posts.created_at DESC LIMIT 6; 

Took 6248.3 ms

SELECT "topic_links"."id" AS t0_r0, "topic_links"."topic_id" AS t0_r1, "topic_links"."post_id" AS t0_r2, "topic_links"."user_id" AS t0_r3, "topic_links"."url" AS t0_r4, "topic_links"."domain" AS t0_r5, "topic_links"."internal" AS t0_r6, "topic_links"."link_topic_id" AS t0_r7, "topic_links"."created_at" AS t0_r8, "topic_links"."updated_at" AS t0_r9, "topic_links"."reflection" AS t0_r10, "topic_links"."clicks" AS t0_r11, "topic_links"."link_post_id" AS t0_r12, "topic_links"."title" AS t0_r13, "topic_links"."crawled_at" AS t0_r14, "topic_links"."quote" AS t0_r15, "topic_links"."extension" AS t0_r16, "topics"."id" AS t1_r0, "topics"."title" AS t1_r1, "topics"."last_posted_at" AS t1_r2, "topics"."created_at" AS t1_r3, "topics"."updated_at" AS t1_r4, "topics"."views" AS t1_r5, "topics"."posts_count" AS t1_r6, "topics"."user_id" AS t1_r7, "topics"."last_post_user_id" AS t1_r8, "topics"."reply_count" AS t1_r9, "topics"."featured_user1_id" AS t1_r10, "topics"."featured_user2_id" AS t1_r11, "topics"."featured_user3_id" AS t1_r12, "topics"."avg_time" AS t1_r13, "topics"."deleted_at" AS t1_r14, "topics"."highest_post_number" AS t1_r15, "topics"."image_url" AS t1_r16, "topics"."like_count" AS t1_r17, "topics"."incoming_link_count" AS t1_r18, "topics"."category_id" AS t1_r19, "topics"."visible" AS t1_r20, "topics"."moderator_posts_count" AS t1_r21, "topics"."closed" AS t1_r22, "topics"."archived" AS t1_r23, "topics"."bumped_at" AS t1_r24, "topics"."has_summary" AS t1_r25, "topics"."archetype" AS t1_r26, "topics"."featured_user4_id" AS t1_r27, "topics"."notify_moderators_count" AS t1_r28, "topics"."spam_count" AS t1_r29, "topics"."pinned_at" AS t1_r30, "topics"."score" AS t1_r31, "topics"."percent_rank" AS t1_r32, "topics"."subtype" AS t1_r33, "topics"."slug" AS t1_r34, "topics"."deleted_by_id" AS t1_r35, "topics"."participant_count" AS t1_r36, "topics"."word_count" AS t1_r37, "topics"."excerpt" AS t1_r38, "topics"."pinned_globally" AS t1_r39, "topics"."pinned_until" AS t1_r40, "topics"."fancy_title" AS t1_r41, "topics"."highest_staff_post_number" AS t1_r42, "topics"."featured_link" AS t1_r43, "topics"."reviewable_score" AS t1_r44, "posts"."id" AS t2_r0, "posts"."user_id" AS t2_r1, "posts"."topic_id" AS t2_r2, "posts"."post_number" AS t2_r3, "posts"."raw" AS t2_r4, "posts"."cooked" AS t2_r5, "posts"."created_at" AS t2_r6, "posts"."updated_at" AS t2_r7, "posts"."reply_to_post_number" AS t2_r8, "posts"."reply_count" AS t2_r9, "posts"."quote_count" AS t2_r10, "posts"."deleted_at" AS t2_r11, "posts"."off_topic_count" AS t2_r12, "posts"."like_count" AS t2_r13, "posts"."incoming_link_count" AS t2_r14, "posts"."bookmark_count" AS t2_r15, "posts"."avg_time" AS t2_r16, "posts"."score" AS t2_r17, "posts"."reads" AS t2_r18, "posts"."post_type" AS t2_r19, "posts"."sort_order" AS t2_r20, "posts"."last_editor_id" AS t2_r21, "posts"."hidden" AS t2_r22, "posts"."hidden_reason_id" AS t2_r23, "posts"."notify_moderators_count" AS t2_r24, "posts"."spam_count" AS t2_r25, "posts"."illegal_count" AS t2_r26, "posts"."inappropriate_count" AS t2_r27, "posts"."last_version_at" AS t2_r28, "posts"."user_deleted" AS t2_r29, "posts"."reply_to_user_id" AS t2_r30, "posts"."percent_rank" AS t2_r31, "posts"."notify_user_count" AS t2_r32, "posts"."like_score" AS t2_r33, "posts"."deleted_by_id" AS t2_r34, "posts"."edit_reason" AS t2_r35, "posts"."word_count" AS t2_r36, "posts"."version" AS t2_r37, "posts"."cook_method" AS t2_r38, "posts"."wiki" AS t2_r39, "posts"."baked_at" AS t2_r40, "posts"."baked_version" AS t2_r41, "posts"."hidden_at" AS t2_r42, "posts"."self_edits" AS t2_r43, "posts"."reply_quoted" AS t2_r44, "posts"."via_email" AS t2_r45, "posts"."raw_email" AS t2_r46, "posts"."public_version" AS t2_r47, "posts"."action_code" AS t2_r48, "posts"."image_url" AS t2_r49, "posts"."locked_by_id" AS t2_r50 FROM "topic_links" INNER JOIN "topics" ON ("topics"."deleted_at" IS NULL) AND "topics"."id" = "topic_links"."topic_id" INNER JOIN "posts" ON ("posts"."deleted_at" IS NULL) AND "posts"."id" = "topic_links"."post_id" WHERE (posts.post_type IN (1,2,3,4)) AND ("topics"."deleted_at" IS NULL) AND (topics.archetype <> 'private_message') AND "topics"."visible" = TRUE AND (topics.category_id IS NULL OR topics.category_id IN (SELECT id FROM categories WHERE NOT read_restricted OR id IN (1,3,6,100,141,202,229,233,235,248,262,594,595,609))) AND "topic_links"."user_id" = 643476 AND "topic_links"."internal" = FALSE AND "topic_links"."reflection" = FALSE AND "topic_links"."quote" = FALSE ORDER BY clicks DESC, topic_links.created_at DESC LIMIT 6; 

Took 258.3 ms

SELECT acting_user_id, COUNT(*) FROM "user_actions" INNER JOIN "topics" ON ("topics"."deleted_at" IS NULL) AND "topics"."id" = "user_actions"."target_topic_id" INNER JOIN "posts" ON ("posts"."deleted_at" IS NULL) AND "posts"."id" = "user_actions"."target_post_id" WHERE ("topics"."deleted_at" IS NULL) AND (topics.archetype <> 'private_message') AND "topics"."visible" = TRUE AND (topics.category_id IS NULL OR topics.category_id IN (SELECT id FROM categories WHERE NOT read_restricted OR id IN (1,3,6,100,141,202,229,233,235,248,262,594,595,609))) AND "user_actions"."user_id" = 643476 AND "user_actions"."action_type" = 2 GROUP BY "user_actions"."acting_user_id" ORDER BY COUNT(*) DESC LIMIT 6; 

Took 245.5 ms

SELECT user_actions.user_id, COUNT(*) FROM "user_actions" INNER JOIN "topics" ON ("topics"."deleted_at" IS NULL) AND "topics"."id" = "user_actions"."target_topic_id" INNER JOIN "posts" ON ("posts"."deleted_at" IS NULL) AND "posts"."id" = "user_actions"."target_post_id" WHERE ("topics"."deleted_at" IS NULL) AND (topics.archetype <> 'private_message') AND "topics"."visible" = TRUE AND (topics.category_id IS NULL OR topics.category_id IN (SELECT id FROM categories WHERE NOT read_restricted OR id IN (1,3,6,100,141,202,229,233,235,248,262,594,595,609))) AND "user_actions"."action_type" = 2 AND "user_actions"."acting_user_id" = 643476 GROUP BY "user_actions"."user_id" ORDER BY COUNT(*) DESC LIMIT 6; 

Took 277.2 ms

SELECT replies.user_id, COUNT(*) FROM "posts" INNER JOIN "topics" ON ("topics"."deleted_at" IS NULL) AND "topics"."id" = "posts"."topic_id" JOIN posts replies ON posts.topic_id = replies.topic_id AND posts.reply_to_post_number = replies.post_number WHERE ("posts"."deleted_at" IS NULL) AND (posts.post_type IN (1,2,3,4)) AND ("topics"."deleted_at" IS NULL) AND (topics.archetype <> 'private_message') AND "topics"."visible" = TRUE AND (topics.category_id IS NULL OR topics.category_id IN (SELECT id FROM categories WHERE NOT read_restricted OR id IN (1,3,6,100,141,202,229,233,235,248,262,594,595,609))) AND "posts"."user_id" = 643476 AND (replies.user_id <> 643476) GROUP BY replies.user_id ORDER BY COUNT(*) DESC LIMIT 6; 

Took 3064.6 ms

SELECT category_id FROM "posts" INNER JOIN "topics" ON ("topics"."deleted_at" IS NULL) AND "topics"."id" = "posts"."topic_id" WHERE ("posts"."deleted_at" IS NULL) AND (posts.post_type IN (1,2,3,4)) AND ("topics"."deleted_at" IS NULL) AND (topics.archetype <> 'private_message') AND "topics"."visible" = TRUE AND (topics.category_id IS NULL OR topics.category_id IN (SELECT id FROM categories WHERE NOT read_restricted OR id IN (1,3,6,100,141,202,229,233,235,248,262,594,595,609))) AND "posts"."user_id" = 643476 GROUP BY topics.category_id ORDER BY COUNT(*) DESC LIMIT 6; 

Took 2283.3 ms

SELECT category_id, COUNT(*) FROM "posts" INNER JOIN "topics" ON ("topics"."deleted_at" IS NULL) AND "topics"."id" = "posts"."topic_id" WHERE ("posts"."deleted_at" IS NULL) AND (posts.post_type IN (1,2,3,4)) AND ("topics"."deleted_at" IS NULL) AND (topics.archetype <> 'private_message') AND "topics"."visible" = TRUE AND (topics.category_id IS NULL OR topics.category_id IN (SELECT id FROM categories WHERE NOT read_restricted OR id IN (1,3,6,100,141,202,229,233,235,248,262,594,595,609))) AND "posts"."user_id" = 643476 AND (post_number > 1) AND (topics.category_id in (64,13,59,124,327,122)) GROUP BY topics.category_id ORDER BY COUNT(*) DESC; 

Took 811.5 ms

I assume Azure has some sort of database statistics for the hosted service, you gotta check those and evaluate what need to change.

Also check the /sidekiq URL on your install to see if there is no queue contention keeping the database busy.

这是我们首先检查的。我们的实例配置如下:

  • 8 核(利用率约 16.18%,峰值达 60%)
  • 40GB 内存(已用约 60%,无峰值波动)
  • 2244 可用 IOPS(利用率约 2.5%,峰值达 24%)

如前所述,我们使用了您在 postgres.10.template.yml 中描述的配置文件。其他设置均为默认值。看来我们需要再次仔细检查。

Sidekiq 目前状态良好。0 个繁忙任务,0 个排队任务,0 次重试,1 个已调度任务,0 个死亡任务。任务列表当前为空。

因此,我们得出初步结论。首先,我们将检查 PostgreSQL 配置,因为有一些优化措施可以应用。如果无效,我们应考虑升级 PostgreSQL 实例和/或执行完整的 VACUUM 操作。

感谢您到目前为止的宝贵时间,祝您周末愉快!
此致
Sascha

如果您的机器拥有 40GB 内存,postgres.10.template.yml 中的默认设置已不再适用,正如 samples/standalone.yml 所指出的:

您好,

感谢您的回复。在 Azure 上使用 PostgreSQL 实例存在一些限制。您无法设置某些参数,例如 effective_cache_sizemax_connectionsmaintenance_worker_memshared_buffers

在提交此支持请求时,我们使用的是“通用用途”(General Purpose)层级,该层级提供 40GB 内存,但仅分配了 1GB 的 shared_buffers 和 2.5GB 的 effective_cache_size

从昨天起,我们切换到了“内存优化”(Memory Optimized)层级,内存翻倍至 80GB,shared_buffers 增至 2GB,effective_cache_size 增至 5GB。

work_mem 是我们能够调整的参数,目前设置为 128MB,因为我们的日志中没有出现 temporary file 相关条目。

有趣的是,一旦我们切换层级,即使未增加 vCore 数量或存储空间,CPU 和 IOPS 的使用率也明显下降。这确实表明之前的问题是由缓存和缓冲区过小引起的。

目前,某些用户(尤其是员工用户或长期用户)的摘要页面以及 关于 页面的加载时间仍然较长,但相比之前已有显著改善(约为之前的 50%)。

此致

附注:
对于遇到类似问题且对 PostgreSQL 安装拥有更多控制权的用户,以下指南可能有所帮助:

很高兴听到这个消息。下一步是看看是否可以通过使用 4vCPU 内存优化型实例来优化成本,或者考虑自行部署运行。

哦,我们目前运行的是 8 vCore,对应 80GB 内存。shared_buffers 当前设置为 2GB,但针对该层级和 vCore 数量,应设置为 16GB。不过,我们已联系 Azure 支持团队以解决此问题。

附言:
我们实际上已经将 shared_buffers 设置为 16GB。我之前误解了 SELECT * FROM pg_settings WHERE name = 'shared_buffers'; 的输出结果。其单位是 8KB

因此,我认为这个话题可以关闭了。感谢大家付出的努力,希望接下来几天在 Azure 支持团队的协助下,我们能共同实现更好的性能。

再附言:
抱歉 @riking,我误会了您。我认为我们使用 8 vCore 是合适的,而不需要将其减少到 4。一旦我们达到了预期的性能目标,我们可以尝试一下。