쿼리가 400% CPU 부하를 유발합니다

최근 CPU 과부하가 발생하고 있습니다.
수 시간 동안 동시에 계속 실행되는 특정 쿼리(아래 참조)로 원인을 파악했습니다.
실행 중인 작업은 postmaster이며, 모든 프로세스를 종료하면 5분마다 재빌드될 때까지 CPU 사용량이 감소합니다.

SELECT “users”.“id”, ARRAY_AGG(ARRAY [uccm.id, c_msg.id]) AS memberships_with_unread_messages
FROM “users”
         INNER JOIN “user_options” ON “user_options”.“user_id” = “users”.“id”
         INNER JOIN user_chat_channel_memberships uccm ON uccm.user_id = users.id
         INNER JOIN chat_channels cc ON cc.id = uccm.chat_channel_id
         INNER JOIN chat_messages c_msg ON c_msg.chat_channel_id = uccm.chat_channel_id
         LEFT OUTER JOIN chat_mentions c_mentions ON c_mentions.chat_message_id = c_msg.id
WHERE “user_options”.“chat_enabled” = TRUE
  AND “user_options”.“chat_email_frequency” = 1
  AND (users.last_seen_at < ‘2023 - 11 - 15 09:54:26.931723’)
  AND (c_msg.deleted_at IS NULL AND c_msg.user_id <> users.id)
  AND (c_msg.created_at > ‘2023 - 11 - 08 10:09:26.931848’)
  AND ((uccm.last_read_message_id IS NULL OR c_msg.id > uccm.last_read_message_id) AND
       (uccm.last_unread_mention_when_emailed_id IS NULL OR c_msg.id > uccm.last_unread_mention_when_emailed_id) AND
       (uccm.user_id = c_mentions.user_id AND uccm.following IS true AND
        cc.chatable_type = ‘Category’

도움을 주실 분이나 해결책을 제안해 주실 분이 계신가요?

추가 정보:

  • 3.2.0.beta4-dev 버전을 사용 중이며, 이 문제는 최소 몇 달 동안 지속되고 있습니다.
  • 설치된 플러그인 목록은 다음과 같습니다:

감사합니다!

2개의 좋아요

@andrei 님이 최근에 채팅 쿼리 최적화 작업을 하셨습니다. 최신 버전으로 업데이트한 후에도 이 문제가 발생합니까?

4개의 좋아요

비슷한 쿼리를 하나 더 작업했는데, 그 수정은 해당 쿼리에 국한된 것이어서 여기에는 도움이 되지 않을 가능성이 높습니다. 그래도 최신 버전으로 업데이트하는 것이 좋습니다. 다른 최적화가 있을 수 있으니까요.

2개의 좋아요

우리는 최신 버전을 사용 중입니다.

쿼리에서 발생한 채팅 문제인 것 같습니다. 설정에서 수정할 수 있는 부분이 있을까요?

1개의 좋아요

한 고객이 채팅에서 @all 멘션을 활성화했는데, 16,000명 규모의 채널이 두 개나 있었습니다. 정말 흥미로운 상황이었습니다!
전체 멘션을 19번 사용한 후, 고객은 이를 빠르게 비활성화했습니다. 하지만 12시간이 지난 후에도 그들의 (성능이 좋은) 시스템은 여전히 높은 CPU 부하를 겪고 있었습니다.

이 문제는 mentions 테이블에서 문제의 320,000개 레코드를 삭제함으로써 해결되었습니다.

delete from chat_mentions 
where chat_message_id in (
  (select chat_message_id 
   from chat_mentions 
   group by chat_message_id having count(*) > 100)
);

하지만 이것이 왜 이렇게 많은 문제를 일으켰는지 여전히 궁금했습니다.
이 쿼리의 여러 인스턴스가 여전히 실행 중이었기 때문입니다.

해당 행들이 이미 삭제되었기 때문에 explain 명령으로는 좋은 결과를 얻을 수 없었지만, 상당한 처리 작업을 수행하고 있었던 것은 분명했습니다. 모든 인덱스는 정상적으로 설정되어 있었습니다.

1개의 좋아요

어제 누군가가 해당 쿼리가 CPU 부하가 크다고 언급한 것 같습니다:

2개의 좋아요

감사합니다 - 이 포럼을 더 효과적으로 검색하는 법을 배워야겠어요.

1개의 좋아요

이 방법은 우리에게 문제를 해결해 주지 못했습니다.

채팅 메시지가 몇 분 동안 사라졌다가 다시 나타나는 현상도 확인했습니다.

전반적으로 채팅 기능에는 개선할 부분이 많다고 생각하지만, 현재 나아가고 있는 방향 자체는 아주 좋습니다. 제 주요 우려는 채팅이 사실상 멈추지 않는 과부하를 유발할 수 있다는 점입니다. 멘션 기능을 꺼 보았지만, 이것도 효과가 없었습니다.

제가 언급한 쿼리가 다시 발생하지 않도록 막을 수 있는 방법이 있을까요? @andrei @JammyDodger

감사합니다.

안녕하세요 @sok777, 후속 조치에 감사드립니다. 몇몇 엔지니어가 이 문제를 조사 중이며, 업데이트가 준비되면 여기에서 다시 알려드리겠습니다. 그간 인내심을 가져주셔서 감사합니다!

2개의 좋아요

잘 작동하는 트릭 중 하나는 관리자 - 사용자 지정 - 감시 단어(Admin - Customize - Watched Words)로 이동하여 두 언급을 모두 “검열(Censor)” 목록에 추가하는 것입니다.

그렇다면 @ 접두사가 붙은 'all’과 'here’는 어떻게 되나요?

감사합니다!

1개의 좋아요

좋아요. 감사합니다!

1개의 좋아요

간단한 업데이트 @lindsey @RGJ

@all에게 보낸 메시지를 하나 삭제했습니다. 하지만 이로 인해 문제가 해결되지 않았습니다. 쿼리가 5분마다 계속 반복되고 있으며, 처리가 너무 오래 걸려 다른 많은 쿼리가 대기열에 쌓여 있습니다.
채팅을 비활성화하자 CPU 부하가 15%까지 떨어졌습니다. 정말 기가 막힙니다.

데이터베이스에 들어가서 언급(mention) 기록을 삭제해야 합니다

psql : delete from chat_mentions where chat_message_id = X
여기서 X는 삭제한 메시지의 ID입니다.

더 일반적인 쿼리는 여기의 제 메시지에 설명되어 있으며, 필요에 따라 숫자를 조정하십시오.

1개의 좋아요

네, 이미 이 방법을 시도해 보았습니다.

참고로 저희의 통계 정보는 다음과 같습니다:

users: 239251
chat_channels: 2864
chat_drafts: 205
chat_mentions: 155527 ->7500~
chat_messages: 390453
chat_threads: 25131
chat_message_reactions: 5993
user_chat_channel_memberships: 158480

1개의 좋아요

해당 쿼리가 오래 걸리는 유일한 이유는 chat_mentions 테이블에 많은 항목이 있기 때문입니다. 제가 게시한 일반 쿼리를 시도해 보셨나요? @all이 아니라 다른 대규모 그룹이 언급되었을 수도 있습니다.

문제가 되는 쿼리는 지난 7일 동안의 채팅에서 모든 언급을 검색합니다.

기존 쿼리 인스턴스도 모두 종료해야 합니다.

네, 그때 삭제했지만 계속 다시 나타납니다.
100개 이상의 모든 언급을 확인해 보았는데 하나도 없었습니다. 왜 그런지 다른 이유는 모르겠네요.
저한테는 쿼리에 근본적인 문제가 있는 것 같지만, 제 생각이 틀렸을 수도 있습니다.

1개의 좋아요

이 쿼리는 멘션 수가 적더라도 느릴 가능성이 높습니다. 수정 작업을 진행하겠습니다.

2개의 좋아요

좋습니다. 저희 사용 사례에 대해 계속해서 지원해 주셔서 감사합니다!

2개의 좋아요

@sok777 이 작업에 대해 조금 도움을 주실 수 있을까요? Postrges가 사용자의 사이트에서 사용하는 쿼리 플랜을 확인해 보고 싶습니다. 데이터베이스에서 아래 쿼리를 실행하여 결과를 공유해 주시겠어요?

EXPLAIN VERBOSE SELECT "users"."id", ARRAY_AGG(ARRAY [uccm.id, c_msg.id]) AS memberships_with_unread_messages
FROM "users"
         INNER JOIN "user_options" ON "user_options"."user_id" = "users"."id"
         INNER JOIN "group_users" ON "group_users"."user_id" = "users"."id"
         INNER JOIN "groups" ON "groups"."id" = "group_users"."group_id"
         INNER JOIN user_chat_channel_memberships uccm ON uccm.user_id = users.id
         INNER JOIN chat_channels cc ON cc.id = uccm.chat_channel_id
         INNER JOIN chat_messages c_msg ON c_msg.chat_channel_id = uccm.chat_channel_id
         LEFT OUTER JOIN chat_mentions c_mentions ON c_mentions.chat_message_id = c_msg.id
WHERE "user_options"."chat_enabled" = TRUE
  AND "user_options"."chat_email_frequency" = 1
  AND (users.last_seen_at < '2023-11-27 08:00:00.0000000')
  AND (c_msg.deleted_at IS NULL AND c_msg.user_id <> users.id)
  AND (c_msg.created_at > '2023-11-20 08:00:00.0000000')
  AND ((uccm.last_read_message_id IS NULL OR c_msg.id > uccm.last_read_message_id) AND
       (uccm.last_unread_mention_when_emailed_id IS NULL OR c_msg.id > uccm.last_unread_mention_when_emailed_id) AND
       (
               (uccm.user_id = c_mentions.user_id AND uccm.following IS true AND cc.chatable_type = 'Category') OR
               (cc.chatable_type = 'DirectMessage')
           )
    )
GROUP BY users.id, uccm.user_id
ORDER BY "users"."id" ASC
LIMIT 1000;
1개의 좋아요