개요

  • 이 문서는 [[Designing-Data-Intensive-Applications]]책의 4장을 공부하며 메모한 것입니다.
  • 이 문서는 메모일 뿐이니 자세한 내용은 교재를 참고해야 합니다.

데이터 부호화 형식(Formats for Encoding Data)

언어별 형식

  • Java : java.io.Serializable
  • Ruby : Marshal
  • Python : pickle

편리하지만 문제점도 많다.

  • 다른 언어와 호환되지 않아 다른 시스템과 통합할 때 방해될 수 있음.
  • 보안 문제.
  • 상위/하위 버전 호환 문제.
  • 효율성
    • Java의 내장 직렬화는 성능이 좋지 않은 것으로 유명.

언어에 내장된 부호화를 사용하는 것은 일반적으로 좋지 않은 편.

JSON과 XML, 이진 변형

JSON, XML, CSV의 문제점들

  • number 인코딩이 애매하다.
    • number인지 숫자로 구성된 문자열인지 구분할 수 없음.
    • JSON은 숫자와 문자열을 구분할 수 있지만, 정수와 부동소수점 수를 구별하지 않고 정밀도를 지정하지 않는다.
    • 큰 수를 다룰 때 문제 발생 가능성.
      • 보다 큰 정수는 IEEE 754 배정도 부동소수점 수에서는 정확히 표현할 수 없음.
  • 이진 문자열을 지원하지 않는다.
  • XML과 JSON은 스키마를 지원하지만, 학습과 구현이 어렵다.
    • JSON 기반 도구는 스키마 사용을 강제하지 않는다.
  • CSV는 스키마가 없어, 각 로우와 컬럼의 의미를 애플리케이션에서 정의해야 한다.
  • CSV의 특정 값에 쉼표나 개행 문자가 포함되었고, 파서가 이스케이핑 문자를 모르는 경우.

스리프트와 프로토콜 버퍼(Thrift and Protocol Buffers)

이진 인코딩 라이브러리

아브로(Avro)

스키마의 장점

  • protocol buffers, Thrift, Avro는 스키마를 사용해 이진 인코딩 형식을 기술한다.
  • 이 스키마 언어는 XML/JSON 스키마보다 심플하며 더 자세한 유효성 검사 규칙을 지원한다.

이진 인코딩의 좋은 특징들

  • 인코딩된 데이터에서 필드 이름을 생략 가능하여, 사이즈가 작다.
  • 스키마는 유용한 문서 형식.
  • 스키마 DB를 유지하여, 상위/하위 호환성을 확인할 수 있다.
  • 정적 타입 프로그래머 언어 사용시에 유용.

데이터플로 모드(Modes of Dataflow)

  • 데이터플로는 매우 추상적인 개념.
  • 하나의 프로세스에서 다른 프로세스로 데이터를 전달하는 방법은 매우 많다.

다음은 가장 보편적인 (메모리를 공유하지 않는) 프로세스 간 데이터 전달 방법이다.

  • 데이터베이스를 통해서
  • 서비스 호출을 통해서
  • 비동기적 메시지 전달을 통해서

데이터베이스를 통한 데이터플로

생략

서비스를 통한 데이터플로: REST와 RPC

클라이언트와 서버

  • 서버 : 네트워크를 통해 API를 공개한다.
    • 서버가 공개한 API를 서비스라 부른다.
  • 클라이언트 : API로 요청을 만들어 서버에 연결할 수 있다.

SOA

서버 자체가 다른 서비스의 클라이언트일 수 있다 (예를 들어 일반적인 웹 앱 서버는 데이터베이스의 클라이언트로 동작한다). 이런 접근 방식은 보통 대용량 애플리케이션의 기능 영역을 소규모 서비스로 나누는 데 사용한다. 예를 들어 하나의 서비스가 다른 서비스의 일부 기능이나 데이터가 필요하다면 해당 서비스에 요청을 보낸다. 이런 애플리케이션 개발 방식을 전통적으로는 서비스 지향 설계(service-oriented architecture, SOA)라고 불렀으며 최근에는 이를 더욱 개선해 마이크로서비스 설계(microservices architecture)란 이름으로 재탄생했다.

SOA, MSA의 핵심 설계 목표

서비스 지향 및 마이크로서비스 아키텍처의 핵심 설계 목표는 서비스를 배포와 변경에 독립적으로 만들어 애플리케이션 변경과 유지보수를 더 쉽게 할 수 있게 만드는 것이다. 예를 들어 각 서비스는 한 팀이 소유해야 하고 해당 팀은 다른 팀과의 조정 없이 자주 서비스의 새로운 버전을 출시할 수 있어야 한다. 다시 말해 예전 버전과 새로운 버전의 서버와 클라이언트가 동시에 실행되기를 기대한다. 따라서 서버와 클라이언트가 사용하는 데이터 부호화는 서비스 API의 버전 간 호환이 가능해야 한다.

웹 서비스

  • 웹 서비스에는 대중적인 두 가지 방법인 REST와 SOAP가 있다.
  • 이 둘은 철학적인 측면에서 거의 정반대의 입장.

REST

  • REST는 프로토콜이 아니라 HTTP의 원칙을 토대로 한 설계 철학이다.
  • REST는 간단한 데이터 타입을 강조한다.
  • URL을 사용해 리소스를 식별하고 캐시 제어, 인증, 콘텐츠 유형 협상에 HTTP 메소드를 사용한다.
  • REST 원칙에 따라 설계된 API를 RESTful이라 부른다.
    • RESTful API는 간단한 접근 방식을 선호한다.
      • 코드 생성기와 자동화된 도구가 없어도 가능한 접근 방식을 선호.

SOAP

  • 네트워크 API 요청을 위한 XML 기반 프로토콜.
    • SOAP 웹 서비스의 API는 WSDL이라 부르는 XML 기반 언어를 사용해 기술한다.
    • WSDL은 사람이 읽을 수 있게 설계하지 않았고, 복잡하므로 IDE/코드 생성 도구에 의존한다.
    • SOAP 벤더가 지원하지 않는 프로그래밍 언어의 경우 SOAP 서비스와의 통합이 어렵다.
  • HTTP와 독립적이며, HTTP 메소드 대부분을 사용하지 않는다.
    • 대신, 다양한 기능을 추가한 여러 관련 표준 프레임워크를 제공한다.
  • 주의: 줄임말이 비슷하긴 하지만 SOAP는 SOA의 요구사항이 아니다.
    • SOAP는 특정 기술이고, SOA는 시스템을 구축하는 방법론이다.

메시지 전달 데이터플로

RPC(Remote Procedure Call)와 DB간 비동기 메시지 시스템(asynchronous message passing system).

  • 클라이언트 요청(메시지)을 낮은 지연 시간으로 다른 프로세스에 전달.
  • 메시지를 직접 네트워크 연결로 전송하지 않고 중간 단계를 거쳐 전송.
    • 중간 단계: 메시지 브로커(message broker), 메시지 큐(message queue).
    • 중간 단계: 메시지 지향 미들웨어(message-oriented middleware).

메시지 브로커 사용 방식의 장점(RPC와 비교).

  • 수신자가 사용 불가능하거나 과부하 상태일 때
    • 메시지 브로커가 버퍼처럼 동작하여 시스템 안정성이 향상된다.
  • 죽었던 프로세스에 메시지를 다시 전달할 수 있으므로, 메시지 유실을 방지할 수 있다.
  • 송신자가 수신자의 IP 주소나 포트 번호를 알 필요가 없다.
  • 하나의 메시지를 여러 수신자로 전송할 수 있다.
  • 논리적으로 송신자는 수신자와 분리된다.

메시지 전달 통신은 일반적으로 단방향이라는 점이 RPC와 다르다. 즉 송신 프로세스는 대개 메시지에 대한 응답을 기대하지 않는다. 프로세스가 응답을 전송하는 것은 가능하지만 이것은 보통 별도 채널에서 수행한다. 이런 통신 패턴이 비동기다. 송신 프로세스는 메시지가 전달될 때까지 기다리지 않고 단순히 메시지를 보낸 다음 잊는다.

메시지 브로커(Message brokers)

상용으로 TIBCO, IBM WebSphere, webMethods 등이 있음.

오픈소스 구현으로는 RabbitMQ, ActiveMQ, HornetQ, NATS, Apache Kafka 등이 있다.

  • 프로세스 하나가 메시지를 이름이 지정된 queuetopic으로 전송한다.
  • 브로커는 해당 queue나 topic의 소비자(consumer) 또는 구독자(subscriber)에게 메시지를 전달한다.
  • 동일한 토픽에 여러 생산자와 소비자가 있을 수 있다.
  • topic은 단방향 데이터플로만 제공한다.

분산 액터 프레임워크(Distributed actor frameworks)

  • actor model
    • 단일 프로세스 안에서 동시성을 위한 프로그래밍 모델.
    • 스레드를 직접 처리하는 대신 로직이 액터에 캡슐화된다.
    • 각 액터는 하나의 클라이언트나 엔티티를 나타낸다.
    • 액터는 로컬 상태를 가질 수 있다.
    • 액터는 비동기 메시지의 송수신으로 다른 액터와 통신한다.
    • 액터는 메시지 전달을 보장하지 않는다.
    • 각 액터 프로세스는 한 번에 하나의 메시지만 처리한다.
      • 스레드에 대해 걱정할 필요가 없음.
      • 각 액터는 프레임워크와 독립적으로 실행 가능.

분산 액터 프레임워크는 기본적으로 메시지 브로커와 액터 프로그래밍 모델을 단일 프레임워크에 통합한다.

인기 있는 분산 액터 프레임워크 tp rkwl.

  • Akka
  • Orleans
  • erlang

Links

  • [[Designing-Data-Intensive-Applications]]