728x90
반응형
- Data outlives code (데이터는 코드보다 오래 산다)
최근 서비스는 무중단배포(ex_ 블루그린배포) - staged rollout 방식과 마이크로서비스와 같은 구조적 차이를 띈다.
그만큼 서비스 내부 코드는 더욱 자주 바뀐다.
# 호환성
- 상위 호환성 : 이전 코드는 새로운 버전의 데이터를 읽을 수 있어야한다.
- 하위 호환성 : 새로운 코드는 예전 버전의 데이터를 읽을 수 있어야한다.
# 직렬화(부호화), 역직렬화(복호화)
- 직렬화(부호화, 마샬링) : 데이터를 인메모리 표현 -> 바이트열 변환
- 역직렬화(복호화, 언마샬링) : 데이터를 바이트열 -> 인메모리 표현으로 변환
데이터 부호화 4가지 방식
- 언어별 내장 라이브러리
- JSON, XML, CSV
- binary Encoding
- Libaray based schema
- 특정 언어에 내장된 라이브러리를 통해 직렬화했을 경우, 다른 언어로 구성된 컴포넌트 혹은 다른 시스템에서 역직렬화를 하기 위한 제약이 발생한다. (ex_ java.io.Serializable - Performance도 좋지 않다.)
표준 직렬화 방식 : JSON / XML / CSV
- 일반적으로 가장 간단한 JSON 형식이 주로 이용되며, 텍스트 형식으로 가독성이 좋다.
- 일부 문제점 :
- 정수와 부동소수점 수를 구별하지 않음
- 이진 문자열을 지원하지 않음
- 데이터의 크기가 증가함
- csv는 로우 및 칼럼 정의를 어플리케이션 레벨에서 해야함
Binary Encoding
- 방대한 양의 데이터 단위일 경우 데이터 타입의 영향력은 커진다.
- 데이터 사용 공간 : Binary Encoding < JSON, XML
종류 : MessagePack / Apache Thrift(아파치 스리프트 - 바이너리프토로콜 , 컴팩트프로토콜) / 프로토콜 버퍼
XML / JSON / Proto 방식 비교
스키마는 발전한다.
- 필드에 태그 번호를 부여하는 방식으로 스키마에 새로운 필드 추가 가능
- 해당 필드를 무시함으로써 상위 호환성 유지
- 각 필드에 고유 태그 번호를 통해 새로운 코드가 예전 데이터를 계속 읽을 수 있음
- 태그 번호는 계속 같은 의미를 지니므로 하위 호환성 유지
- 추가되는 모든 필드는 optional or default value
Avro (아브로)
스리프트가 하둡에 알맞지 않아 하둡의 하위 프로젝트로 시작
- 태그 번호 X
- 부호화가 단순하다 (정수는 가변 길이 부호화를 사용해서 부호화 == 스리프트 컴팩트프로토콜)
- 이진 데이터 파싱시, 데이터를 읽는 코드가 데이터를 기록한 코드와 정확히 같은 스키마를 사용해야한다.
스키마 발전 규칙
- 호환성 유지를 위해 default 값이 있는 필드만 추가 / 삭제 가능
- if default 값이 있는 필드 추가했을 때, 예전 스키마에 없을 때에는?
- 새로운 스키마를 사용하는 읽기에서 해당 필드는 default 값으로 대체
- 기본값이 없는 필드를 추가 / 삭제
- 추가 : 새로운 읽기는 이전 버전의 기록된 데이터를 읽을 수 없다. -> 하휘 호환성 깨짐
- 삭제 : 예전 읽기는 새로운 버전의 기록된 데이터를 읽을 수 없다. -> 상위 호환성 깨짐
- 기본 값으로 필드에 null을 허용한다면 null 일 수 있고 없고를 통해 디버깅이 쉽다.
스키마의 장점
- protobuff, thrift, avro 와 같은 스키마 언어 : XML, JSON 스키마보다 간단 및 유효성 검사 규칙 지원
- 이진 부호화를 독자적으로 구현하는 시스템
- RDB에서 질의를 DB로 보내고 응답 받을 수 있는 프로토콜
- 특정 DB에 특화, 특정 DB 네트워크 프로토콜로부터 응답을 인메모리 데이터 구조로 복호화하는 드라이버 제공
- 이진 부호화 장점
- 필드이름 생략 가능 -> 크기 축소
- 스키마 자체가 유용한 문서화 형식
- 스키마 DB 유지시, 스키마 변경 전 상/하위 호환성 확인 가능
- 정적 타입 프로그래밍 언어에서 스키마로부터 코드 생성에 유용 -> 컴파일 시점 타입 체크
데이터플로 모드(Modes of Dataflow)
하나의 프로세스에서 다른 프로세스로의 데이터 전달
- By DB
- By 서비스 호출
- By 비동기적 메시지 전달
DB를 통한 데이터플로
- RDB는 대부분 NULL 을 통해 새로운 칼럼을 추가하는 간단한 스키마 변경 허용
- DB read / write 시 부호화, 복호화 이루어진다.
서비스를 통한 데이터플로
- 클라이언트 - 서버 구조
- 각각의 서버는 클라이언트로 동작할 수 있고, 이런 접근 방식은 보통 대용량 애플리케이션의 기능 영역을 소규모 서비스로 나누는 데 사용한다.
- 전통적으로는 SOA(service-oriented architecture) , 현재는 MSA(micro service architecture)
- 핵심 설계 목표는 서비스를 배포와 변경에 독립적으로 만들어 애플리케이션 변경과 유지보수를 더 쉽게 할 수 있게 만드는 것
# REST : HTTP 원칙 토대의 설계 철학
- REST는 프로토콜 X
- REST는 간단한 데이터 타입을 강조
- URL을 사용해 리소스를 식별하고 캐시 제어, 인증, 콘텐츠 유형 협상에 HTTP 메소드를 사용
- REST 원칙에 따라 설계된 API를 RESTful이라 부름
# SOAP
- 철학적 위치에서 REST 와 정반대
- 네트워크 API 요청을 위한 XML 기반 프로토콜.
- SOAP 웹 서비스의 API는 WSDL이라 부르는 XML 기반 언어를 사용하여 기술
- WSDL은 사람이 읽을 수 있게 설계하지 않았고, 복잡하므로 IDE/코드 생성 도구에 의존
- SOAP 벤더가 지원하지 않는 프로그래밍 언어의 경우 SOAP 서비스와의 통합이 어려움
- HTTP와 독립적이며, HTTP 메소드 대부분을 사용하지 않는다
메시지 전달 데이터플로
RPC(Remote Procedure Call) / DB간 비동기 메시지 시스템(asynchronous message passing system).
# RPC
- 클라이언트 요청(메시지)을 낮은 지연 시간으로 다른 프로세스에 전달.
- 메시지를 직접 네트워크 연결로 전송하지 않고 중간 단계를 거쳐 전송.
- 중간 단계: 메시지 브로커(message broker), 메시지 큐(message queue).
- 중간 단계: 메시지 지향 미들웨어(message-oriented middleware).
- 고려해야할 점
- 결과로 TimeOut 발생 가능
- 실패한 네트워크 요청 retry : 실제로는 처리되었지만 response가 유실될 수 있음
- 네트워크 요청을 통해 진행 : 함수 호출보다 느리고 latency도 다양
- 매개변수를 네트워크로 전송 : 바이트열 부호화 작업 필요
- gRPC : 하나의 요청과 하나의 응답뿐만이 아닌, 시간에 따른 일련의 요청 및 응답으로 구성된 스트림 지원
- 동작 흐름
- 각 API 아키텍쳐 스타일
REST vs gRPC
메시지 전달 데이터 플로
비동기 메시지 전달 시스템
- 클라이언트 요청(메시지)을 낮은 지연 시간으로 다른 프로세스에 전달.
- 메시지를 직접 네트워크 연결로 전송하지 않고 중간 단계를 거쳐 전송.
- 메시지 브로커(message broker)
- 메시지 큐(message queue)
- 메시지 지향 미들웨어(message-oriented middleware).
RPC 와 비교한 메시지 브로커(ex_kafka)의 장점
- 수신자가 사용 불가능하거나 과부하 상태일 때
- 메시지 브로커가 버퍼처럼 동작하여 시스템 안정성이 향상된다.
- 죽었던 프로세스에 메시지를 다시 전달할 수 있으므로, 메시지 유실을 방지할 수 있다.
- 송신자가 수신자의 IP 주소나 포트 번호를 알 필요가 없다.
- 하나의 메시지를 여러 수신자로 전송할 수 있다.
- 논리적으로 송신자는 수신자와 분리된다.
메시지 브로커
- 프로세스 하나가 메시지를 이름이 지정된 queue나 topic으로 전송
- 브로커는 소비자(consumer) 또는 구독자(subscriber)에게 메시지를 전달한다.
- 동일한 토픽에 여러 생산자와 소비자가 있을 수 있다.
- topic은 단방향 데이터플로만 제공한다.
분산 액터 프레임워크
actor model
- 단일 프로세스 안에서 동시성을 위한 프로그래밍 모델.
- 스레드를 직접 처리하는 대신 로직이 액터에 캡슐화된다.
- 각 액터는 하나의 클라이언트나 엔티티를 나타낸다.
- 액터는 로컬 상태를 가질 수 있다.
- 액터는 비동기 메시지의 송수신으로 다른 액터와 통신한다.
- 액터는 메시지 전달을 보장하지 않는다.
- 각 액터 프로세스는 한 번에 하나의 메시지만 처리한다.
- 스레드에 대해 걱정할 필요가 없음.
- 각 액터는 프레임워크와 독립적으로 실행 가능.
- 분산 액터 프레임워크 : 메시지 브로커와 액터 프로그래밍 모델을 단일 프레임워크에 통합
- ex) Akka, Orleans, erlang
728x90
반응형
'책 > 데이터중심 애플리케이션 설계' 카테고리의 다른 글
데이터중심 애플리케이션 설계 - 6장 [파티셔닝] 리뷰 - 2 (0) | 2022.10.21 |
---|---|
데이터중심 애플리케이션 설계 - 6장 [파티셔닝] 리뷰 - 1 (0) | 2022.10.20 |
데이터중심 애플리케이션 설계 - 3장 [저장소와 검색] 리뷰 - 3 : 트랜잭션 처리 / 분석 (0) | 2022.09.13 |
데이터중심 애플리케이션 설계 - 3장 [저장소와 검색] 리뷰 - 2 (0) | 2022.09.09 |
데이터중심 애플리케이션 설계 - 3장 [저장소와 검색] 리뷰 - 1 (0) | 2022.09.05 |