프로토콜 버퍼

옥영진·2020년 10월 26일
0

프로토콜 버퍼(Protocol Buffer)은 구글에서 만든 데이터 직렬화 규격을 말한다. JSON, XML 등과 같이 텍스트 기반이 아니라, 바이너리 기반 규격이기에 용량이 작고 더 빠르게 데이터를 처리할 수 있다.

프로토콜 버퍼의 특징

바이너리 규격

프로토콜 버퍼는 바이너리 형태로 데이터를 가공하므로 사람이 읽을 수 없다. 그리고 메세지를 받는 소프트웨어 역시 메세지를 보낸 곳과 같은 메세지 규격을 사용해야만 복원하고 읽을 수 있다. 하지만 이는 암호화하여 저장한다는 의미가 아니기 때문에 보안에 안전한 것은 아니다.
프로토콜 버퍼로 가공된 데이터는 프로토콜 버퍼에서 제공하는 인터페이스 코드를 통해서만 볼 수 있어 디버깅 하기 어렵다. 그래도 바이너리 기반 규격을 사용하는 이유는 메세지 크기를 크게 줄일 수 있고 처리 성능이 좋기 때문이다.

메세지 규격 코드화

JSON, XML과 같은 텍스트 기반 메세지 규격은 규격만 일치하는 파일을 만들어도 사용할 수 있지만, 프로토콜 버퍼의 경우 다른 형태로 규격을 관리하므로 몇 가지 준비가 필요하다.

  • 스키마 파일
    스키마 파일(.proto)은 프로토콜 버퍼에서 사용할 메세지 구조를 정의한다. 사용하는 프로그래밍 언어와 상관없이 공통적인 문법을 가지므로, 스키마 구조만 정확히 알면 다른 프로그래밍 언어에서도 똑같이 사용이 가능하다.
message SimpleMessage {
	string name = 1;
	int64 num64 = 2;
	double float64 = 3;
	bytes uuid = 4;
	-
}
  • 컴파일러
    컴파일러(protoc)는 스키마 파일에 필요한 언어를 인터페이스 코드로 만들어주는 프로그램이다.

  • 인터페이스 코드
    인터페이스 코드는 컴파일러가 스키마를 읽어 만들어낸 결과물로, 모든 프로그램은 이 코드를 통해서만 데이터를 직렬화/역직렬화할 수 있다.

스키마 파일 구조

// 프로토콜 버퍼 문법 정의
syntax = "proto3";

// 여기서부터 메세지 정의

// message 키워드는 메세지 시작
message AnotherMessage {
	string name = 1;
	int64 num = 2;
}

message SimpleMessage {
	string name = 1;
	int64 num = 2;
	double float = 3;
	bytes uuid = 4;
	enum Type {
		Ping = 0;
		Urgent = 1;
	}
	Type type = 5;
}

repeated string name_list = 6;
repeated int64 num_list = 7;

map<string, string> map_field = 8;
  • 기본 필드
    스키마 내부에서 사용할 데이터를 필드라고 한다. 모든 필드는 타입, 필드 이름, 필드 번호가 있는데, 아래와 같이 정의한다.

<타입> <필드 이름> = <필드 번호>

필드 번호는 메세지 안에 정의된 필드를 직렬화할 때 사용하는 고유 식별자이다. 같은 메세지 내에서는 중복될 수 없지만, 다른 메세지면 중복될 수 있다.

  • 이넘 필드
    이넘 타입을 정의할 때 첫번째 이넘 필드 번호는 반드시 0이어야 한다. 이넘 타입은 중괄호로 감싸져 메세지와 독립적인 형태로 취급하기 때문에 같은 메세지 내에서도 필드 번호가 중복될 수 있다.

  • 리스트와 맵 필드
    타입 앞에 repeated 키워드가 붙은 필드는 리스트를 의미하고, map 키워드가 붙은 필드는 맵 필드를 의미한다.

profile
안녕하세요 함께 공부합시다

0개의 댓글