데이터 타입이나 스키마가 변경될 때 애플리케이션 코드에 대한 변경이 종종 발생하는데 대규모 애플리케이션에서 코드 변경은 즉시 반영할 수 없다.
- 순화식 업그레이드를 사용하기 때문에 일시적으로 버전의 불일치가 생길 수 있다.
- 클라이언트 측 애플리케이션은 사용자에 따라 버전이 따를 수 있다.
시스템이 원할하게 실행되게 하려면 양방향으로 호환성을 유지해야 한다.
- 하위 호환성
- 새로운 코드는 예전 코드가 기록한 데이터를 읽을 수 있어야 한다.
- 상위 호환성
- 예전 코드는 새로운 코드가 기록한 데이터를 읽을 수 있어야 한다.
- 새 버전의 코드에 의해 추간된 것을 무시할 수 있어야해서 다루기 더 어렵다.
데이터 부호화 형식
데이터를 파일에 쓰거나 네트워크를 통해 전송하려면 바이트열의 형태로 부호화해야 한다.
언어별 형식
많은 프로그래밍 언어는 객체를 바이트열로 부호화하는 기능을 내장한다.
하지만 이런 내장 기능은 문제점이 많다.
- 부호화는 특정 언어와 묶여 있어 서로 다른 언어에서 읽기 매우 어렵다.
- 공격자가 임의의 바이트열을 복화할 수 있는 애플리케이션을 얻을 수 있으면 임의의 클래스를 인스턴스화할 수 있고 임의 코드를 실행할 수 있어 보안 문제가 있다.
- 상위, 하위 호환성의 문제가 등한시 된다.
- 성능이 좋지 않다.
JSON, XML, 이진 변형
많은 프로그래밍 언어에서 읽고 쓸 수 있는 표준화된 부호화로서 JSON, XML이 있다.
하지만 이런 표준화된 부호화에도 문제점이 있다.
- 데이터 타입이 없기 때문에 수의 부호화에 애매함이 있다.
- 이진 문자열을 지원하지 않고 데이터 크기가 늘어난다.
이진 부호화
JSON은 XML 보다는 덜 장황하지만 이진 형식과 비교하면 훨씬 많은 공간을 사용한다.
메시지 팩

- 8 → 객체, 9 → 배열, a → 문자열
- 이진 부호화는 길이 66바이트로 JSON으로 얻은 81바이트보다 작다.
- 하지만 작은 공간의 절약이 사람의 가독성을 해칠만큼 가치가 있는지는 확실하지 않다.
스리프트와 프로토콜 버퍼
스리프트는 페이스북, 프로토콜 버퍼는 구글에서 개발된 이진 부호화 라이브러리다.
- 부호화할 데이터를 위한 스키마가 필요하다.
- 이러한 스키마를 가지고 다양한 언어의 클래스를 생성할 수 있다.
스리프트의 바이너리 프로토콜

메시지 팩과 마찬가지로 타입 주석이 있고 길이와 데이터를 표시하는 문자열이 있다.
다른점은 필드 이름 대신 필드 대그를 사용한다.
스리프트 컴팩트 프로토콜

- 필드 타입과 태그 숫자를 단일 바이트로 줄인다.
- 숫자는 8바이트 모두 사용하는 대신 2바이트로 부호화한다.
프로토콜 버퍼

- 스리프트 컴팩트 프로토콜과 비슷하다.
- 필드 타입과 태그 숫자를 단일 바이트로 줄인다.
- 스키마 필드에 있던 required, optional 표시를 이진 데이터에서 표현하지 않는다.
필드 태그와 스키마 발전
- 스키마 발전
- 필드에 새로운 태그 번호를 부여하는 방식으로 스키마에 새로운 필드를 추가할 수 있다.
- 필드를 추가하기 이전 코드는 모르는 태그를 무시하면 되므로 상위 호환성을 유지할 수 있다.
- 스키마에 새로운 필드를 추가할 때는 optinal or 기본값을 가져야 한다.
- 예전코드는 추가한 값을 기록하지 않기 때문에 필수값으로 설정하면 새로운 코드에서 읽을 수 없다.
- 필드를 삭제할 때는 필드를 추가할 때와 반대로 하면 된다.
데이터타입과 스키마 발전
- 데이터 타입을 변경하는 건 불가능 하지 않지만 값이 정확하지 않을 수 있다.
- 프로토콜 버퍼는 배열, 목록 데이터 타입 대신 repeated 표시자가 있다.
- 이것은 좀 더 유연하게 단일 값 → 다중 값 변경을 할 수 있다.
- 스리프트는 단일 값→ 다중 값을 변경할 수 없지만 중첩된 목록을 지원한다는 장점이 있다.
아브로
하둡에서 사용하기 위해 만들어진 부호화 형식
- 필드나 데이터 타입 식별을 위한 정보가 없다.
- 아브로에서는 파싱할 때 스키마에 나타난 순서대로 데이터타입을 파악해야한다.
쓰기 스키마와 읽기 스키마
- 쓰기 스키마
- 데이터를 아브로로 부호화할 때 사용하는 스키마
- 읽기 스키마
- 읽은 데이터를 복호화할 때 사요하는 스키마
- 애플리케이션 코드가 의존한다.
- 쓰기 스키마와 읽기 스키마는 동일하지 않아도 되고 호환 가능하면 된다
스키마 발전 규칙
아브로에서도 상위 호환성, 하위 호환성을 유지할 수 있고 호환성을 유지하기 위해서는 기본값이 있는 필드만 추가, 삭제 가능하다.
필드에 널을 허용하려면 유니온 타입을 사용해야 한다. union { null, long, string } feild;
쓰기 스키마는 무엇인가?
쓰기 스키마를 알 수 있는 다양한 방법
- 많은 레코드가 있는 대용량 파일
- 파일 시작 부분에 한 번만 쓰기 스키마를 포함한다.
- 개별적으로 기록된 레코드를 가진 데이터 베이스 (에스프레소)
- 레코드 시작 부분에 버전 번호를 포함한다.
- 데이터베이스에는 스키마 버전 목록을 유지한다
- 네트워크 연결을 통해 레코드 보내기
- 스키마 버전을 합의하고 연결을 유지하는 동안 합의된 스키마를 사용한다.
동적 생성 스키마
아브로는 동적 생성 스키마를 고려해 설계해서 스리프트, 프로토콜 버퍼에 비해 수월하게 스키마 변경에 유연하게 대처 가능하다.
코드 생성과 동적 타입 언어
스리프트와 프로토콜 버퍼는 코드 생성에 의존하는데 아브로는 코드 생성을 선택적으로 제공하고 필요하면 JSON 파일을 열어 데이터를 볼 수 있다.
스키마의 장점
- 부호화된 데이터에서 필드 이름을 생략할 수 있어 크기가 작을 수 있다.
- 자동화 할 수 있는 유용한 문서화 형식이다.
- 스키마 데이터베이스를 유지하면 상위 호환성과 하위 호환성을 확인할 수 있다.
- 정적 언어에서는 타입체크가 가능해 유용하다.
데이터플로 모드
하나의 프로세스에서 다른 프로세스로 데이터를 전달하는 다양한 방법을 알아본다.
데이터베이스를 통한 데이터플로
새로운 버전의 애플리케이션이 기록한 데이터를 예전 버전의 애플리케이션이 갱신하는 경우 주의하지 않으면 데이터가 유실될 수 있다
보관 저장소
백업 목적으로 데이터를 보관할 때는 일관되게 부호화를 하는게 좋다
서비스를 통한 데이터 플로 : REST와 RPC
서버 자체가 다른 서비스의 클라이언트일 수 있고 이런 방식을 전통적으로는 서비스 지향 설계라고 불렀으면 최근에는 MSA로 재탄생되었다.
서비스 지향 및 마이크로서비스 아키텍처의 핵심 설계 목표는 서비스를 배포와 변경에 독립적으로 만들어 애플리케이션 변경과 유지보수를 더 쉽게 하는 것이다.
웹 서비스
웹 서비스에는 REST와 SOAP가 있다
- REST
- HTTP의 원칙을 토대로 한 설계 철학
- 캐시, 인증 등등 HTTP 기능을 사용한다.
- SOAP
- 네트워크 API 요청을 위한 XML 기반 프로토콜
- 대부분 HTTP 기능을 사용하지 않는다.
원격 프로시저 호출 문제
RPC 모델은 원격 네트워크 서비스 요청을 같은 프로세스 안에서 특정 프로그래밍 언어의 함수나 메서드를 호출하는 것돠 동일하게 사용 가능하게 해준다.
하지만 로컬 함수 호출과 네트워크 요청은 다르기 때문에 실패한 요청을 다시 보내는 것과 같은 대책을 세워야 한다.
- 타임 아웃이 발생할 수 있다.
- 요청이 실제로 처리되고 응답만 유실될 수 있다.
- 지연시간이 다양하게 발생할 수 있다.
RPC의 현재 방향
차세대 RPC 프레임워크는 하나의 요청과 하나의 응답뿐 아니라 시간에 따른 일련의 요청과 응답으로 구성된 스트림을 지원한다.
- REST
- RPC
- 같은 데이터센터 내의 같은 조직이 소유한 서비스간 요청
메시지 전달 데이터플로
메시지 브로커를 사용하는 방식은 RPC 방식에 비해 여러 장점이 있다.
- 수신자가 사용 불가능할 때 버퍼 역할을 할 수 있어 시스템 안정성이 향상된다.
- 메시지를 재 전달 할 수 있기에 유실을 방지할 수 있다.
- 하나의 메시지를 여러 수신자로 전송할 수 있다.
- 논리적으로 송신자와 수신자가 분리된다.
메시지 브로커
과거에는 상용 소프트웨어가 우위를 차지했지만 최근에는 래빗MQ, 카프카 등 오픈소스가 대중화 됐다.
프로세스 하나가 메시지를 큐나 토픽으로 전송하고 브로커는 소비자 또는 구독자에게 메시지를 전달한다.
분산 액터 프레임워크
- 액터 모델
- 단일 프로세스 안에서 동시성을 위한 프로그래밍 모델
- 로컬 상태를 가질 수 있고 비동기 메시지의 송수신으로 다른 액터와 통신한다.