Skip to content

피드 Profile 집계가 회원 기록 수에 정비례한다 — 명세된 Redis 캐시 미구현 #196

Description

@minyongP

급한 문제가 아닙니다. 지금 배포 데이터로는 실해가 없고(운영 record 162건), 기록이 많은
헤비 유저가 생겼을 때 드러나는 문제입니다. 명세된 캐시가 미구현이라는 사실과 실측 근거를
남겨 두는 것이 목적이고, 개선 여부와 시점은 AI 파트 판단에 맡깁니다.

무엇을 발견했나

FeedKeywordRepository.PROFILE_KEYWORDS_SQL(회원 관심 Keyword 집계)이 회원 본인의 기록 수에
정비례
하고, 피드 요청마다 실행됩니다.

천만 건 벤치 볼륨(S15P11A705-283, postgres 1Gi 한도)에서 회원 규모별 실측:

회원 record 수 Profile 쿼리
697건 5.8 ms
4,000건 14.5 ms
20,000건 216.4 ms

record 20,000건 회원의 피드 API가 197ms인데 그중 163ms가 이 쿼리입니다
(S15P11A705-303으로 최신 채널을 236ms → 2.3ms로 줄인 뒤 남은 몫).

FeedService.rank()가 커서 페이지마다 다시 도는 구조라(코드 주석에 명시됨) 스크롤할 때마다
반복
됩니다.

계획·인덱스로는 못 고칩니다

enable_mergejoin = off로 Nested Loop를 강제해 보면 77ms로 보이지만 8.8만 블록(약 690MB)을
만지며
ai.context_keyword를 Parallel Seq Scan으로 두 번 훑습니다. 어느 계획을 골라도 회원의
맥락 26,666건 × 키워드 테이블 조인 비용은 남습니다.

즉 쿼리 튜닝 대상이 아니라 호출 빈도를 줄이는 문제로 보입니다.

해법이 이미 명세에 있습니다

docs/ai/spec/feed-profile-cache.md 첫 줄:

현재 코드가 없는 구현 예정 명세입니다.

Cache Key TTL
사용자 관심 Profile feed:profile:{memberId} 6시간
Collection 특징 feed:coll:{collectionId} 1시간

TTL 6시간의 근거도 이 쿼리를 두고 쓴 문장으로 읽힙니다 — "Record 하나가 추가돼도 분포가 크게
흔들리지 않으므로 길게 잡습니다. 계산 비용도 상대적으로 큽니다."

Redis는 이미 떠 있고 현재는 refresh token 저장에만 쓰고 있습니다(@Cacheable 0건).

측정 해석에 중요한 한계

벤치 데이터에는 AI 파생 행이 없습니다.

ai.context_keyword 전체        213,290행  (전부 옛 시드 것)
회원 3008의 context_keyword         0행
회원 3008의 context            26,666행

즉 위 216ms는 결과가 0건인데도 나온 값입니다. 실제 운영처럼 맥락에 키워드가 붙어 있으면
조인이 행을 만들어 더 비싸질 수도 있고, 반대로 통계가 달라져 플래너가 다른 계획을 고를
수도 있습니다. AI 파생 데이터가 있는 볼륨에서 재측정해야 확정됩니다 — 그 판단과 재측정은
AI 파트 영역이라 제가 하지 않았습니다.

재현 방법

# 천만 건 벤치 볼륨 적재 (약 5분, 디스크 5.9GB)
bash loadtest/tools/run-massive.sh

# 운영과 같은 자원 한도를 얹고 측정
docker compose -p back -f compose.yaml -f compose.bench.yaml up -d postgres

# 회원 규모별 Profile 쿼리 비교 — 괴물 회원은 member 3008~3057 (record 20,000건)

되돌리기는 loadtest/tools/teardown-massive.sql입니다. 자세한 실행법은
loadtest/README.md「대량 벤치」절에 있습니다.

배경 문서

경계에 대해

FeedCandidateRepository·FeedKeywordRepositoryai 스키마는 AI 파트 소유이고 정본 명세도
그쪽에 있습니다. 저는 관측과 근거만 남깁니다. 캐시 도입은 TTL 동안 새 기록이 취향에
반영되지 않는 트레이드오프를 포함하므로(명세는 이벤트 기반 무효화 없이 TTL만 쓰기로 정하고
있습니다) 정책 결정이 필요한 사안으로 보입니다.

필요하면 재측정이나 벤치 환경 세팅은 도와드릴 수 있습니다.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions