Skip to content

[데모 발표] week4

Seongho Yun edited this page Dec 8, 2022 · 1 revision

프로젝트 소개

BoostForm

  • Google Forms와 유사한 형태의 설문조사 서비스

  • 회원끼리 설문조사를 공유할 수 있도록 게시판 제공

    data1

주요 이슈

스트레스 테스트 진행

  • Artillery와 Locust를 이용하여 테스트 진행

테스트 1

  • 테스트 대상
    • 배포 서버
  • 시나리오
    • 10초동안 초당 n명의 유저를 보낸다
    • 각 유저는 설문지 응답 페이지를 요청한 뒤(GET), 10초의 대기시간을 가진다
    • 대기시간이 끝난 뒤 설문지를 제출한다(POST)
  • 결과
    • 초당 50개의 응답 제출 요청 시 median 과 상위 95, 99 % 의 응답 속도간 차이가 크지 않음 (성능 저하 없음)

      data2

    • 초당 약 60개 이상의 응답 제출 요청 시 급격하게 Latency가 증가

    • 응답시간의 median 값과 상위 95, 99 % 의 응답 속도간 차이가 매우 커지는 현상 발생

      data3

    • 초당 100개 이상의 응답 제출 요청 시 응답 시간이 10초를 넘어가서 errors.ETIMEDOUT가 발생

      data4

테스트 2

  • 테스트 대상
    • 배포 서버
  • 시나리오
    • 설문지 게시판 api에 설문지 목록 요청
    • 1초에 1명씩 사용자를 늘린다. (최대 64명)
  • 결과
    • 초당 요청 횟수가 100회 전후에서 수렴한다.

    • 시간이 지날수록 응답시간도 함께 길어진다.

      data5

      data6

      data7

문제 원인 파악

  • mongoDB에서의 작업 병목 현상(추정)

    • 근거
      • 테스트 1 진행 중 배포 서버의 CPU 및 메모리 사용량을 모니터링 한 결과 문제가 발견되지 않음

        data8

      • 요청을 분산하여 보내었는데도 latency가 늦어지는 문제 발생

        • 배포 서버에 초당 50개, 로컬 서버에 초당 50개의 유저를 보냄

        • 배포 서버에서의 결과
          data9

        • 로컬 서버에서의 결과
          data10

        • 위의 두 실험 결과를 토대로 서버측의 문제는 아니라고 판단, DB상에 문제가 있을 것으로 추측함

  • 병목이 발생하고부터 DB의 성능이 저하됨

    • 병목이 발생하지 않도록 부하를 분산시킬 방법이 필요

해결 방법

  • 후보

    • Sharding

      • 설계의 어려움
        • 만약 하나의 query에서 여러 shard를 거치게 되는 경우, 오히려 성능 하향이 발생할 수

          있음

    • Caching

      • Redis를 활용한 Caching
      • 자주 읽혀지는 데이터를 캐싱하여 DB의 읽기를 분산시킨다.
      • 대량의 쓰기 요청에 대해 속도가 빠른 Redis에 우선 저장하여 쓰기 부하를 받고 DB에 천천히 업데이트 시킨다.
    • Scale Up

      • mongoDB Atlas에서 무료로 제공하는 DB의 경우 성능이 매우 낮음
      • mongoDB Atlas 업그레이드
        • 비용 발생 (NCP 캐시 사용 불가)
      • NCP에서 제공하는 Cloud DB for MongoDB 사용
        • 레플리카 셋이나 샤드를 쉽게 구성할 수 있다.
        • 가격이 매우 비쌈
      • 서버 인스턴스를 생성한 뒤 mongoDB를 직접 설치
        • 제일 간단해 보이는 방법
  • 토의 결과

    • Sharding
      • shard 구성을 하려면 현재 atlas에서는 불가
        • NCP로 가던 atlas에서 업그레이드를 하던 scale-up이 우선되어야 함
      • mongoDB 샤딩에 대한 학습
      • DevOps적인 성향이 강함. 실무에서는 mongoDB 샤딩을 직접 구성할 일이 적을 것이라 판단됨
    • Scalue Up
      • 제일 간단해 보이는 작업
      • 비용 발생
      • 하지만, 기술적으로 도전할 부분이 적음
    • Caching
      • 성능적으로 제일 큰 향상이 기대됨
      • 캐시에 대한 학습
      • 실무에서도 많이 사용되는 기술

    최종적으로, 우선 Caching을 적용하기로 하였다

Caching 적용

Caching 전략에 대한 고민

  • 설문지 호출 API

    • 읽기 전략

      data11

      • 하나의 설문지에 사람이 몰리는 경우(즉, 반복적인 읽기가 대량으로 발생하는 경우)를

        고려했을 때, Look Aside 패턴이 적합하다고 판단

      • Look Aside 패턴만 사용할 경우, 설문지가 업데이트 되는 경우에 Cache와 DB간에 데이터 정합성 문제가 발생할 수 있음

        • 응답자가 설문지에 올바른 응답을 할 수 있기 위해서는 설문지 데이터의 정합성이 중요함

        • 설문지 업데이트 시 Cache상에도 업데이트 하도록 함

          (설문지 업데이트에 한해서 Write through 적용)

  • 설문지 응답 API

    • 쓰기 전략

      data12

      • 설문지 작성이 몰리는 경우 (짧은 시간에 과도한 insert 작업이 발생하는 경우)
      • Cache에 설문지 작성 내용을 빠르게 저장한 뒤, 빠르게 응답을 줌
      • 일정 주기마다 Cache의 데이터를 DB로 저장
  • 게시판 관련 API

    • 읽기 전략

      data13

      • Look Aside 패턴 사용

      • 첫 페이지 호출, 정렬 기능에서만 사용(검색 기능에서는 사용하지 않음)

        • 검색의 경우, 경우의 수가 다양하기 때문에, Look Aside 패턴에 적합하지 않다고

          판단(miss가 나올 확률이 높다)

      • 작성된 설문지가 실시간으로 게시판에 노출된 필요는 없기에 캐시와 DB의 정합성을 2분 주기로 맞춰지도록 캐시 데이터에 2분의 유효기간 설정

  • 우선 Caching을 읽기 작업에만 적용해 보고, 실제로 성능 향상이 있다면 쓰기 작업에도

    적용하기로 함

  • 실제 성능 개선이 있을 시, 쓰기 작업에도 Caching 적용 예정

Caching 적용 결과

  • 설문지 조회

    • 10초동안 초당 200개의 설문지 요청을 보냄
      • 수정 전

        https://user-images.githubusercontent.com/96734037/204943794-bf34a4c2-f428-468b-88a3-414ed1543272.png

        https://user-images.githubusercontent.com/96734037/204943804-87df6c4d-13b0-4567-9d12-0e27596425c0.png

      • 수정 후

        https://user-images.githubusercontent.com/96734037/204943827-9061db34-5729-47ff-b68c-bff3b57ce3c6.png

        https://user-images.githubusercontent.com/96734037/204943834-daae770e-9693-45a7-9be2-09647c719b59.png

  • 설문지 게시판 검색

    • 검색 api - RPS

      • 수정 전

        https://user-images.githubusercontent.com/96734037/204943885-319d580e-5cad-4c76-8a59-aefc02c74b47.png

      • 수정 후

        https://user-images.githubusercontent.com/96734037/204943896-f673b9dc-9130-461a-9e87-7a0846a42e8d.png

    • 검색 api - 응답 시간

      • 수정 전 https://user-images.githubusercontent.com/96734037/204943910-40c7aae7-3940-4223-a1ca-ced45ae97fb0.png

      • 수정 후
        https://user-images.githubusercontent.com/96734037/204943917-2b4ca1d5-a78e-4f87-9252-cfcd7da65b7e.png

회고

  • 읽기 작업에서 확실히 성능 개선을 보였으니, 쓰기 작업에도 도입해 보자
  • 성능 개선이 나타난 것은 좋긴한데…
    • 애초에 현재 사용하고 있는 mongoDB Atlas의 성능이 너무 안 좋았기 때문에 이런 극적인

      성능 개선이 나타난 것 아닐까?

      • 다음에는 DB Scale Up도 고려해 볼까?
    • 주어진 환경에서 최소한의 비용으로 문제를 해결했다는 것은 매우 의미 있다고 생각

데모 시연

Home

규칙

프로젝트 계획

스프린트 회의록

데일리 스크럼

week 1
week 2
week 3
week 4
week 5
week 6

회고록

데모

Problem & Solving

Clone this wiki locally