프로토콜 버프(Protobuf, Protocol Buffers)

V A M M U Z·2024년 10월 22일

알아보기

목록 보기
11/13

Protobuf(Protocol Buffers)

Google에서 개발한 데이터 직렬화 형식으로, 플랫폼 및 언어 독립적으로 데이터를 구조화하고 효율적으로 전송하거나 저장하기 위해 설계되었습니다.
XML이나 JSON 같은 형식과 비교했을 때 더 빠르고, 더 작은 크기를 유지하면서도 구조적 데이터를 표현할 수 있습니다.

프로토콜 버프의 특징

1. 이진 포맷 (Binary Format)

텍스트 기반 형식이 아닌 이진 형식으로 데이터를 직렬화합니다.

이를 통해 데이터 크기를 크게 줄이고 네트워크 전송이나 저장 시 성능을 향상시킵니다.

예를 들어, JSON은 사람이 읽을 수 있는 형식이지만, Protobuf는 더 작은 크기로 데이터를 표현하며 읽기 속도도 더 빠릅니다.

2. 스키마 정의

.proto 파일에서 데이터의 구조를 정의합니다.

이 파일에는 메시지 형식, 필드의 타입 및 순서 등이 명시되며, 이를 바탕으로 데이터를 직렬화/역직렬화합니다.

* 받는 곳, 보내는 곳 모두 있어야 함!

syntax = "proto3";

message Person {
  string name = 1;
  int32 id = 2;
  string email = 3;
}

Person 메시지는 이름(name), ID(id), 이메일(email)을 필드로 가지는 구조를 정의합니다.
각 필드에는 번호(1, 2, 3)도 부여되며, 이 번호는 Protobuf가 직렬화된 데이터를 해석할 때 사용됩니다.

3. 다양한 언어 지원

Protobuf는 다양한 프로그래밍 언어에서 사용할 수 있도록 지원됩니다.

.proto 파일로부터 C++, Java, Python, Go, Dart 등 여러 언어에 대한 코드 생성이 가능합니다. 이를 통해 각 언어에서 동일한 데이터 구조를 사용하여 데이터를 직렬화하고 역직렬화할 수 있습니다

4. 전방/후방 호환성

Protobuf의 중요한 장점 중 하나는 전방 및 후방 호환성을 쉽게 유지할 수 있다는 것입니다. 기존에 정의된 메시지에 새로운 필드를 추가하더라도, 이전 버전의 메시지를 사용하는 시스템과 호환됩니다.

새로운 필드는 무시되거나 기본값으로 설정되며, 삭제된 필드는 시스템에 영향을 미치지 않습니다.

5. 효율적인 직렬화/역직렬화

Protobuf는 CPU 자원을 효율적으로 사용하여 데이터를 직렬화 및 역직렬화합니다. JSON이나 XML과 달리, Protobuf는 이진 데이터를 사용하므로 파싱 속도가 매우 빠르며, 메모리 사용량이 적습니다.

6. 데이터 타입

  • int32, int64: 32비트 또는 64비트 정수
  • bool: 불리언
  • string: UTF-8로 인코딩된 문자열
  • bytes: 이진 데이터
  • 복합 타입: 메시지 내에 다른 메시지를 포함할 수 있습니다.

프로토콜 버프 언어가이드(proto 3)

Protobuf의 장점

  • 효율성: 이진 포맷이 매우 작고, 네트워크 대역폭과 저장 공간을 줄여줍니다.
  • 다양한 언어 지원: 개 이상의 언어에 대한 코드 생성을 지원하여 여러 기술이 혼합된 시스템에서 유리합니다.
  • 호환성: Protobuf는 이전 버전과의 호환성을 유지할 수 있도록 설계되었으며, 새로운 필드를 추가해도 기존 서비스가 깨지지 않습니다
  • 구조적 데이터: 복잡한 데이터 구조를 쉽게 정의하고 관리 가능합니다.

Protobuf의 단점

  • 가독성: 이진 형식이므로 사람이 직접 읽거나 수정하기 어려움.
  • 복잡성: 스키마를 정의하고, 이를 위한 코드 생성을 해야 하므로 초기 설정이 복잡할 수 있음.
💡

Protobuf는 성능과 효율성을 중시하는 시스템에서 특히 유용합니다.

예를 들어, 분산 시스템, 마이크로서비스 아키텍처, 모바일 애플리케이션, 게임 서버 등에서 Protobuf는 데이터 전송 및 저장에 뛰어난 성능을 제공합니다.


Node.js에서 protobuf 사용하기

모듈 설치하기 ( https://www.npmjs.com/package/protobufjs )

npm install protobufjs

protobuf의 스키마 정의 (~.proto)

syntax = 'proto3'; // protobuf 언어 사양의 proto3 개정판을 사용하고 있음을 지정합니다

package common;

message Person {
  string name = 1;
  int32 id = 2;
  string email = 3;
}

/*
* [ 유의사항 ] 
* 
* [1]
* 메시지 유형이 사용 중이면 변경할 수 없습니다
* 
* [2]
* 절대로 재사용해서는 안 됩니다
* 
* [3]
* 가장 자주 설정되는 필드에는 1~15까지의 필드 번호를 사용해야 합니다. 
* 낮은 필드 번호 값은 와이어 포맷에서 공간을 덜 차지합니다. 
* 예를 들어, 1~15 범위의 필드 번호는 인코딩하는 데 1바이트가 필요합니다. 
* 16~2047 범위의 필드 번호는 2바이트가 필요합니다
/*
  • 예제 코드
const protobuf = require("protobufjs");

// .proto 파일을 로드
protobuf.load("example.proto", function(err, root) {
  if (err) throw err;

  // 메시지 타입을 얻기
  const Person = root.lookupType("Person");

  // 메시지 생성
  const personPayload = { name: "John", id: 123, email: "john@example.com" };

  // 유효성 검사
  const errMsg = Person.verify(personPayload);
  if (errMsg) throw Error(errMsg);

  // 메시지 인스턴스 생성
  const message = Person.create(personPayload);

  // 직렬화 (바이너리 데이터로 변환)
  const buffer = Person.encode(message).finish();
  console.log(buffer);

  // 역직렬화 (바이너리 데이터를 메시지 객체로 변환)
  const decodedMessage = Person.decode(buffer);
  console.log(decodedMessage);
});

0개의 댓글