[Volume 5] 인덱스와 캐시를 활용한 조회 읽기 성능 최적화#223
Open
dd-jiny wants to merge 5 commits intoLoopers-dev-lab:dd-jinyfrom
Open
[Volume 5] 인덱스와 캐시를 활용한 조회 읽기 성능 최적화#223dd-jiny wants to merge 5 commits intoLoopers-dev-lab:dd-jinyfrom
dd-jiny wants to merge 5 commits intoLoopers-dev-lab:dd-jinyfrom
Conversation
fix : 예제 테스트 코드 오류 해결을 위한 testcontainers 버전 업
|
Important Review skippedToo many files! This PR contains 191 files, which is 41 over the limit of 150. ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (191)
You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment Tip CodeRabbit can use Trivy to scan for security misconfigurations and secrets in Infrastructure as Code files.Add a .trivyignore file to your project to customize which findings Trivy reports. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📌 Summary
🧭 Context & Decision
문제 정의
인덱스
캐시
선택지와 결정
인덱스
캐시
🏗️ Design Overview
변경 범위
CacheConfig,TwoLevelCache,TwoLevelCacheManager(infrastructure/cache)RedisCacheIntegrationTest,TwoLevelCacheIntegrationTest,CacheBenchmarkTest확정 인덱스 목록 (9개)
idx_products_status_createdProductJpaRepository.findAllForCustomerPaged()idx_products_status_likeProductJpaRepository.findAllForCustomerPaged()idx_orders_status_del_expiresOrderJpaRepository.findExpiredPendingOrders()idx_products_brand_delProductJpaRepository.findAllByBrandId()idx_orders_user_createdOrderJpaRepository.findAllByUserIdAndPeriod()idx_orders_user_statusOrderJpaRepository.countByUserIdAndStatus()idx_orders_del_createdOrderJpaRepository.findAllByPeriod()idx_brands_del_displayBrandJpaRepository.findAllByDelYnAndDisplayStatus()idx_order_items_del_productOrderItemJpaRepository.findAllByOrderIdIn()캐시 적용 클래스 및 메서드
@Cacheable@CacheEvictproductDetailProductService.findById()updateProduct(),deleteProduct(),changeSaleStatus(),incrementLikeCount(),decrementLikeCount()stockAvailableStockService.findByProductId()hold(),release(),commit()brandDetailBrandService.findById()updateBrand(),deleteBrand()authUserUserService.findByLoginId()changePassword()productListProductFacade.getCachedProductList()createProduct(),updateProduct()—allEntries=truestatsOverviewStatsService.getOverview()statsDailyStatsService.getDailyOrderStats()statsTopLikedStatsService.getTopLikedProducts()statsTopOrderedStatsService.getTopOrderedProducts()statsLowStockStatsService.getLowStockProducts()주요 컴포넌트 책임
CacheConfig: 캐시 매니저 구성 (Redis + Caffeine), 캐시별 TTL 설정,CacheErrorHandler로 Redis 장애 시 graceful degradationTwoLevelCache: L1 → L2 순차 조회, 양방향 put/evict 동기화TwoLevelCacheManager: 캐시 이름 기반으로 L1+L2 또는 L2-only 라우팅🔍 리뷰 포인트
캐시 전략에 대해 리뷰 부탁드립니다. 각 조회 패턴별로 어떤 전략을 적용했는지 정리하고, 판단이 어려웠던 부분을 질문으로 남겼습니다.
조회 패턴별 캐시 전략 요약
리뷰 요청 사항
allEntries=true로 목록 캐시를 전부 날리는데, 관리자 수정이 잦을 경우 hit rate가 떨어질 수 있습니다. 이 전략이 적절한지 피드백 부탁드립니다.|
🔁 Flow Diagram
인덱스 실험 프로세스
flowchart TD A[인덱스 없는 상태에서 EXPLAIN] --> B[후보 A 생성 → EXPLAIN → 드랍] B --> C[후보 B 생성 → EXPLAIN → 드랍] C --> D{후보 비교} D -->|filesort 제거 + filtered 100%| E[최적 인덱스 확정] D -->|트레이드오프 존재| F[쓰기 비용 vs 읽기 성능 판단] F --> E E --> G[SHOW PROFILES로 실행시간 비교]캐시 조회 흐름 (L1+L2)
sequenceDiagram autonumber participant Client participant Controller participant Service participant L1 as L1 (Caffeine) participant L2 as L2 (Redis) participant DB as MySQL Client->>Controller: GET /api/v1/products/{id} Controller->>Service: findById(id) Note over Service,L1: @Cacheable("productDetail") Service->>L1: get(key) alt L1 Hit L1-->>Service: cached value else L1 Miss Service->>L2: get(key) alt L2 Hit L2-->>Service: cached value Service->>L1: put(key, value) else L2 Miss Service->>DB: SELECT * FROM products DB-->>Service: result Service->>L2: put(key, value) Service->>L1: put(key, value) end end Service-->>Controller: ProductModel Controller-->>Client: ApiResponse캐시 무효화 흐름
sequenceDiagram autonumber participant Admin participant Controller participant Facade participant Service participant L1 as L1 (Caffeine) participant L2 as L2 (Redis) Admin->>Controller: PUT /api-admin/v1/products/{id} Controller->>Facade: updateProduct(id, command) Note over Facade,L2: @CacheEvict("productList", allEntries=true) Facade->>Service: updateProduct(id, command) Note over Service,L2: @CacheEvict("productDetail", key="#productId") Service->>L1: evict(productDetail::id) Service->>L2: evict(productDetail::id) Facade->>L1: clear(productList) Facade->>L2: clear(productList) Facade-->>Controller: updated Controller-->>Admin: ApiResponse📊 성능 비교 결과
인덱스 실행 시간 (Before → After)
products 쿼리
orders 쿼리
악화 원인
k6 부하 테스트 — L2-only vs L1+L2 비교
비교 분석 요약
테스트 환경 제약 (WSL2)
5배, 디스크 I/O 310배 느림