Skip to content

Technical Decision

kyeonkim edited this page Oct 24, 2024 · 5 revisions

Elastic Search 도입으로 검색 성능 최적화

Elastic Search 도입 배경

  • 기존 RDB 검색 방식

    • 정확한 값 매칭에 최적화 되어있지만 Like 검색시 전체 테이블의 스캔이 필요
    • 와일드 카드 검색시 인덱스 활용 불가
    • 부분 일치 검색 시 성능 저하

    → 대용량 데이터 처리가 가능하고 실시간으로 색인 및 검색이 가능한 Elastic Search 도입

데이터 구조와 저장방식

  • 비정형 데이터를 처리하는데 최적화
  • 역색인을 활용하여 검색 성능 극대화
  • 대용량 데이터에서 빠른 검색 속도가 필요한 경우 유리

검색 성능

  • 대규모 텍스트 기반 고속 검색 제공
  • 분산 환경에서 동작할 수 있어 확장성이 뛰어남

복잡한 쿼리 지원

  • Match Query, Range Query, Bool Query 등 다양한 쿼리 지원
  • 복합적인 검색 조건과 필터링 적용 가능

Redis sorted set을 이용한 게이트웨이 대기열

게이트웨이 대기열 도입 배경

  • 단일 API가 아닌 게이트웨이에 대기열을 만들어 서비스의 전체적인 트래픽을 조절하기 위해 도입
  • Rank 등 다양한 기능을 제공하는 Redis의 Sorted set으로 대기열 구현

Redis sorted Set

  • 클라이언트 요청이 들어올때마다 현재 시간을 score로 하여 score가 낮은 순서대로 요청 처리
  • Proceed Queue 사용자들의 활동 시간을 추적해 일정 시간 이상 활동이 없을 경우 proceed queue에서 제거

Queue Filter

  • gateway filter로 대기열 필터를 구현해 들어오는 모든 요청 관리
  • Scheduled로 30초에 한번씩 proceed 대기열의 빈자리 확인 및 이동

상품 저장소를 Cassandra로 선택하여 스케일아웃 상황에 유리하도록 구축

우리 시스템 상품 데이터의 특징

  • 양이 방대하고 다양한 필터링, 정렬조건들로 조회가 필요함
  • 조회성능 확보가 중요하고 분산환경에서도 처리가 가능해야함

NoSQL, 카산드라를 선택한 이유

  • 트랜잭션 처리와 테이블 관계 저장에 유리한 관계형 DB보다 조회성능에서 더 유리한 NoSQL을 선택
  • 카산드라는 노드기반의 분산구조라 수평확장이 다른 NoSQL보다 쉬움 (노드추가)
  • 모든 노드가 독립적으로 읽기 쓰기작업을 진행하여 특정노드가 문제있을때도 가용성을 보장
  • 컬렉션 구조에 맞지않는 데이터를 저장할 수 있거나 중복을 허용할 수 있는 다른 서비스보단 일관되게 저장하기 때문에 구조가 정형화된 상품 데이터에 적합하다고 생각함

Redis 기반 캐싱을 통한 장바구니 및 카테고리 조회 성능 최적화

Redis

  • 높은 성능과 낮은 지연 시간
  • 유연한 데이터 구조
  • 실시간 데이터 처리가 가능한 인메모리 데이터 저장소

도입 배경

  • 장바구니 데이터 사용자별 실시간 업데이트가 필요, 만료기한 30일
  • 카테고리 데이터 자주 조회되지만 변경 빈도 낮음

Redis 도입으로 성능 최적화 및 데이터베이스 부하 감소

장바구니 캐싱

  • 실시간 업데이트 장바구니 조회 시에만 데이터베이스를 조회하고, 그 외 작업은 Redis에서 처리하여 I/O 부하를 줄임
  • TTL 30일이 지난 데이터를 자동으로 삭제

카테고리 데이터 캐싱

  • 빠른 조회 변경이 적은 카테고리 데이터를 Redis에 캐싱하여 신속하게 조회

→ 대규모 트래픽에도 안정적인 성능 유지

Redisson 분산 락을 활용해 쿠폰발행/재고차감/사전예약수량의 동시성 이슈를 해결

도입 배경

  • 쿠폰 발행 여러 사용자가 동시에 쿠폰을 요청할 경우 데이터 무결성 유지 필요
  • 재고 관리 여러 클라이언트가 동시에 재고를 수정할 경우 데이터 무결성 유지 필요
  • 사전예약주문 동시에 주문을 요청할 경우 한정된 사전예약수량만큼만 진행되도록 구현해야함

Redisson vs. Zookeeper

  • Redisson
    • 높은 성능과 사용 용이성
    • 자동 락 타임아웃
    • 다양한 락 유형 지원
  • Zookeeper
    • 고가용성
    • 강력한 일관성
    • 클러스터 관리
    • 복잡한 설정 및 운영
  • Redisson 선택
    • 기존의 캐시로 Redis를 사용중이었기 때문에 확장성 면에서 Redisson을 선택
    • 대용량 트래픽 기반의 서비스에서 안정적이고 효율적인 분산 락 지원

Kafka를 이용하여 대규모 트래픽 처리 및 모듈 간 비동기 메시지 전송

Kafka 도입을 고민한 이유

  • 극한의 트래픽 상황에서 높은 처리량과 빠른 응답 속도를 제공하여 신뢰성 확보가 필요
  • 트랜잭션 처리시간이 길고 처리량 수치가 낮아 중요도가 낮은 로직의 비동기 처리가 필요
  • 대용량 스트리밍 데이터 처리에 강점을 가지고 있고 메시지의 영속성을 보장하는 카프카를 도입

Kafka vs RabbitMQ

  • RabbitMQ는 복잡한 라우팅메커니즘으로 인한 오버헤드로 성능저하가 될 가능성이 있음
  • 높은 데이터 처리, 분산환경에 더 적합한 카프카를 선택

이미지 저장과 썸네일 생성을 외부에서 처리하여 API 성능 개선

이미지 외부저장소 도입의 목적

  • DB에 이미지 저장시 용량 증가, 바이너리 형식 변환 등으로 상품저장시 트랜잭션 시간이 길어지는 등의 문제 발생
  • DB I/O로 인한 오버헤드 증가로 API 성능에 악영향을 줄 수 있어 외부 저장소를 도입

AWS S3 + Lambda 조합을 선택한 이유

  • 기존 인프라 구성을 AWS에서 진행하고 있어 이미지 저장소도 AWS S3를 선택
  • S3는 확장성, 가용성이 뛰어나 대규모 트래픽 환경에서도 안정적으로 이미지 저장
  • 썸네일 생성은 서버리스인 Lambda에서 처리하여 요청이 많을떄에도 안정적으로 생성할 수 있도록 구현