[내일배움캠프 Spring 심화] 2024.08.12 TIL

박상훈·2024년 8월 12일

[내일배움캠프] TIL

목록 보기
10/20

대규모 스트림에 대한 기본 지식을 습득했다.


대규모 시스템이란?

  • 인터넷 환경에서는 수백만 명의 사용자가 동시에 접속하고 상호작용할 수 있는 시스템을 구축해야 하는 상황이 자주 발생한다.
  • 이러한 시스템은 단순히 많은 사용자를 처리하는 것 뿐만 아니라, 안정성과 신뢰성을 유지하면서 고성능을 제공해야 한다.
  • 그렇다면 어떠한 기준으로 대규모 시스템을 설계해야 할까?

동시 접속자와 초당 요청량(TPS)

사용자 수

  • 대규모 시스템을 설계할 때 가장 중요한 요소 중 하나는 사용자 수이다.

TPS(Transactions Per Second)

  • 시스템은 초당 요청량(TPS)을 견딜 수 있어야 한다.
  • 예상치 못한 이벤트로 인해 설계 예상 이상의 요청이 몰린다면 시스템이 중단될 수 있다.

요청 종류에 따른 개발

시스템이 읽기 전용인지, 쓰기 및 업데이트를 위한 것인지도 중요하다. 이를 파악하고 처리 속도를 빠르게 하여 응답한다면 보다 많은 사용자를 수용할 수 있다.

읽기 요청 최적화

  • 캐시 사용

    • 모든 사용자가 같은 데이터를 요청하는 경우, 이를 해소하기 위해 DB의 데이터를 레디스에 올려 응답 속도를 빠르게 한다.

    • 캐시를 사용하면 데이터를 빠르게 제공할 수 있으며, DB의 부하를 줄일 수 있다.

    • 개인화 데이터가 아니라면 캐시를 사용하여 데이터 로드에 시간 소요를 최소화 하는 방법이 중요하다.

    • 데이터에서 필터된 데이터를 가져오는것보다 레디스에서 필터된 데이터를 가져오거나 애플리케이션 로직에서 필터링을 수행하는것이 성능상 더 큰 이점을 가질 것이다.

    • 엣지 단에서 캐싱을 처리하면 시스템의 요청 처리량이 줄어들어 적은 수의 애플리캐이션으로도 요청을 처리할 수 있다. 엣지 캐싱은 사용자와 가까운 곳에서 데이터를 제공하므로 네트워크 지연을 최소화하고, 사용자 경험을 향상시키는 것이 가능하다.

    • 캐싱 전략을 설계할 때는 캐시 갱신 정책도 중요하다. 예를 들어, 공지사항이 자주 변경되지 않는 경우에는 캐시의 유효 기간을 길게 설정할 수 있다. 반면, 변경이 잦은 경우에는 짧은 유효 기간을 설정하거나, 변경 시점에 캐시를 무효화하여 최신 데이터를 제공할 수 있도록 해야 한다. 이러한 캐싱 전략을 통해 시스템의 효율성을 극대화할 수 있다.

  • 데이터 베이스 사용 최적화

    • 데이터베이스 인덱싱 : 데이터베이스 인덱싱은 조회 성능을 크게 향상시킬 수 있는 방법이다. 인덱스를 사용하면 데이터베이스는 데이터를 빠르게 검색할 수 있다. 올바르게 설계된 인덱스는 읽기 성능을 최적화하고 쿼리 응답 시간을 줄인다. 주의할 점은 인덱스가 너무 많으면 쓰기 성능이 저하될 수 있다는 것이다.

    • 데이터베이스 샤딩 : 데이터베이스 샤딩은 데이터베이스를 여러 샤드로 분할하여 각각의 샤드가 독립적으로 쿼리를 처리하도록 하는 방법이다. 이를 통해 단일 데이터베이스에 대한 부하를 분산시킬 수 있으며, 읽기 요청에 대한 응답 속도를 향상시킬 수 있다. 예를 들어, 사용자 데이터를 여러 샤드에 분산 저장하여 읽기 성능을 최적화할 수 있다.

      • 예를 들어 테이블 파티셔닝을 생각해볼 수 있다. 이는 기본적인 형태의 샤딩으로, 데이터베이스 수준에서 데이터를 분할한다.
        CREATE TABLE orders (
          order_id SERIAL PRIMARY KEY,
          customer_id INT,
          order_date DATE,
          amount DECIMAL
        ) PARTITION BY RANGE (order_date);
        
        CREATE TABLE orders_2023_01 PARTITION OF orders FOR VALUES FROM ('2023-01-01') TO ('2023-02-01');
        CREATE TABLE orders_2023_02 PARTITION OF orders FOR VALUES FROM ('2023-02-01') TO ('2023-03-01');
        
    • 읽기 전용 데이터베이스 : 읽기 전용 데이터베이스는 주로 읽기 요청을 처리하는 데이터베이스 인스턴스이다. 쓰기 전용 데이터베이스와 읽기 전용 데이터베이스를 따로 두고 비교적 요청이 많은 Read 요청에 대한 데이터베이스의 수를 늘려 데이터베이스에 대한 읽기 부하를 줄이고 성능을 최적화할 수 있다.

    • 쿼리 최적화 : 쿼리 최적화는 SQL 쿼리를 효율적으로 작성하여 데이터베이스의 읽기 성능을 향상시키는 방법이다. 예를 들어, 불필요한 조인을 줄이고, 필요한 컬럼만 선택하며, 적절한 조건을 사용하는 것이 중요하다. 쿼리 실행 계획을 분석하여 병목 지점을 찾아내고, 이를 최적화할 수 있다.

쓰기 요청 최적화

쓰기 요청도 가장 많은 시간을 소요하는 부분은 DB에 데이터를 생성하는 부분이다. 이를 해결하기 위한 다양한 방법이 있다.

비동기 처리

  • 쓰기 요청을 비동기 방식으로 처리하여 DB에 접근하지 않고도 빠르게 응답을 반환할 수 있다.

  • 예를 들어 메시지를 바로 DB에 쓰지 않고, 큐에 넣어 나중에 처리하는 방법이 있다.

  • 비동기 처리 시 데이터 소실이나 오류를 방지하기 위해 큐에 데이터를 넣을 때 적절한 검증을 수행하고, 큐에 쌓인 데이터를 지속적으로 모니터링하여 실패한 요청을 재시도할 수 있는 메커니즘을 마련해야 한다.

배치 처리

  • 실시간으로 처리할 필요가 없는 쓰기 요청은 배치 처리를 통해 한꺼번에 처리할 수 있다.

  • 예를 들어 일정 시간마다 큐에 쌓인 메시지를 DB에 쓰는 방법이 있다.

  • 배치 처리 시에도 데이터 소실을 방지하기 위해 배치 작업 중 오류가 발생한 경우 이를 기록하고, 재시도할 수 있는 메커니즘을 마련해야 한다.

분산 DB

  • 단일 DB로 모든 요청을 처리하기 어렵다면 여러 개의 DB 인스턴스를 사용하여 각 인스턴스가 특정 사용자 그룹의 데이터를 처리하도록 할 수 있다.

  • 분산 DB는 데이터를 여러 개의 노드에 분산 저장하여 고가용성과 확장성을 제공한다.

  • 또한, 샤딩(Sharding) 기법을 통해 데이터베이스를 수평으로 분할하여 각 샤드가 독립적으로 쓰기 작업을 처리하도록 할 수 있다. 이를 통해 단일 노드의 부하를 줄이고, 시스템의 전체 성능을 향상시킬 수 있다.

📌 분산 DB 사용 시 데이터 일관성을 유지하기 위해 트랜잭션 관리와 데이터 동기화에 신경 써야 한다. 예를 들어, 분산 트랜잭션이나 이벤트 소싱을 사용하여 데이터 일관성을 유지할 수 있다.

데이터 일관성 유지

📌 대규모 시스템에서는 데이터 일관성을 유지하는 것이 중요하다. 이를 위해 분산 트랜잭션, 이벤트 소싱, CQRS(Command Query Responsibility Segregation) 등의 기법을 사용할 수 있다.

분산 트랜잭션

  • 여러 개의 독립된 시스템이나 데이터베이스에서 동시에 일어나는 트랜잭션을 일관되게 관리하는 방법

  • 단일 트랜잭션이 여러 시스템에 걸쳐 발생할 때, 모든 시스템이 해당 트랜잭션을 성공적으로 완료하거나, 모든 시스템이 트랜잭션을 실패 처리하도록 보장하여 데이터의 일관성을 유지할 수 있다.

  • MSA에서 여러 서비스가 독립적으로 운영되기 때문에 분산 트랜잭션이 필요하다.

이벤트 소싱

  • 데이터 상태 변화를 이벤트로 기록하고, 해당 이벤트들을 순차적을 재생하여 현재 상태를 파악하는 방법

  • 데이터 변경 자체가 아닌 변경 이벤트를 저장하여 데이터 일관성과 추적 가능성을 높이는 데 유용하다.

  • 복잡성이 증가할 수 있으므로 시스템의 요구사항에 따라 신중하게 적용해야 한다.

CQRS

  • CQRS는 명령(Query)과 조회(Query)의 책임을 분리하는 소프트웨어 디자인 패턴

  • 이 패턴은 읽기 작업과 쓰기 작업을 서로 다른 모델로 분리하여, 각 작업에 최적화된 구조를 사용할 수 있도록 한다.

  • CQRS는 시스템의 성능, 확장성, 유지보수성을 향상시키는 데 도움이 된다.


profile
안녕하세요

0개의 댓글