블로그 이미지
평범하게 살고 싶은 월급쟁이 기술적인 토론 환영합니다.같이 이야기 하고 싶으시면 부담 말고 연락주세요:이메일-bwcho75골뱅이지메일 닷컴. 조대협


Archive»


 
 

구글 프로토콜 버퍼 (Protocol buffer)

프로그래밍 | 2017.06.25 19:30 | Posted by 조대협


구글 프로토콜 버퍼

조대협 (http://bcho.tistory.com)


텐서 플로우로 모델을 개발하다가 학습이 끝난 모델을 저장하여, 예측하는 데 사용하려고 하니, 모델을 저장하는 부분이 꽤나 복잡하여 찾아보니, 텐서플로우는 파일 저장 포맷을 프로토콜 버퍼를 사용한다는 것을 알았다.


그래서, 오래전에 살펴보았던 프로토콜 버퍼를 다시 살펴보았다.

개요 및 특징

프로토토콜 버퍼는 구글에서 개발하고 오픈소스로 공개한, 직렬화 데이타 구조 (Serialized Data Structure)이다. C++,C#, Go, Java, Python, Object C, Javascript, Ruby 등 다양한 언어를 지원하며 특히 직렬화 속도가 빠르고 직렬화된 파일의 크기도 작아서 Apache Avro 파일 포맷과 함께 많이 사용된다.

(직렬화란 데이타를 파일로 저장하거나 또는 네트워크로 전송하기 위하여 바이너리 스트림 형태로 저장하는 행위이다.)


특히 GRPC 라는 네트워크 프로토콜의 경우 HTTP 2.0 을 기반으로 하면서, 메세지를 이 프로토콜 버퍼를 이용하여 직렬화하기 때문에, 프로토콜 버퍼를 이해해놓으면 GRPC를 습득하는 것이 상대적으로 쉽다.


프로토콜 버퍼는 하나의 파일에 최대 64M까지 지원할 수 있으며, 재미있는 기능중 하나는 JSON 파일을 프로토콜 버퍼 파일 포맷으로 전환이 가능하고, 반대로 프로토콜 버퍼 파일도 JSON으로 전환이 가능하다.

설치 및 구성

프로토콜 버퍼 개발툴킷은 크게 두가지 부분이 있다. 데이타 포맷 파일을 컴파일 해주는 protoc 와 각 프로그래밍 언어에서 프로토콜 버퍼를 사용하게 해주는 라이브러리 SDK가 있다.


protoc 컴파일러와, 각 프로그래밍 언어별 SDK는 https://github.com/google/protobuf/releases  에서 다운 받으면 된다.


protoc 는 C++ 소스 코드를 직접 다운 받아서 컴파일하여 설치할 수 도 있고, 아니면 OS 별로 미리 컴파일된 바이너리를 다운받아서 설치할 수 도 있다.  


각 프로그래밍 언어용 프로토콜 버퍼 SDK는 맞는 버전을 다운 받아서 사용하면 된다. 파이썬 버전 설치 방법은  https://github.com/google/protobuf/tree/master/python 를 참고한다.

이 글에서는 파이썬 SDK 버전을 기준으로 설명하도록 한다.

구조 및 사용 방법

프로토콜 버퍼를 사용하기 위해서는 저장하기 위한 데이타형을 proto file 이라는 형태로 정의한다. 프로토콜 버퍼는 하나의 프로그래밍 언어가 아니라 여러 프로그래밍 언어를 지원하기 때문에, 특정 언어에 종속성이 없는 형태로 데이타 타입을 정의하게 되는데, 이 파일을 proto file이라고 한다.

이렇게 정의된 데이타 타입을 프로그래밍 언어에서 사용하려면, 해당 언어에 맞는 형태의 데이타 클래스로 생성을 해야 하는데, protoc 컴파일러로 proto file을 컴파일하면, 각 언어에 맞는 형태의 데이타 클래스 파일을 생성해준다.


다음은 생성된 데이타 파일을 프로그래밍 언어에서 불러서, 데이타 클래스를 사용하면 된다.

예제

간단한 파이썬 예제를 통해서 사용법을 익혀보자. 저장하고자 하는 데이타 포맷은 Person 이라는 클래스형으로, 이름,나이,이메일을 순차적으로 가지고 있는 데이타 포맷을 정의하여, Person 객체를 생성하여 데이타를 저장하고 이 객체를 파일에 저장했다가 읽어 들이는 예제이다.


이름과 이메일은 문자열, 나이는 숫자로 저장된다. 이 데이타형을 proto 형으로 정의하면 다음과 같다.

address.proto

syntax = "proto3";

package com.terry.proto;


message Person{

 string name = 1;

 int32 age=2;

 string email=3;

}


이 파일을 address.proto 라는 이름으로 저장한다. 다음 proto 파일을 파이썬용 코드로 컴파일한다. protoc 명령을 이용하면 되는데,


protoc -I=./ --python_out=./ ./address.proto


  • -I에는 이 protofile이 있는 소스 디렉토리

  • --python_out에는 생성된 파이썬 파일이 저장될 디렉토리

  • 그리고 마지막으로 proto 파일을 정의한다.


이렇게 컴파일을 하면 --python_out으로 지정된 디렉토리에 address_pb2.py 라는 이름으로 파이썬 파일이 생성된다. (pb2는 protocol buffer2를 의미하는 확장자이다.)


다음은 생성된 Person 클래스를 이용하여 객체를 만들고, 값을 지정한 후 이를 파일로 저장하는 예제이다.

write.py

import address_pb2


person = address_pb2.Person()


person.name = 'Terry'

person.age = 42

person.email = 'terry@mycompany.com'


try:

f = open('myaddress','wb')

f.write(person.SerializeToString())

f.close()

print 'file is wriiten'

except IOError:

print 'file creation error'


protoc에 의해 컴파일된 address_pb2 모듈을 import 한후에, address_pb2.Person()으로 person 객체를 생성한다. 다음에 person.name, person.age, person.email에 값을 넣은 후 파일을 열어서 파일에 person 객체의 내용을 넣는데, 이때 SerializeToString() 메서드를 이용하여 문자열로 직렬화 한다.


다음 코드는 이렇게 파일로 저장된 person 객체를 다시 파일로 부터 읽는 코드이다.

read.py

import address_pb2


person = address_pb2.Person()


try:

f = open('myaddress','rb')

person.ParseFromString(f.read())

f.close()

print person.name

print person.age

print person.email

except IOError:

print 'file read error'


앞의 코드와 같이 빈 person 객체를 만든 후에, 파일에서 문자열을 읽어서 ParseFromString() 메서드를 이용하여 문자열을 person 객체로 파싱한후에, 그 내용을 출력한다.

데이타 구조

위의 예제에서는 간단하게 name,age,email 정도의 구조만 간단하게 정의했지만, JSON과 같이 계층을 가지거나 배열형의 데이타 구조도 같이 정의할 수 있고, enum과 같은 타입 정의도 가능하다.

자세한 설명은 https://developers.google.com/protocol-buffers/docs/proto 를 참고하기 바란다.

간단한 팁 - JSON 변환

앞서 설명했듯이, 프로토콜 버퍼의 다른 장점중의 하나는 프로토콜 버퍼로 저장된 데이타 구조를 JSON으로 변환하는 것도 가능하고 역으로 JSON 구조를 프로토콜 버퍼 객체로 만들 수 도 있다.

아래 코드는 프로토콜 버퍼 객체인 person을 JSON으로 변환하여 출력하는 부분이다. MessageToJson 메서드를 사용하면 된다.


print person.name

print person.age

print person.email


from google.protobuf.json_format import MessageToJson

jsonObj = MessageToJson(person)

print jsonObj


다음은 실행 결과이다.


Terry

42

terry@mycompany.com

{

 "age": 42,

 "name": "Terry",

 "email": "terry@mycompany.com"

}



이 기능을 사용하면, 클라이언트(모바일)에서 서버로 HTTP/JSON 과 같은 REST API를 구현할때, 전송전에, JSON을 프로토콜 버퍼 포맷으로 직렬화 해서, 전체적인 패킷양을 줄여서 전송하고, 서버에서는 받은 후에, 다시 JSON으로 풀어서 사용하는 구조를 취할 수 있다. 사실 이게 바로 GRPC 구조이다.

API 게이트웨이를 백앤드 서버 전면에 배치 해놓고, 프로토콜 버퍼로 들어온 메세지 바디를 JSON으로 변환해서 백앤드 API 서버에 넘겨주는 식의 구현이 가능하다.


'프로그래밍' 카테고리의 다른 글

gRPC Channel  (0) 2018.11.23
구글 프로토콜 버퍼 (Protocol buffer)  (3) 2017.06.25
grpc 설치하기  (0) 2015.04.02
grpc (google rpc)에 대한 분석 #1  (0) 2015.04.01
구글의 HTTP 기반의 RPC 프로토콜 GRPC  (1) 2015.03.31
국내 자바 MVC 프레임웍 사용 현황  (5) 2009.11.11

grpc 설치하기

프로그래밍 | 2015.04.02 02:11 | Posted by 조대협

Google RPC 설치하기

(조대협 http://bcho.tistory.com)


지난 GRPC 소개에 이어서 오늘은 JAVA에서 GRPC를 사용하기 위한 설치 방법을 설명한다.


  • https://github.com/grpc/grpc-common/tree/master/java
  • https://github.com/grpc/grpc-common
  • https://github.com/grpc/grpc-common/blob/master/java/javatutorial.md
  • https://github.com/grpc/grpc-java


글들을 참고하였으며, 컴파일 환경 설정등을 위해서 생각보다 시간이 많이 소요된다. (삽질,Visual Studio 설치 포함 한 2~3시간 걸린듯)


grpc hello world / java





grpc-java 설치하기

https://github.com/grpc/grpc-java#how-to-build 를 참고


준비 : java 8, maven 3.2.x,gradle 2.3 필요


1. 코드 받기

 C:\dev\libs> git clone https://github.com/grpc/grpc-java


2. 관련 라이브러리 설치


1) Netty 4.1 설치

grpc-java는 Netty 4.1에 기반함. 아래절차에 따라서 설치한다.

cd C:\dev\libs\grpc-java>

$ git submodule update --init

$ cd lib/netty

$ mvn install -pl codec-http2 -am -DskipTests=true


2) Protocolbuf 3.0.0-alhpa-2 설치 (windows)

안타깝게도 알파버전이라 윈도우즈용 인스톨 바이너리가 없다. 소스 받아서 직접 컴파일해야 한다.

윈도우 환경에서는 C/C++ 컴파일러가 필요하니까는 간단하게 Visual Studio 무료 버전을 깔자 https://www.visualstudio.com/en-us/products/free-developer-offers-vs.aspx

(무료 버전 제공)

다음은 c:\dev\lib\protobuf에 설치 하는 순서이다.


C:\dev\libs>git clone https://github.com/google/protobuf.git


다음으로, C:\dev\libs\protobuf\vsprojects 에 들어가면 visual studio 프로젝트 파일이 있음

VC로 Release 빌드하면 됨. (이때 반드시, Release 모드로 빌드할것, Debug 모드로 빌드하면 나중에 grpc-java 빌드할때 링크에러남). Test 코드 빌드하다가 에러가 나는데 무시하자. 테스트 코드가 안들어가 있다.


빌드 후, C:\dev\libs\protobuf\vsprojects 아래에 readme.txt를 보고 따라할것


C:\dev\libs\protobuf\vsprojects\Release 에 빌드 결과가 생김

안에 protoc.exe가 생김



3. grpc-java 설치


위에서 만든 protoc.exe를 path가 있는 디렉토리에 복사하거나.

본인의 경우에는 위의 디렉토리 자체를 다 PATH에 걸어버렸다. (연관 라이브러리들이 있어서리)

다음으로 grpc-java를 설치하자


앞에서 받은 grpc-java 디렉토리로 가서

$ gradlew install -Pprotobuf.include=C:\dev\libs\protobuf\src  -Pprotobuf.libs=C:\dev\libs\protobuf\vsprojects\Release


여기까지 했으면 grpc 설치가 완료되었다. 실제로 동작하는지 확인하려면, 예제 코드를 돌려보면 되는데, 실행 방법은 다음과 같다. 


서버 실행

gradlew :grpc-examples:helloWorldServer -Pprotobuf.include=C:\dev\libs\protobuf\src  -Pprotobuf.libs=C:\dev\libs\protobuf\vsprojects\Release



클라이언트 실행

gradlew :grpc-examples:helloWorldClient -Pprotobuf.include=C:\dev\libs\protobuf\src  -Pprotobuf.libs=C:\dev\libs\protobuf\vsprojects\Release


실행시 위와 같이 protocol buf lib 위치와 소스 위치를 지정해야 하는데, 매번 지정하기 귀찮다면 다음과 같이 환경 변수로 넣어놓아도 된다.

Since specifying those properties every build is bothersome, you can instead create %HOMEDRIVE%%HOMEPATH%.gradle\gradle.properties with contents like:

protobuf.include=C:\\path\\to\\protobuf-3.0.0-alpha-2\\src

protobuf.libs=C:\\path\\to\\protobuf-3.0.0-alpha-2\\vsprojects\\Release


'프로그래밍' 카테고리의 다른 글

gRPC Channel  (0) 2018.11.23
구글 프로토콜 버퍼 (Protocol buffer)  (3) 2017.06.25
grpc 설치하기  (0) 2015.04.02
grpc (google rpc)에 대한 분석 #1  (0) 2015.04.01
구글의 HTTP 기반의 RPC 프로토콜 GRPC  (1) 2015.03.31
국내 자바 MVC 프레임웍 사용 현황  (5) 2009.11.11

grpc (google rpc)에 대한 분석 #1

프로그래밍 | 2015.04.01 23:40 | Posted by 조대협

GRPC 분석 #1


앞글에서도 간단하게 GRPC에 대해서 소개했는데, 제법 괜찮은것 같아서 조금 더 분석해보기로 결정하였다.

주목할만한 특징 중의 크게 두가지가 있다.


모바일 지원 여부

먼저, 모바일이 지원된다. 안드로이드나, iOS (Object-C)를 지원하기 때문에, 모바일 클라이언트에서 호출이 가능하고, 바이너리 프로토콜을 사용하며, 하나의 Connection으로 RPC 호출을 처리하기 때문에, JSON/HTTP REST에 비해서 네트워크 대역폭 소모가 적고, 매번 커넥션을 열어야 하는 부담이 없기 때문에, 효율적이다. (속도는 당연히 빠를듯)


확인을 해봐야 겠지만, 양방향 스트리밍을 지원한다는 것을 봐서는 푸쉬같이 클라이언트쪽으로 메세지를 쏘는 기능도 가능할듯 하다.


Google Protocol Buffer 기반

안의 메세지는 구글의 PB를 기반으로 한다. PB는 Serialization 프레임웍으로, Message Q로 넘기거나, 또는 NoSQL등에 바로 저장할 수 있기 때문에, 내부 메세징 포맷으로도 바로 사용이 가능하다.


아쉬운 점은 아직까지 웹 브라우져 기반의 자바스크립트는 지원하지 않는다. (이것까지 되면, 웹 소켓까지 대체할 수 있을 듯한다. 약간 아쉬운듯)


구체적인 내용은 프로토타입핑을 해봐야 알 수 있을듯..

어쨌거나, 조금 지켜볼 필요가 있는 프레임웍인듯



구글의 HTTP 기반의 RPC 프로토콜 GRPC

프로그래밍 | 2015.03.31 01:42 | Posted by 조대협


간단한 GRPC 소개



어제 오늘 약간 커뮤니티를 달군 내용 중의 하나가 구글에서 새롭게 발표한 GRPC라는 개념이다.

GRPC는 한마디로 이야기하자면, 예전 자바 RMI나, CORBA의 웹 버전 정도?


RPC란, Remote Procedure Call의 약자로, 원격에 있는 함수를 호출해주는 기능을 이야기 한다.

RPC는 일반적으로, request parameter와 response parameter를 알아야 하기 때문에, 양쪽의 인터페이스 규약을 IDL 등의 언어로 정의한후, 해당 프로그래밍 언어가 부를 수 있는 형태의 코드로 생성을 해줘야 하는데, 이를 Skeleton과 Stub코드라고 한다.


HTTP 기반의 REST가 유행하면서 RPC는 많이 사라 졌는데, 반대로 REST의 경우, 호출 하는 parameter와 응답 값이 명시적이지 않기 때문에, 오류의 여지가 많고 (API 스펙만을 의존, 형 체크등을 안함) JSON을 HTTP를 통해서 쏘기 때문에, 다소 속도가 떨어진다는 단점을 가지고 있다.


그래서 근래에 RPC 개념이 다시 유행하기 시작했는데, 페이스북의 경우에는 Thrift라는 바이너리기반의 RPC 프레임웍을 발표했다. 구글은 RPC 자체는 지원하지 않고, 메세지(JSON등)을 Serialize할 수 있는 프레임웍으로 PB (Protocol Buffer)를 제공해왔는데, GRPC라는 개념으로, PB를 기본으로한 Serizlaizer에 HTTP2를 붙여서 RPC 프레임웍을 릴리즈 하였다.

http://www.grpc.io/


GRPC의 특징 중의 하나는 C/C++  뿐 아니라 자바나 Ruby,node.js,python과 같은 대부분의 모던 프로그래밍 언어를 지원하며, 또한, 요즘 유행하는 MSA (마이크로 서비스 아키텍쳐)와 물려서, RPC를 하나의 서비스로 하여 배포할 수 있는 개념을 가지고 왔다고 해야 할까? MSA와 모던 프로그래밍 언어의 조합은 상당히 매력적이다. 서비스의 개념을 가지고 있는 것만으로도, 잘 서비스화된 서버 시스템을 만들어 낼 수 있으니까는.

이러한 서비스 컨셉은 TP 모니터로 유명한 Tuxedo에 널리 사용되었는데, (그러고보면 10년이 훨 지난 이 제품이 아직도 현대의 많은 개념을 리드하는게 존경 스러울 뿐이다.) 잘 정의된 서비스 정의 프레임웍은 깔끔한 서비스 개발을 보장해주기 때문에, 훨씬 정리된 형태의 MSA 구현이 가능하지 않을까 싶다.


또한 서버 구현체 역시 자바의 경우 Netty를 이용하여, 몇줄 안되는 코드로 고 성능 서버에 서비스를 많지 않은 코딩양으로 구현이 가능하다. 


얼마나 확산이 될지는 지켜봐야 하겠지만, REST의 단방향의 한계를 극복하고, HTTP2 기반의 Streaming을 지원하며, REST대비 빠른 성능을 지원하기 때문에, 충분히 검토해볼만한 가치는 있는 것으로 보인다.

또한 코딩양 역시 Spring Boot 만큼이나 적고 간단해서 경쟁력이 있고, 무엇보다 여러 언어를 동시 지원함으로써 폴리그랏 형태의 개발이 가능하다는 장점은 있지만, 반대로, 네이티브 프로토콜의 한계상, 데이타 포맷 변환이 런타임시 자유롭지 못하고, 중간에 메세지를 열어서 라우팅이나 메디에이션을 하는 API GATEWAY 도입이 어려운 구조이기 때문에, 분명히 한계는 있다.


시간이 될때, 몇가지 샘플을 가지고 테스트 좀 해봐야 할듯

거의 예전 코바 + 턱시도와 컨셉이 같은듯... 장점만 따왔으니 괜찮지 않을까?

'프로그래밍' 카테고리의 다른 글

grpc 설치하기  (0) 2015.04.02
grpc (google rpc)에 대한 분석 #1  (0) 2015.04.01
구글의 HTTP 기반의 RPC 프로토콜 GRPC  (1) 2015.03.31
국내 자바 MVC 프레임웍 사용 현황  (5) 2009.11.11
UML Notation 설명  (0) 2009.04.09
Java Transaction Model  (0) 2009.04.09

Thrift에 대해서 잘 설명해놓은 글 http://thrift-tutorial.readthedocs.org/en/latest/thrift-stack.html

Thrift

RPC 지원

프로그래밍 언어 커버리지가 넓음

TLS 기반의 Secure 프로토콜 지원

Map,List 지원


PB

IDL 정의가 조금 더 직관적

"Serialize/Deserialize 전용 (Message 정의용) :그래서 다른 Transport 프로토콜이 필요함"-다른 Protocol을 통해 Tunneling 함 (HTTP,AMQP,심지어 Thrifit까지,Netty의 경우 확장 플러그인이 있음)

Map,List등을 지원하지 않음