나만의 작은 도서관
[Network] protoBuf와 직렬화/역직렬화 본문
유의사항: 해당 글은 공부한 내용을 정리하는 용도이므로, 수정이 필요할 경우 내용의 수정이 있을 수 있습니다.
protoBuf
protoBuf는 Protocol Buffer의 약자이며, Google에서 개발한 직렬화 데이터 구조이다. 효율적인 데이터 교환을 위해 설계되었으며, 특히 네트워크 통신과 저장 시스템에서 널리 사용됩니다. 이런 protoBuf는 여러 가지 데이터 구조 중 하나이기 때문에 자주 접해본 XML, JSON과 방식과 유사하다고 볼 수 있습니다.
직렬화 (serialization)와 역직렬화( Deserialization )
protoBuf가 직렬화 데이터 구조인만큼 우선 직렬화와 반대되는 개념인 역직렬화가 무엇이지 알아야합니다.
직렬화는 객체 또는 데이터 구조를 연속적인 바이트 스트림(byte Stream)으로 변환하는 과정입니다. 이 바이트 스트림은 파일, 메모리 또는 네트워크를 통해 다른 프로그램이나 시스템으로 전달될 수 있습니다.
반대로, 역직렬화는 직렬화된 바이트 스트림을 다시 원래의 객체나 데이터 구조로 변환하는 과정입니다. 이를 통해 데이터를 저장하거나 전송한 후에 원래의 상태로 복원할 수 있습니다.
직렬화와 역직렬화를 사용하는 여러 방식들
protobuf가 아니더라도 직렬화와 역직렬화를 사용하는 방식들은 다양합니다. 방식들의 종류는 아래와 같습니다.
직렬화 | 역직렬화 | |
Java | Serializable 인터페이스를 사용하여 객체를 직렬화. | ObjectInputStream을 사용하여 객체를 역직렬화. |
Python | pickle 모듈을 사용하여 객체를 직렬화. | pickle 모듈을 사용하여 객체를 역직렬화. |
JSON, XML | 데이터를 텍스트 형식으로 직렬화. | 데이터를 텍스트 형식에서 객체로 역직렬화. |
protoBuf의 장점
- 효율적인 데이터 표현 및 빠른 처리 속도: 작은 크기의 바이너리 형식과 빠른 직렬화/역직렬화 덕분에 성능이 뛰어납니다.
- 후방 호환성: 시스템을 업데이트하면서도 이전 버전의 데이터를 유지할 수 있어, 데이터 모델의 변화에 유연하게 대응할 수 있습니다.
- 언어 및 플랫폼 독립성: 다양한 언어와 플랫폼을 지원하여 이기종 시스템 간의 통신을 용이하게 합니다.
- 명확한 데이터 정의: 스키마 파일을 통해 데이터 구조를 명확히 정의하고, 자동 코드 생성을 통해 개발을 단순화합니다.
- 풍부한 데이터 타입: 기본 데이터 타입과 복합 타입을 지원하여 복잡한 데이터 구조를 효과적으로 표현할 수 있습니다.
- 우수한 성능과 확장성: 성능이 중요한 애플리케이션과 큰 규모의 데이터 처리에 적합합니다.
protoBuf 사용법
protoBuf를 사용하고 싶다면 데이터 구조를 정의해야합니다. JSON을 사용했을 때 package.json과 같이 .json확장자를 사용하듯 protoBuf는 .proto 확장자를 통해 데이터 구조를 정의합니다.
.proto에서 메세지 정의 예제
// person.proto
syntax = "proto3";
message Person {
// field type field name = field number
string name = 1;
int32 id = 2;
string email = 3;
}
- syntax: 버전. 위 예시에서는 proto3버전을 사용한다 선언했다.
- message: 메세지를 정의한다. 메세지 이름과 메세지 안에 들어갈 필드를 작성하면 된다.
- field: 메세지 안에 들어가는 필드이다. "field type field name = field number "형식으로 작성하면 된다.
- field type: 필드 타입(string, int32등등...)
- field name: 필드 이름
- field number: 필드 번호이다. 다른 필드와 중복되지 않는 숫자를 넣어주면 된다.
필드 번호를 사용하는 이유
Protobuf는 데이터를 압축하여 효율적으로 저장하고 전송하는데, 이 과정에서 필드 이름 대신 필드 번호를 사용하기 때문입니다. 필드 번호를 사용하게되면 데이터를 더 작은 크기로 생성할 수 있고, 이는 전송 속도를 높이고 저장 공간을 절약하는 데 도움이 됩니다.
+) field Tag에서 사용해야하는 번호가 정해져있는건 아닙니다. 그저 관리와 이해를 쉽게 하기 위한 관례라고 보시면 됩니다.
protoBuf의 작동과정을 알고싶다면 아래 링크 글을 참고하면 좋을 듯 하다.
https://jeong-pro.tistory.com/190
자바스크립트에서 protobuf 사용해보기
자바스크립트에서 protobuf를 사용하려면 우선 protobufjs 패키지를 설치해야합니다.
https://protobufjs.github.io/protobuf.js/
아래 코드는 protobuf 방식으로 직렬화된 메세지를 만들고 해당 메세지, 인코딩된 메세지, 디코딩한 메세지를 출력해보는 코드입니다.
import protobuf from 'protobufjs';
protobuf.load("person.proto").then(root => {
const Person = root.lookupType("Person");
const message = Person.create({ name: "John Doe", id: 123, email: "johndoe@example.com" });
const buffer = Person.encode(message).finish();
const decodedMessage = Person.decode(buffer);
console.log("Original message:", message);
console.log("Encoded buffer:", buffer);
console.log("Decoded message:", decodedMessage);
})
참고 자료
https://appmaster.io/ko/blog/peurotobeopeuran-mueosibnigga
https://martin.kleppmann.com/2012/12/05/schema-evolution-in-avro-protocol-buffers-thrift.html
'Common > CS-네트워크' 카테고리의 다른 글
[Network] 빅 엔디안(Big Endian)과 리틀 엔디안(Little Endian) (0) | 2024.06.28 |
---|---|
[Network] 1분 간단 질문. TCP와 UDP가 무엇인가요? (0) | 2024.06.28 |
[Network] 1분 간단 질문. TCP Handshake란 무엇인가요? (0) | 2024.06.27 |
[Network] 대칭 키 암호화 방식과 공개 키 암호화 방식 (0) | 2024.06.26 |
[Network] 로드 밸런싱(Load Balancing) (0) | 2024.06.26 |