여기 참조

객체가 직접적으로 기능을 수행하는 대신에 다른 객체에 해당 기능을 위임

인터페이스를 이용하여 구현하는 경우가 많음

 

예시

public enum PrinterType {
    LASER, INKJET
}

public interface Printer {
    void printDocument(String document);
    PrinterType getType();
    boolean isSameType(PrinterType type);
}

public class LaserPrinter implements Printer {
    @Override
    public void printDocument(String document) {
        System.out.println("Laser Printer printing: " + document);
    }
    
    @Override
    public PrinterType getType() {
        return PrinterType.LASER;
    }
    
    @Override
    public boolean isSameType(PrinterType type) {
        return PrinterType.LASER.equals(type);
    }
}

public class InkjetPrinter implements Printer {
    @Override
    public void printDocument(String document) {
        System.out.println("Inkjet Printer printing: " + document);
    }

    @Override
    public PrinterType getType() {
        return PrinterType.INKJET;
    }
    
    @Override
    public boolean isSameType(PrinterType type) {
        return PrinterType.INKJET.equals(type);
    }
}

public class PrinterManager {
    private final List<Printer> printers;
    
    public PrinterManager() {
        printers = new ArrayList<>();
        printers.add(new LaserPrinter());
        printers.add(new InkjetPrinter());
    }

    public void print(String document, PrinterType type) {
        printers.stream()
                .filter(printer -> printer.isSameType(type))
                .forEach(printer -> printer.printDocument(document));
    }
}

public class Client {
    public static void main(String[] args) {
        PrinterManager manager = new PrinterManager();
        manager.print("Hello, world!", PrinterType.LASER); // "Laser Printer printing: Hello, world!" 출력
        manager.print("Hello, world!", PrinterType.INKJET); // "Ink
    }
}

 

위임의 장점

  • 객체간 결합도가 낮아짐
  • 런타임에 구현체를 변경 가능(어차피 빌드는 다시해야하지 않나?)
  • 위임하는 객체의 코드를 변경할 필요 없이 구현체를 추가하거나 교체하기 쉬움
반응형

'System Architect' 카테고리의 다른 글

Application  (0) 2023.10.28
graphQL  (0) 2023.10.12
gRPC  (0) 2023.10.11
시스템설계 Q&A 2  (0) 2023.09.20
데이터 분석 관련 정리  (0) 2023.08.19

"응용 프로그램"은 사용자가 특정 작업을 수행하기 위해 실행하는 소프트웨어를 가리킵니다.

이 응용 프로그램은 전통적인 모놀리식 구조일 수도 있고, MSA(Microservices Architecture)와 같은 구조일 수도 있습니다.

따라서 Application은  MSA보다 더 넓은 범위를 가집니다.


응용 프로그램(Application)

사용자가 특정 작업을 수행하기 위해 실행하는 소프트웨어의 집합.

전통적인 모놀리식 구조일 수도 있고, MSA(Microservices Architecture)와 같은 구조일 수도 있습니다.

 

MSA (Microservices Architecture)

응용 프로그램을 작은 서비스들로 분리하는 아키텍처 스타일.
각 서비스는 특정 기능에 초점을 맞추며 독립적으로 동작합니다.

반응형

'System Architect' 카테고리의 다른 글

위임(delegate) 패턴  (0) 2024.02.17
graphQL  (0) 2023.10.12
gRPC  (0) 2023.10.11
시스템설계 Q&A 2  (0) 2023.09.20
데이터 분석 관련 정리  (0) 2023.08.19

개요

RESTful API: N endpoints
GraphQL: 단일 endpoint

조회는 Query, 생성/수정/삭제는 Mutation 이라고 함

 

명시적 정의와 자유도

  • 명시적 정의
    • GraphQL은 서버 개발자에게 데이터 타입, 쿼리, 뮤테이션을 명시적으로 정의하도록 요구합니다. 
      이는 GraphQL 스키마에서 수행되며, 서버가 제공할 수 있는 데이터와 작업을 명확하게 정의합니다.
      예를 들어, 서버 개발자는 사용자 데이터를 반환하는 getUser 쿼리와 사용자 데이터를 업데이트하는 updateUser 뮤테이션을 스키마에 정의할 수 있습니다.
  • 클라이언트의 자유도 (Client Flexibility):
    • 클라이언트는 서버에 정의된 스키마를 기반으로 데이터를 요청합니다. 
      • 필드 선택 (Field Selection):
        • 클라이언트는 쿼리를 통해 필요한 필드만 선택할 수 있습니다. 예를 들어, 사용자 객체에 대한 쿼리를 만들 때, 클라이언트는 이름과 이메일만 요청할 수 있으며, 다른 필드는 무시할 수 있습니다. 이는 네트워크 트래픽을 최적화하고, 필요한 데이터만 가져오도록 할 수 있습니다.
      • 중첩 및 복잡한 쿼리 (Nested and Complex Queries):
        • 또한, 클라이언트는 중첩된 쿼리를 생성하여 관련된 객체와 필드를 한 번의 요청으로 가져올 수 있습니다. 이는 데이터의 관계와 구조를 유연하게 표현할 수 있으며, 복잡한 데이터 요청을 단순화할 수 있습니다.
      • 응답 구조의 맞춤화 (Customized Response Structure):
        • 클라이언트는 요청의 구조를 지정할 수 있으며, 서버는 클라이언트의 요청에 따라 응답을 제공합니다. 이는 클라이언트가 받고 싶은 데이터의 구조를 정확하게 지정할 수 있게 해줍니다.

스키마

아래와 같은 스키마 개념이 있다.(여기 참조)

type Query {
  bookById(id: ID): Book
}

type Book {
  id: ID
  name: String
  pageCount: Int
  author: Author
}

type Author {
  id: ID
  firstName: String
  lastName: String
}

 

 

장단점

 

Q&A

  • 아니 무슨 단일 endpoint라고 자랑하더니 mutation마다 명세서를 만들어야 하는거 같네.(암튼 클라이언트 맘대로 쿼리하는 방임형 자유는 아닌거 같네) 이럴거면 endpoint 여러개인거랑 뭐가 다르지? Query의 경우는 개별 명세서가 필요 없나?
  • federation?
반응형

'System Architect' 카테고리의 다른 글

위임(delegate) 패턴  (0) 2024.02.17
Application  (0) 2023.10.28
gRPC  (0) 2023.10.11
시스템설계 Q&A 2  (0) 2023.09.20
데이터 분석 관련 정리  (0) 2023.08.19

개요

gRPC는 Google이 개발한 고성능, 오픈 소스 및 범용의 원격 프로시저 호출(RPC) 프레임워크입니다. 

효율적인 프로토콜로, 서버 간 통신에 아주 적합하며, Protocol Buffers를 사용하여 타입을 정의하고, 강력한 타입 검사와 높은 성능을 제공합니다.
이는 서로 다른 시스템 간에 통신을 가능하게 하며, 다양한 환경과 언어에서 작동합니다. 

 

gRPC는 2015년 3월에 Google이 Stubby의 다음 버전을 개발하고 오픈 소스로 만들기로 결정했을 때 처음 생성되었습니다. gRPC의 최초 릴리스는 2016년 8월에 이루어졌습니다​. 현재 gRPC의 최신 버전은 1.59.1(2023년 10월 6일기준)

 

장점:

  • 기존의 REST등 텍스트 기반 프로토콜보다 더 효율적인 바이너리 프로토콜을 제공하여, 데이터 전송의 오버헤드를 줄이고 성능을 향상시킵니다.   
  • 컨트랙트 첫 접근 방식: 서비스의 인터페이스와 메시지를 먼저 정의하고, 이를 기반으로 코드를 생성합니다.
    (Protocol Buffers를 사용하여 데이터를 직렬화하고 역직렬화하여, 높은 성능을 제공합니다.)
  • 스트리밍 및 빠른 통신: 양방향 스트리밍과 빠른 통신을 지원하여, 실시간 애플리케이션에 이상적입니다.
  • 비동기 콜도 지원하는 것 같다.

단점:

  • 복잡성: gRPC는 설정과 디버깅이 복잡할 수 있으며, 새로운 사용자에게 진입 장벽을 제공할 수 있습니다.
  • 텍스트 기반 포맷의 부족: gRPC는 바이너리 프로토콜을 사용하므로, 텍스트 기반 프로토콜보다 디버깅이 어려울 수 있습니다.
  • 브라우저 지원: gRPC-Web을 통해 브라우저에서 gRPC를 사용할 수 있지만, 네이티브 gRPC 클라이언트보다 기능이 제한적일 수 있습니다.

 

vs REST

REST는 HTTP/1.1을 기반으로 하며, 텍스트 기반의 JSON 또는 XML을 사용하여 데이터를 전송합니다. 이에 비해 gRPC는 HTTP/2를 기반으로 하며, 바이너리 기반의 Protocol Buffers를 사용합니다.
gRPC는 REST보다 더 높은 성능과 더 낮은 데이터 오버헤드를 제공하지만, REST는 더 단순하고 더 넓게 지원됩니다.

 

 

spring과 연동하기

여기 참조

 

TMI

굳이 protobuf를 별도 포맷으로 했는데(yml, json, xml등을 사용하지 않고), verbose하지 않고 간결한 것이 장점인 것 같다. (다른 이유는 굳이 없는듯)

gRPC는 일반적으로 REST와 별개 포트로 구성(graphQL은 REST와 같은 포트로 보통하는듯)

반응형

'System Architect' 카테고리의 다른 글

Application  (0) 2023.10.28
graphQL  (0) 2023.10.12
시스템설계 Q&A 2  (0) 2023.09.20
데이터 분석 관련 정리  (0) 2023.08.19
시스템설계 Q&A  (0) 2023.08.08

Q. 설계 디자인 문제의 경우 초기에 질문할 것들은?

  • 기능적 요구사항
  • 비기능적 요구사항
    • 성능, 확장성, 안정성, 보안
    • 비용최적화
    • 트래픽패턴
  • 제약사항
    • 벤드위스, 시스템사양, 외부시스템 디펜던시
  • 프로세스
    • 스케일아웃등 의사결정시 데이터 포인트 필요(응답시간, 에러율, CPU/메모리/IO사용율, 대기중인요청, 스레드개수등)
    • 메트릭측정
    • 필드테스트전 로드테스트(환경구축 필요)

Q. 과부하처리

  • 웹서버/WAS
    • 정적컨텐츠면 CDN(Content Delivery Network) 고려
    • 커넥션풀
    • 로드밸런싱(리버스 프록시)
    • Scale up, Scale out
    • Auto Scaling
  • DB
    • 쿼리최적화/인덱싱
    • 머터리얼뷰(정규화 수준 낮추기)
    • Master/Slave분리
    • 샤딩, 분산트렌젝션(2단계 커밋)
    • NoSQL도입(쓰기작업이 많거나, 주문서등 비정형 데이터 저장)
    • 이벤트소싱(CQRS)
  •  캐시적용(Redis등)
    • 읽는경우: Look aside. Cache에 있으면 Cache에서 가져오고 없으면 DB에서 읽고 Cache에 업데이트
    • 쓰는경우:
      • Write Through. 항상 cache에 저장하고 DB에도 저장
      • Write Back. Cache에 저장하고 주기적으로 모아서 DB에 배치 업데이트
    • 일관성보완: 캐시만료timeout, 쓰기시 캐시무효화
    • 가용성보완: 캐시복제

  •  
    • Redis의 한계: 싱글스레드. 
      • keys대신 scan사용
  • 비동기 처리
    • 대기열 시스템을 통한 고객 경험 개선
  •  코드최적화
    • 지연로딩(이미지등), 디바운싱(마지막 요청만 처리)
  • 전송방식 변경
    • gRPC
  • 외부 디펜던시가 있다면
    • 스로틀링(rate limit포함, 요청수 제한), 서킷브레이크(close, open, half-open)
      • 푸시/풀(전자는 리소스헤비)
      • failover=fallback(다른 결제 시스템)
    • 분리된 Queue에 요청을 저장하고, 백그라운드로 처리. 시스템 복구시 순차적 처리
    • 회로차단기로 막혔을때의 요청을 DLQ(Dead Letter Queue)에 넣고 모니터링 후 원래큐로 돌리거나 후처리.

Q. 장애대층

  • 네트워크 실패 문제
    • 다중 AZ, 서킷브레이크(외부 서비스면)
  • 단일 실패지점
    • 데이터 복제, 로드밸런싱, 자동장애복구(클라우드), 장애격리(MSA)
    • 다중 AZ

Q. 무중단 DB마이그레이션(RDB > NoSQL기준)

  • 데이터 동기화
    • 이미 존재하는 RDB데이터를 NoSQL로 복사(배치, ETL)
  • 더블 Writing (RDB, NoSQL)
  • 읽기연산을 NoSQL로 전환
  • 쓰기연산 전환, RDB중단(feature flag사용)
  • 경우에 따라 일부 사용자 또는 서비스만 전환(카나리테스트)
  • 중간중간에 일관성확인/모니터링/롤백계획도 수립하면서 해야함

Q. Monolithic에서 MSA로 전환

  • 도메인 분석을 통해 몇개 서비스로 나눌지 결정
  • 비즈니스영향력이 작고 기술적으로 단순한 도메인 부터 이전
  • DB분리 > 서비스간 API설계 > 통계는 별도 ETL구축
  • 단점: API는 DB Join보다 비싸고 느림. 대안: 모듈식(펑션콜/공유메모리/로컬큐)

Q. 도메인주도설계(DDD)

  • DB스키마 부터 설계하고 CRUD > 비즈니스로직 구현 순서가 아님
  • 비즈니스부터 고민. 바운디드 컨텍스트(용어 정의)
  • 애그리게이트(대출계좌, 대출자, 대출상품을 묶어 대출로 애그리게이트)
  • 이벤트(대출신청, 승인, 상환)
  • 서비스(복잡한 비즈니스로직 예를들어 대출 신용평가)

Q. NoSQL vs 스팍/하둡 vs Kafka

  • NoSQL: 실시간성
  • 스팍/하둡: 배치(하둡은 디스크액세스때문에 느리고, 스팍은 실시간성이 있으나 데이터 저장/관리 기능없음)
  • Kafka: 배치보다는 실시간성에 강점. 하지만 메시지가 저장되므로 배치에도 사용가능.

 

 

 

 

 

 

 

 

 

 

반응형

'System Architect' 카테고리의 다른 글

Application  (0) 2023.10.28
graphQL  (0) 2023.10.12
gRPC  (0) 2023.10.11
데이터 분석 관련 정리  (0) 2023.08.19
시스템설계 Q&A  (0) 2023.08.08

 인과관계 추론

  • RCT(Randomized Controlled Trial). 즉 A/B테스트는 랜덤하게 나누는게 중요하며 인과관계를 과학적으로 보여준다(나머지기업은 인과관계추론이 완전하게 안됨) 좋지만 인공실험이 필요.
  • RD(Regression Discontinuity): 회귀불연속설계법. 경계선에 집중

  • 집군분석(Cluster Analysis):

  • 패널데이터분석: 평행 트렌드 가정이 성립해야함.

  •  
반응형

'System Architect' 카테고리의 다른 글

Application  (0) 2023.10.28
graphQL  (0) 2023.10.12
gRPC  (0) 2023.10.11
시스템설계 Q&A 2  (0) 2023.09.20
시스템설계 Q&A  (0) 2023.08.08

Q. 설계디자인 문제의 경우 초기에 질문할것들은?

  • 요구사항을 확인하는게 먼저
    • 기능적요구사항 명확히,
      • 개발범위에 대해 반드시 물어볼 것
    • 성능등 비기능정요구사항 명확히
      • 성능요구사항에 따라, NoSQL도입/fanout복사/캐시/비정규화(CQRS등의 읽기쓰기분리)등을 고려가능
      • 단일실패지점(SPOF)을 failover등으로 대응
      • 스로틀링 이야기가 나오면 트래픽패턴에 대해 반드시 물어볼것
        • 시간대/시즌별 트래픽, 요청유형(특정API에 몰리는가), 특정지역에 몰리는가
        • 고객경험도 반드시 이야기할것(비동기시 UX변경)
      • SLA(Service Level Agreement): 고객에게 제공할 서비스 품질 명시(성능,범위,보상,유지보수등)
  • 제약사항도 확인
    • 네트워크 밴드위스, 시스템사양, 사용자수, 데이터처리량, 외부시스템 디펜던시, 기타리스크요소 등

Q. 서버과부하 처리법

  • 먼저 모니터링을 하여 서버이슈인지 API이슈인지 응답시간확인, 트래픽 패턴 파악
    • 일반적으로
      • 로드벨런서(Nginx등)를 사용하여 트래픽을 분산 
      • 스케일업, 스케일아웃검토.
        • 스케일아웃은 spkie대처가 느리므로 캐싱, 로드밸런싱, 스로틀링, 비동기, 오토스케일링등 추가 고려
        • 또한 스케일 아웃은 downstream에 더 많은 압박을 줄 수 있다.
      • 정적 리소스인경우 CDN(콘텐츠 전송 네트워크) 사용
      • HTTP/2 사용: 압축, 단일연결 멀티플펙싱 등
      • DB이슈는 다음질문으로..
    • 웹서버
      • 리버스 프록시: 정적 컨텐츠를 캐싱하고, 들어오는 요청을 적절한 WEB 서버로 라우팅
      • CDN(Content Delivery Network) 사용
      • 커넥션 풀링: 웹 서버와 WAS 사이의 커넥션을 효율적으로 관리하여 리소스 사용을 최적화
    • WAS
      • 로드 밸런싱: 여러 WAS 인스턴스를 배포하고 로드 밸런서를 사용하여 들어오는 요청을 여러 서버에 고르게 분배합니다.
      • 자동 확장: 트래픽이 증가할 때 자동으로 WAS 인스턴스를 추가하고, 트래픽이 감소하면 인스턴스를 줄이는 기능을 활용할 수 있습니다.
      • 세션 클러스터링: 사용자 세션 정보를 여러 서버 간에 공유하므로, 한 서버가 실패하더라도 세션은 유지됩니다.
    • API이슈이면
      • 코드최적화
      • API호출 최적화
        • spike문제라면 지연로딩(이미지등), 디바운싱(마지막요청만처리), 배치처리(묶음API를 한번에 처리),
        • 웹소켓(반복연결부담줄임..근데 이건 spkie상황에서는 조심해야할듯),
        • 네트워크부하가 문제라면 GraphQL(이것도 서버부하를 증가시킬수 있어서 트레이드오프 조심)
        • gRPC도 고려
      • 캐시 적용(Redis등)
        • 단, 플래시딜등 정확한 재고 트랜잭션 관리가 필요할때는 사용이 제한적
          • 해결책으로 Redis에서는 분산lock제공, 비동기큐 순차처리로 해결가능, 
          • 큐잉의 경우 UX변경 필요. 대기열 안내등
      • 전송방식 변경(gRPC, GraphQL등)
      • 비동기처리 검토(대기열 시스템을 통한 고객 경험개선)
        • 고객UX 새로 디자인
        • 일관성을 위해 결제상태추적/재시도 필요.
        • 순서보장: kafka는 파티션 단위로만 순서를 보장하므로 주의해서 설계
          • 중요한작업은 동일한 파티션으로 처리하도록 설계
      • 스로틀링: 요청수 제한
      • downstream API의 경우(API1 > 2 > 3 의존성 체인)
        • API1을 스케일아웃해도 2,3때문에 병목 유지될수 있음.
        • 서킷브레이크
        • 백 프레셔: 프로듀서-컨슈머간 흐름조절(소비속도가 느리면 생산속도 조절. 아예 멈추기도 함)
        • failover = fallback (문제가 발생했을때 대체 시스템으로 넘어가는 것)
        • failback (failover상황에서 원래 대로 복귀하는 것)
    • DB이슈이면?
      • 다음 질문으로..

Q. DB과부하

  • 쿼리최적화/인덱싱
  •  캐싱
    • 보통 SQL 캐시는 RDBMS에서 자제적으로 수행
    • 캐시 테이블 개념으로 별도 테이블을 만들기도 하며, 머터리얼뷰라고 해서 뷰인데 디스크에 저장하는 형태도 있음
    • Redis등 DB외부에 캐시를 두면 효율이 좋은대신 Key-Value행태로 어떻게 저장할지 추가 고민/구현 필요
  • 데이터베이스 분할
    • Master/Slave구분하여 Master는 Insert, Slave는 Read
      • 순간적인 불일치: Master Insert직후는 Master에서 Read
      • 문제적인 불일치: 마스터 DB의 트랜잭션 로그를 사용하여 슬레이브 DB를 동기화(근데 DBMS가 자동으로 해주는 부분)
      • 정말 문제적인 상황: 예를들어 관리자가 실수로 slave에 insert했다. 그럼 Slave를 Master로 강제동기 초기화.
    • 샤딩
  • NoSQL도입
    • RDB로 커버안되거나 특히 쓰기 작업이 많을때
    • 주문서등 비정형 데이터를 저장해야할때

Q. DB마이그레이션(RDB->NoSQL기준)

  • 데이터 복제: 기존 RDBMS의 데이터를 새로운 NoSQL 데이터베이스로 복제합니다.
  • 동시 업데이트: 변경 과정에서 발생하는 새로운 데이터도 두 데이터베이스 모두에 업데이트합니다.
  • 읽기/쓰기 전환: 복제가 완료되면, 읽기 요청은 먼저 NoSQL로 전환하고, 쓰기 요청은 RDBMS에서 계속 처리합니다.
  • 최종 전환: 모든 테스트와 검증이 완료되면, 쓰기 요청도 NoSQL로 전환하고, RDBMS를 완전히 중단합니다.

Q. 외부 디펜던시(예)payment) 문제해결타임아웃 설정

  • 타임아웃을 설정: 하여, 응답이 지연되는 경우 사용자에게 적절한 응답을 제공하고 시스템 자원을 효율적으로 관리합니다.
  • 장애 처리 메커니즘: payment 시스템과의 통신 중 장애가 발생하면, 사용자에게 명확한 오류 메시지를 제공하고, 필요한 경우 주문을 재시도하거나 나중에 처리할 수 있도록 지원합니다.
  • 분리된 큐 사용: 결제 요청을 분리된 큐에 저장하고, 백그라운드 작업으로 처리합니다. 결제 시스템이 복구되면 큐에 있는 요청을 순차적으로 처리합니다.
  • 회로 차단기 패턴: 외부 서비스의 연속된 실패가 발생하면 일시적으로 해당 서비스 호출을 차단하고, 일정 시간 후에 다시 시도합니다. 이를 통해 시스템 자원을 보호하고, 외부 서비스가 복구될 기회를 제공합니다.
  • 복제 및 재시도 전략: 여러 payment 시스템 제공자와 통합하여, 한 시스템이 실패하면 다른 시스템으로 자동 전환(fail over)
  • 모니터링 및 알림, 문서화 및 사용자 안내

Q. 네트워크 실패 문제 대응

  • 다중 AZ, 서비스별 네트워크 분리/격리, 백업 네트워크
  • 외부서비스면 서킷브레이크

Q. 데이터포인트와 메트릭, 로드테스트

  • 스케일아웃 같은 의사결정을 할때는 관련 측정자료인(1회성도 괜찮음) 데이터포인트들이 필요하다.
    • 예를들어, 응답시간, 에러율(500에러), CPU/메모리/IO 사용률, 대기중인요청 등이다(스레드 개수로 대변될수도)
  • 메트릭은 의사결정후 데이터포인트들을 여러번 반복측정해서 개선된걸 보는거라 둘은 밀접하게 연결돼있다.(데이터포인트는 메트릭의 구성요소)
  • 로드테스트는 길거리 필드테스트가 아니라 부하테스트를 의미하며, 위의 메트릭에 대한 성능평가를 의미하는데, 실제 환경과 비슷한 테스트 환경 구축이 필요한만큼 비용이 들며 항상가능하지는 않다.

Q. Redis등 분산캐시 이용시 고려사항

  • 효율화: 병목데이터 분석하여 어떤부분을 캐시할지 결정..  hot spot.
  • 일관성이 중요하면: 서버간 캐시 불일치가 생길수 있다. 이를 해결하기 위해
    • 캐시 만료: timeout 시간설정(TTL)
    • 캐시 무효화: 쓰기작업등 캐시변경 발생시 전 서버 캐시 무효화(강한 일관성)
    • 캐시 파티셔닝: 캐시를 해시해서 노드별 분산하는 것(각 노드는 독립적 캐시관리 가능) 
  • 가용성, 내구성, 성능향상이 더 중요하면: 캐시 복제(같은 캐시를 여러서버에 복제)
    • 경우에 따라 불일치 어느정도 허용
    • 노드간 비동기 메시징을 통한 최종적 일관성(강한 일관성보다 성능이 좋으나, 일시적 불일치 감수/처리 필요)
  • 경우에 따라 로컬캐시/글로벌캐시를 분리하면 성능향상.
    • 로컬캐시예시: 스티키세션
  • Disk쓰기 옵션을 제공하지만 풀방식이므로 휘발성고려해야한다.
    • AOF(Append Only File) 로깅으로 보완 (저널링)
    • 위의 복제로 보완
    • 중요데이터는 DB로 복제하므로써 보완

Q. AWS옵션

  • 하둡: S3
  • 카산드라: dynamoDB
  • Redis: Amazon ElastiCache for Redis, DAX(DynamoDB Accelerator)
  • Kafka: Kinesis

Q. ACID

  • 원자성(Atomicity): 트랜잭션 all or nothing
  • 일관성(Consistency): 트랜잭션 이전과 이후에도 데이터베이스의 모든 무결성 제약 조건이 만족되어야 합니다.
  • 독립성(Isolation): 한 트랜잭션의 중간 결과는 다른 트랜잭션에게 보이지 않아야 합니다.
  • 지속성(Durability): 트랜잭션이 성공적으로 완료되면, 그 결과는 영구적으로 반영되어야 함을 의미

Q. 분산트랜잭션

  • 2단계 커밋
    • 2대이상의 노드(컴퓨터)에서 트랜잭션을 처리하기 위한 방법
    • 준비단계: 이 단계에서는 트랜잭션을 시작한 노드(코디네이터)가 모든 참여 노드에게 트랜잭션을 커밋할 준비가 되었는지 물음. 각 참여 노드는 이 요청을 받고, 자신의 상태를 확인한 후 준비가 되었다면 '예'를, 그렇지 않다면 '아니오'를 코디네이터에게 보냄.
    • 커밋단계: 코디네이터는 모든 참여 노드로부터 응답을 받은 후, 모든 노드가 '예'라고 응답했다면 트랜잭션을 커밋하라는 메시지를 보냄. 만약 하나라도 '아니오'라고 응답한 노드가 있다면, 트랜잭션을 롤백하라는 메시지를 보냄
    • 단점: 하나의 노드라도 실패하거나 응답이 늦어지면 전체 트랜잭션이 블록되는 블록킹 문제가 있다.
  • 3단계 커밋
    • 프리커밋단계를 추가하여, 2단계 커밋의 블록킹 문제점을 타임아웃을 통해 극복
    • 준비 단계: 2단계 커밋의 준비단계와 동일
    • 프리-커밋 단계: 각 노드에게 프리-커밋 메시지를 보내 블록킹 상황에서의 행동을 알려줌(프리커밋을 받은 노드는 타임아웃시 커밋을 수행하고 받지 않은 노드는 커밋을 수행하지 않음)
    • 커밋단계: 각 노드는 프리-커밋단계에서는 확인만 하고 기다리다가 커밋메시지를 받으면 실제 커밋 시작

Q. 이벤트 소싱

  • 파일시스템,DB에서 쓰이는 저널링의 비즈니스 로직 버전. 
  • 이벤트, 이벤트 저장소, 상태재구성 등의 구성요소가 있으며, 분산환경에서는 주로 타임스탬프로 순서를 관리한다.
  • 사용처: 상태변화를 추적하므로 디버깅에 도움이됨. 시간여행가능. 분산환경에서 일관성문제 발생시 해결실마리 제공.

Q. 인증세션관리

  • 전통적인세션: 서버에서 ID를 발급하고 메모리에 들고 있고, 클라이언트에 전송해서 쿠키로 소통하는 방식
  • JWT: 상태없이 인증정보가 토큰에 저장되어 MSA등 분산환경에 유리. 서버의개인키로 서명되며 싱글사이온에도 적용가능
  • Redis: 분산서버간 세션저장소로 활용될 수 있으며, JWT와 결합하여 캐시형태로 속도향상가능.

Q. 12-Factor 앱이란

  • 12-factor 앱은 소프트웨어 개발자들이 현대적인 웹 애플리케이션을 만들고 배포하는 데 도움이 되는 원칙과 방법론을 제시하는 개념. 이 개념은 Heroku의 개발자인 Adam Wiggins에 의해 처음 제안되었으며, 클라우드, 마이크로서비스, 컨테이너, 지속적인 배포 등과 같은 현대적인 개발 패러다임을 지원
  1. 코드베이스: 애플리케이션은 하나의 코드베이스를 가지며, 다양한 배포 환경에서 실행될 수 있어야 한다.
  2. 의존성: 애플리케이션은 명시적으로 모든 의존성을 선언하고, 시스템에 사전 설치된 패키지에 의존해서는 안 된다.
  3. 설정: 설정 정보는 코드에서 분리되어야 하며, 환경 변수를 통해 관리되어야 한다.
  4. 백엔드 서비스: 백엔드 서비스는 서로 긴밀하게 연결되어야 한다.
  5. 빌드, 릴리즈, 실행: 빌드와 실행 단계는 엄격하게 분리되어야 한다.
  6. 프로세스: 앱 서비스들은 무상태 프로세스로 실행되어야 한다.(JWT등) 앱의 상태는 외부서비스(DB,캐시,세션저장소)에 저장한다.
  7. 포트 바인딩: 서비스는 포트 바인딩을 통해 노출되어야 한다(MSA)
  8. 동시성: 확장성을 위해 프로세스 모델을 사용해야 한다.(MSA)
  9. 처리 유연성: 빠른 시작과 정상적인 종료를 통해 견고성을 보장해야 한다.(당연한소리)
  10. 개발/프로덕션 환경 일치: 개발, 스테이징, 프로덕션 환경은 가능한 한 유사하게 유지해야 한다(당연한 소리)
  11. 로그: 로그는 이벤트 스트림으로 취급되어야 한다.(모니터링, 분석등을 위해 필요. 분산환경에서 합치기도 용이)
  12. 관리 프로세스: 관리 작업을 일회성 프로세스로 실행해야 한다.(앱실행과 마이그레이션등을 분리하라는 것)

Q. 스케일아웃의 단점

  • 스케일 아웃이 성능향상에 도움이 되나, 세션등 서버간 공유되는 자료가 많으면 상태공유문제 발생
  • 보통은 가급적 stateless로 설계하고, 외부저장소(캐시,DB등)를 참조하도록 해서 해결

Q. Monolithic에서 MSA로 전환하는 순서

  • 단계적 이전을 원칙으로 함
  • 도메인분석을 통해 몇개 서비스로 나눌지 결정
    • 비즈니스 중요도, 기술적 복잡도, 팀의 능력을고려. 일반적으로는 비즈니스 영향이 작고 기술적으로 단순한 도메인부터 이전
  • 데이터를 가급적 분리(DB조인도 분리) > 서비스간 API설계 > 통계는 따로 ETL구축 검토
  • 클라이언트와 서비스간 통신을 담당하는 API게이트웨이 도입 검토
  • CI/CD구축
  • 리스크관리
    • circuitBreaker 등

 

Q. MSA구조의 단점

  • 모놀리식에서 쉽게 조인연산으로 되던것이 DB분리로 인해 서비스간 API로 치환되어야 한다.
  • 초기 스타트업에서는 하나의 애플리케이션안에 모듈식 디자인을 적용하는게 나을 수 있다.
    • 모듈은 독립적으로 작동하나 MSA처럼 프로세스/노드분리까지는 하지 않을 수 있다.
    • 따라서 펑션콜이나, 공유메모리, 로컬큐등을 활용 가능

Q. 도메인 주도 설계(Domain-Driven Design, DDD)

  • DDD가 아닌것: DB 스키마 부터 설계. 그걸로 CRUD코드 작성. 비즈니스로직은 코드사이에 흩어짐
  • DDD인것: 도메인 비즈니스부터 고민. 비즈니스로직 분리. 예를들어 뱅킹에서 계좌와 거래라는 도메인이 있을때 이체, 입출금을 비즈니스로직으로 잡을 수 있다. 
  • 비즈니스로직이 간단한 경우 xxxService.java로 비즈니스로직을 분리하는 것으로도 충분하지만,
  • DDD는 좀 더 복잡한 비즈니스를 모델링하기 위한 것으로 그 요소는 다음과 같다.
    1. 바운디드 컨텍스트(Bounded Context): 특정 비즈니스 도메인을 구현하는데 필요한 모델과 규칙을 정의하는 경계. 예를 들어, 은행 시스템에서는 '대출', '예금', '이체' 등이 각각의 바운디드 컨텍스트가 될 수 있다. 즉 도메인에 속하는 용어(규칙,모델포함)들을 정의하는 단계라고 보면 된다.
    2. 애그리게이트(Aggregate): 도메인 모델 내에서 일관성을 유지해야 하는 객체의 집합을 의미. 예를 들어, '대출' 도메인에서는 '대출 계좌', '대출자', '대출 상품' 등이 하나의 애그리게이트를 구성. 도메인 요소간 관계를 규정(묶을 수 있는건 묶는다)
    3. 도메인 이벤트(Domain Event): 비즈니스 로직에서 중요한 변화를 나타내는 이벤트. 예를 들어, '대출' 도메인에서는 '대출 신청', '대출 승인', '대출 상환' 등이 도메인 이벤트가 될 수 있다.
    4. 도메인 서비스(Domain Service): 도메인 서비스는 애그리게이트나 값 객체로 표현하기 어려운 도메인 로직을 수행하는 서비스를 의미. 예를 들어, '대출 신용 평가'는 대출 신청자의 신용 정보를 바탕으로 대출 가능 여부를 판단하는 도메인 서비스가 될 수 있다. 외부로 노출되는 서비스를 의미

Q. ETL프로세스

  • DDD로 하다보면 도메인 서비스별로 DB분리가 일어나는데, 통계/분석은 전체DB를 통합적으로 봐야한다.
  • 이때 ETL프로세스가 따로 배치로 돌면서 각 도메인별 DB에서 정보를 추출해서 변환후 DW에 로딩하게 된다. 
    • DW는 RDB가 될수도 있고(복잡한 쿼리가 필요한 경우), NoSQL이나 하둡/스팍이 될수도 있다. (대용량 처리속도가 우선인 경우)
    • ETL은 보통 Airflow등으로 수행되는 배치작업이지만, 실시간 처리가 필요한경우 Kafka/Flink/스팍Stream등을 붙여준다.

Q.Q. NoSQL vs 스팍/하둡

  • 둘다 대용량 데이터를 스케일아웃 전략으로 처리하도록 만들어졌지만 NoSQL은 실시간성, 스팍/하둡은 배치처리에 초점이 있음.
    • 하둡은 디스크액세스 때문에 실시간이 힘들고, 스팍은 실시간성과 자체 분산처리기술이 있지만 데이터 저장/관리 기능은 없음.
    • 그래서 스팍 단독으로도 NoSQL이 아님
  • 참고로 Redis도 NoSQL의 한 종류임.

Q. NoSQL vs RDB 정규화수준 낮추기

  • 공통점: 조인연산을 줄이고, 성능향상, 중복데이터허용
  • 차이점
    • RDB정규화수준 낮추기: 스키마변경의 제약
    • NoSQL도입: 스키마 유연(문서,키-밸류등), 수평확장용이, 

Q. 몽고DB vs 카산드라

  • 둘다 수평확장에 능한 NoSQL이다.
  • Document기반의 json 처리가 필요하면 몽고DB
  • 컬럼기반의 SQL비슷한 쿼리지원을 원하면 카산드라

Q. 장애복구 관련

  • 단일실패지점 대응
    • 데이터복제, 로드밸런싱, 자동장애복구, 장애격리(MSA)
    • Availability Zone을 분리

Q. Rate Limiting vs Throttling(스로틀링)

  • 전자는 제한 초과하면 거부. 후자는 큐잉되거나 지연해서 최종적으로는 처리됨.
  • 사실 전자는 후자의 한 형태
  • 실제 적용시는 다음을 고려해야함
    • 트래픽패턴(글로벌/로컬), 시간당/유저당, 로컬/중앙 카운팅(빠른응답, 확장성/고급기능 트레이드오프), 
    • 푸시/풀(즉시/폴링 전자는 리소스헤비), 우선순위큐사용(Redis로 가능)
    • 고객경험에 부정적이므로 가급적 줄이는게 좋음

Q. 검색시스템 구현방법

  • 토큰화 > 정규화 > 색인생성(inverted index) > 색인으로 문서매칭 > 문서간 순위에 TD-IDF사용
  • Elastic Search도 이방법을 사용하며, 분산처리를 지원.

Q. TF-IDF

  • 단어 카운팅을 통해 bag of word벡터를 먼저 문서별로 구한다.
  • 문서간 유사도는 보통 코사인유사도로 구하는데 A,B문서의 코사인유사도는 AB의 내적을 |A|*|B|로 나눠줌. 원리?
  • 단어 카운팅 대신에 bag of word에서 자주 등장하는 단어일수록 (분모가 증가하여) 숫자를낮춰 중요도를 낮추는 기법

Q. Kafka

  • 배치보다는 실시간 처리에 강점을 가짐(높은 처리량, 낮은 지연시간) 하지만 메시지가 저장되므로 배치에도 사용가능
  • 더빠른 지연시간을 원하면 RabitMQ, Redis사용가능 (디스크 연속저장 스킵가능)

Q. 비용최적화

  • 필요한 대역폭과 저장공간등을 측정하여 가장 알맞는 클라우드/온프레미스 비용 산정
  • 자동스케일링을 설정하여 안쓸때는 비용절감(온프레미스에서는 제한적이나 쿠버네티스로 어느정도 가능)
  • 저장할때 압축해서 저장

Q. 노드간 동기화 이슈(재고 동기화를 생각해보자)

  • 소스가 있어야 한다 (예를 들어 중앙서버)
  • 소스에서 타겟으로 동기화 방법
    • Sync 방식: 최종재고체크 단계면 고려해볼 수 있다.
    • ASync방식: 지연시간 최소화. 카프카 사용. 지속성에도 장점(디스크에 저장하므로)
  • 전달확인방법(일관성)
    • 2단계커밋
    • 비동기 Ack (preface 주문 ack생각하면됨)
  • 반복실행가능성이 크므로 멱등성이 중요.
    • 고유키(트랜잭션ID)를 사용
    • DB도 멱등하도록 설계. 예를 들어 재고수량을 update하도록 하지말고 트랜잭션ID에 변화수량만 기록.
      • 실제수량은 트랜잭션ID를 고려하며 수행

Q. CQRS 패턴

  • 명령과 조회를 분리(도메인 분리)
  • 명령(insert/update)시 조회쪽 데이터 생성/변경작업해줌
    • 이때 부담을 줄이는게 이벤트소싱
    • 변경사항생겼을때 이벤트 거쳐서 다른 서비스에서 조회모델 저장
  • 조회쪽은 속도를 위해 NoSQL을 쓰는 경우도 많음
  • 명령은 덜자주, 조회는 자주일어나는 모델에서 유용
  • 단점: 데이터 정합성/일관성

Q. 3-tier architecture

  • Presentation Layer, Business Logic Layer, Data Access Layer 이며,
    • 각각 프론트엔드/백엔드WAS/DB정도에 대응된다고 보면 된다.

Q. Hot spot(row) 이슈

  • 해당 부분을 캐시(redis)로 분리

Q. 재고 관리

  • 소스정의: 재고 데이터의 원본은 중앙 재고 관리 시스템이 될 것이며, 이 시스템은 모든 판매 채널과 동기화
  • 일관성이 중요한 경우:
    • 2단계 커밋으로 분산트랜잭션 사용
    • 멱등성 지원 가능하도록 설계
  • 지연시간이 중요한 경우
    • 캐싱, 로드밸런싱
    • 비동기 전송을 사용하여 시스템 간 지연을 최소화
    • Kafka나 RabbitMQ와 같은 메시지 브로커를 사용하여 소스에서 대상으로 수량 데이터를 비동기로 전파
  • 확인 방법: 2단계 커밋과 비동기 Ack 모델을 사용하여 메시지 전달을 보장(2단계 커밋은 맥락이 다르지 않나)
  • 주기적 동기화 검증: 주기적 비교와 실시간 지연 큐를 사용하여 동기화를 검증합니다.
  • 고성능이 필요하면: 캐시적용
  • 영화관 자리예약에는 옵티미스틱 락킹이 많이 쓰인다. (락없이 예약, 결제시 확정)
  • 잘팔리는 스큐는 레디스에 넣어서 가속
  • 마이크로 서비스 분리
    • 주문 서비스: 주문 생성, 주문 상태 관리
    • 결제 서비스: 결제 처리
    • 재고 서비스: 재고 확인, 재고 차감
  • 기능적요구사항
    • 재고 조회, 차감 및 추가, 예약 및 해제, 경고, 이력 관리, 다중 창고 지원
  • 비기능적요구사항
    • 성능, 확장성, 안정성, 보안, 통합성(주문관리, 창고관리, 외부), 사용자 경험, 쉬운인터페이스

Q. 체크아웃 기능 구현하기

  • 장바구니 관리 모듈: 사용자의 선택한 상품을 관리하고, 수량 변경, 쿠폰 적용 등의 기능을 제공합니다.
  • 배송 정보 관리 모듈: 배송 주소, 배송 방법, 배송 시간 등을 관리하고 사용자에게 적절한 옵션을 제공합니다.
  • 결제 처리 모듈: 다양한 결제 방법(신용 카드, 데빗 카드, PayPal 등)을 지원하고, 결제 승인 및 처리를 담당합니다.
  • 주문 검증 모듈: 주문의 유효성을 검사하고, 재고 확인, 가격 검증 등을 수행합니다.
  • 할인 및 프로모션 모듈: 쿠폰, 할인 코드, 회원 할인 등의 프로모션을 관리하고 적용합니다.
  • 알림 및 통신 모듈: 주문 상태 변경, 배송 추적 등의 알림을 사용자에게 전송합니다.
  • 보안 및 인증 모듈: 사용자 인증, 결제 보안 등을 담당하여 전체 프로세스의 보안을 유지합니다.
  • 모니터링 및 로깅 모듈: 시스템의 성능과 에러를 모니터링하고 로깅하여, 문제 발생 시 신속한 대응이 가능하도록 합니다.

 

Q. 모니터링 시스템 설계

  • 수집할 정보 정의: 어떤 정보를 수집할 것인지. CPU 사용률, 메모리 사용량, 디스크 I/O, 네트워크 트래픽 등
  • 성능 고려: 클라이언트가 시스템에 부담을 주지 않도록, 성능에 민감한 부분은 특히 주의
  • 확장성 있는 설계: 시스템이 변화하고 성장함에 따라 새로운 정보를 수집해야 할 수도 있으므로
  • 데이터 수집 주기: 얼마나 자주 데이터를 수집할 것인지 결정/조정기능 추가
  • 데이터 전송 방식: 수집한 데이터를 중앙 서버나 데이터베이스에 어떻게 전송할 것인지. REST API, Kafka, gRPC등
  • 에러 핸들링/보안/테스트 및 검증/문서화: 알림, 와치독

 

Q. 질문시간에 질문한 것들

  • 다가오는 5년 내에 시장에서 차지하고자 하는 위치는 어떻게 되나요?
  • 제가 지원한 포지션에서의 주요 업무와 책임은 무엇인가요?
  •  
  • FTS(IPFO) 시스템의 현재 아키텍처는 어떠한 형태를 가지고 있나요?
  • 현재 애자일 적용 현황이 궁금합니다.
  • 현재 팀의 비즈니스 전략과 목표는 어떻게 되나요?
  • XX의 기술 스택은 어떻게 구성되어 있으며, 이 포지션에서는 어떤 기술이 주로 사용되나요?

 

Q. 병목분석 & 처리 

  1. 예상되는 병목지점 파악
    • 데이터베이스 쿼리 지연: 복잡한 쿼리나 인덱싱이 제대로 이루어지지 않은 경우
    • 웹 서버나 WAS 서버의 부하: 동시 요청 수가 많을 경우
    • 네트워크 지연: 서버 간의 통신이 빈번하거나 대용량 데이터 전송이 필요한 경우
    • 디스크 I/O 병목: 디스크 읽기/쓰기가 빈번한 작업에서 I/O 지연이 발생할 수 있습니다.
  2.  원인 분석
    • 성능 모니터링 도구 활용: 시스템의 CPU, 메모리, 디스크 I/O, 네트워크 사용률 등을 모니터링하여 병목 지점을 찾습니다.
    • 쿼리 분석: 실행 계획을 분석하거나 프로파일러를 사용하여 쿼리 성능을 검토합니다.
    • 로드 테스트: 예상 트래픽을 모방하여 병목 지점을 확인합니다.
    • 로깅 및 추적: 로그와 추적 데이터를 분석하여 성능 저하가 발생하는 지점을 확인합니다.
  3. 해결 방안
    • 캐싱 적용: 자주 접근하는 데이터를 캐시하여 DB 부하를 줄입니다.
    • 로드 밸런싱: 요청을 여러 서버에 분산시켜 부하를 줄입니다.
    • 쿼리 최적화: 쿼리 실행 계획을 분석하고, 필요한 인덱스를 추가하거나 쿼리를 개선합니다.
      • (db부하는 그밖에도 많다. Master/Slave분리, 파티셔닝, 복제, 커넥션풀 등)
    • 하드웨어 업그레이드: 필요한 경우, CPU, 메모리, 디스크 등의 하드웨어를 업그레이드합니다.
반응형

'System Architect' 카테고리의 다른 글

Application  (0) 2023.10.28
graphQL  (0) 2023.10.12
gRPC  (0) 2023.10.11
시스템설계 Q&A 2  (0) 2023.09.20
데이터 분석 관련 정리  (0) 2023.08.19

+ Recent posts