본문 바로가기
Etc.

Protocol Buffer

by devOat 2024. 8. 19.

 

저번에 gRPC에 대해 알아보는 글을 적었었는데,

그 과정에서 gRPC는 JSON이 아닌 프로토콜 버퍼를 이용하여 데이터를 전송한다고 했었다.

 

 

오늘은 그래서 프로토콜 버퍼가 무엇인지,

JSON에 비해 왜 좋다고 하는 건지 정리를 해보자 !

 

 

 

 

Protocol Buffer?

 구조화 된 데이터를 직렬화 하는 방식

 

직렬화(Serialization)란 , 데이터를 파일로 저장하거나 네트워크 통신에 사용하기 위한 byte stream형태로 변환하는 것이다.

 

 

 server - client 간 데이터를 교환 할 때 주로 JSON을 사용하는데,

gRPC에서 ProtoBuf를 사용하는 이유는 무엇일까?

 

 

 

JSON과의 차이점?

{name : "minah", age : 27} 이라는 객체가 있다고 했을 때,

 

1. JSON 포맷으로 직렬화 할 경우

let person = { name : "jinny" age : 27 };

//JS객체 -> JSON 문자열로 변경
let serializedJson = JSON.stringify(person);

// 데이터 크기는 총 25byte 
//serializedJson = {"name":"jinny","age":27}

 

2. 프로토콜 버퍼 포맷으로 직렬화 할 경우

* 프로토 파일 : 프로토콜 버퍼 방식을 사용하기 위해 필요한 파일

message Person
{
	string name = 1; //필드 넘버
	int32 age = 27;
}

 

프로토콜 버퍼를 사용할 경우에는 속성 값 (name, age)을 필드 넘버로 대체하기 때문에, 총 9byte를 사용하게 하게 된다.

 

name?

■( 최초 1 byte => 필드 넘버와 타입을 표기하는데 사용 ) ■ (다음에 올 데이터 길이) ■ ■ ■ ■ ■ (데이터)

<최초 1byte>

□ □ □ □ □ (필드 넘버) □ □ □ (필드 타입)

 

age?

■ (필드 태그와 넘버) ■ (데이터)

 

 

 

Field Type

프로토콜 버퍼의 메세지에서 사용할 수 있는 필드 타입은 한정적으로 정해져 있는데,
내가 사용하는 유니티. 즉 c#에서 자주 사용하는 필드 타입만 정리해보겠다.

.proto c#
double double
float float
int32 int
int64 long
uint32 uint
uint64 ulong
bool bool
string string

 

 

또한 c++ 의 헤더 참조 (#include)처럼 .proto또한 import 문을 추가 하여 다른 .proto파일을 참조할 수 있다.

예를 들어 아래와 같은 ItemBase 를 정의해놓은 파일이 있다고 가정해보자.

// item_base.proto 라고 가정할 때

message ItemBase
{
	int32 id = 1;
    string name = 2;
    int32 amount = 3;
}

 

만약, 다른 프로토 파일에서 해당 message 유형을 사용하고 싶을 경우

아래와 같이 사용할 수 있다.

import "protos/item_base.proto";

message ItemWeapon
{
	ItemBase data = 1;
    bool is_equip = 2;
    int32 weapon_option = 3;
}

 

그 외 repeated 타입을 이용하여 C++의 Vector (C#의 List) ,

 

map 을 이용하여 페어링 된 키 - 필드 자료 구조를 사용할 수 있다.
(C++의 unordered_map (정렬 되지않은 해시셋이라고 생각하면 될 것 같음) / C#의 Dictionary)

 

 

관련한 자료의 링크를 첨부함.

https://protobuf.dev/programming-guides/encoding/#maps%EF%BB%BF

 

Encoding

Explains how Protocol Buffers encodes data to files or to the wire.

protobuf.dev

 

 

 

 

그러나 map의 value는 repeated가 될 수 없다

즉 내가 애용하는...

 

map<string,vector<T>> 의 형태가 불가능 하다는 것....

 

그치만 message유형은 저장이 가능하기에 조금 번거롭긴 하지만

실무에서는 대충 이런 느낌으로 사용 중...

 

message ItemBase
{
	int32 id = 1;
    int32 amount = 2;
}

message ItemList
{
	repeated ItemBase item_lists = 1;
}

message UserEquipments
{
	map<string,ItemList> all_user_equipments = 1;
}

 

 

 

 

 

 

 

프로토콜 버퍼에 대한 공식 문서를 추가로 첨부하고 

글을 마치겠음.

 

 

[구글에서 제시한 스타일 가이드]

https://protobuf.dev/programming-guides/style/

 

Style Guide

Provides direction for how best to structure your proto definitions.

protobuf.dev

 

 

[protocol buffers]

https://protobuf.dev/overview/

 

Overview

Protocol Buffers are a language-neutral, platform-neutral extensible mechanism for serializing structured data.

protobuf.dev

 

 

'Etc.' 카테고리의 다른 글

gRPC란?  (0) 2024.08.05