-
Thrift 알아보기BigData 2023. 11. 4. 16:58728x90반응형
- 목차
함께 보면 좋은 글
https://westlife0615.tistory.com/361
소개.
Thrift 는 분산환경 시스템에서 많은 역할을 수행하는 도구입니다.
많은 역할을 수행하다보니 "Thrift 는 바로 이것이다 !" 라고 쉽게 정의를 내리기보단 주요한 역할들을 알아보려고 합니다.
먼저, Thrift 는 RPC 프레임워크로써 동작합니다.
RPC 는 Remote Procedure Call 의 약자인데요.
Remote Procedure Call 은 물리적으로 떨어진 두 서버가 통신하는 행위와 방식을 의미합니다.
HTTP 통신으로 요청을 주고받아도 RPC 이고,
gRPC 와 같은 RPC 의 구현 프로토콜도 존재합니다.
그리고 TCP 소켓을 연결하여 클라이언트와 서버가 데이터를 주고 받아도 이 또한 RPC 라고 부를 수 있습니다.
Thrift 는 분산환경에서 분산 서버들끼리 효율적으로 데이터를 교환하기 위한 방식을 제공합니다.
RPC 로써의 Thrift 는 이어지는 내용에서 알아보도록 하겠습니다.
두번째로 Thrift 는 Serialization/Deserialization 기능을 수행합니다.
Avro, Parquet 등과 같이 Thrift 또한 Serialiation, Deserialization 기능을 가집니다.
Thrift 가 RPC 를 위한 수단이기 때문에 Thrift 는 네트워크 통신에서 사용됩니다.
그리고 네트워크 통신은 Serialization/Deserialization 가 필수입니다.
비트 단위로 데이터가 전달되어야하기 때문이죠.
이 과정에서 효율적으로 직렬화하는 것이 중요한데, Thrift 는 자체적인 Serialization 체계를 가집니다.
그래서 Thrift 를 RPC 의 용도가 아닌 Serialization/Deserialization 의 용도로 사용할 수도 있습니다.
이 또한 이어지는 내용에서 알아보도록 하겠습니다.
Thrift IDL.
Thrift 의 IDL 인 Interface Definition Language 의 약자입니다.
Thrift IDL 은 하나의 파일이며, 파일의 내용으로 Thrift 의 구성요소들이 작성됩니다.
구성요소를 아래와 같습니다.
1. Serialization/Deserialization 할 데이터의 모양
2. RPC 로써 동작한 기능들
Java 로 치면 Class 의 Field 와 Method 들을 정의하는 것과 유사합니다.
Thrift 에서 어떤 데이터 ( Field )를 사용할 것이며, 어떤 기능 ( Method ) 들을 제공해야하는지 정의합니다.
예를 들어보겠습니다.
아래 예시는 Person.thrift 파일이며, 텍스트 기반의 파일입니다.
해당 파일은 Thrift 에서 사용할 데이터와 기능을 정의하는 명세입니다.
Person 이라는 struct 은 Serialization/Deserialization 을 수행하는 데이터 형식입니다.
PersonService 라는 service 는 RPC Function 들이죠.
< IDL 예시 Person.thrift >
namespace java com.example.thrift typedef i32 int struct Person { 1: required string name, 2: optional int age, 3: list<string> email } service PersonService { void create(1: Person person), Person get(1: string name), list<Person> getAll() }
이러한 방식으로 IDL 이 구성되면, 이는 thrift 바이너리 실행 파일에 의해서 활용됩니다.
Mac 에선 아래와 같이 brew 로 설치가 가능합니다.
brew install thrift
그리고 아래와 같은 명령어로 관련된 결과물을 얻을 수 있습니다.
thrift -gen java Person.thrift
결과물은 아래와 같이 Person.java, PersonService.java 파일이 생성됩니다.
ls -al total 224 drwxr-xr-x 4 XXXXXXXX 128 11 4 15:48 . drwxr-xr-x 3 XXXXXXXX 96 11 4 15:48 .. -rw-r--r-- 1 XXXXXXXX 20443 11 4 15:48 Person.java -rw-r--r-- 1 XXXXXXXX 93188 11 4 15:48 PersonService.java
Thrift Compiler.
Thrift Compiler 는 Thrift IDL 파일을 기반으로 소스코드를 생성하는 Thrift 구성요소입니다.
이름그대로 IDL 파일을 컴파일하여 실질적인 소스코드를 생성합니다.
아래 예시처럼
struct 디렉티브로 설정된 Person 이라는 구조는 커스텀 데이터 타입 ( class, struct ) 으로 변형됩니다.
java 의 경우라면 Person Class, Golang 이나 C 같은 경우에는 struct 등이 생성되죠.
service 디렉티브로 설정된 PersonService 또한 소스코드로 변형되는데요.
RPC 통신을 위한 실질적인 기능을 수행할 수 있도록 변형됩니다.
이는 네트워크 스택 위에서 동작하므로 내부적으로 네트워크 통신을 위한 로직들 또한 추상화됩니다.
< IDL 예시 >
struct Person { 1: required string name, 2: optional int age, 3: list<string> email } service PersonService { void create(1: Person person), Person get(1: string name), list<Person> getAll() }
output file 의 언어와 버전은 어떻게 설정하는가?
Thrift Compiler 는 IDL 파일을 기반으로 실제 소스코드를 생성합니다.
생성된 소스코드는 지정된 프로그래밍 언어로 작성됩니다.
아래와 같은 형식으로 프로그래밍 언어와 언어의 버전을 설정할 수 있습니다.
# Generate Java code with Java version 11 thrift -gen java -version 11 Person.thrift # Generate C++ code with C++ version 17 thrift -gen c++ -version 17 Person.thrift # Generate Python code with Python version 3.8 thrift -gen python -version 3.8 Person.thrift # Generate PHP code with PHP version 8.1 thrift -gen php -version 8.1 Person.thrift # Generate Ruby code with Ruby version 3.1 thrift -gen ruby -version 3.1 Person.thrift # Generate Erlang code with Erlang version 25 thrift -gen erlang -version 25 Person.thrift # Generate Perl code with Perl version 5.30 thrift -gen perl -version 5.30 Person.thrift # Generate Haskell code with Haskell version 9.4 thrift -gen haskell -version 9.4 Person.thrift # Generate C# code with C# version 11 thrift -gen csharp -version 11 Person.thrift # Generate Cocoa code with Cocoa version 13.4 thrift -gen cocoa -version 13.4 Person.thrift # Generate JavaScript code with JavaScript version ES2023 thrift -gen js -version ES2023 Person.thrift # Generate Node.js code with Node.js version 18 thrift -gen nodejs -version 18 Person.thrift
examples for javascript version.
아래는 javascript 로 작성된 output 소스코드를 위한 예시입니다.
class 가 없는 javascript 같은 경우에는 output 소스코드가 어떻게 생겼을지 궁금해서 시도해보았습니다.
< IDL & Compile >
cat <<EOF > /tmp/Person.thrift typedef i32 int struct Person { 1: required string name, 2: optional int age, 3: list<string> email } service PersonService { void create(1: Person person), Person get(1: string name), list<Person> getAll() } EOF thrift -gen js -version es6 /tmp/Person.thrift
< JS Thrift 결과물 >
javascript 는 Class 가 없으므로 Person_types.js 라는 파일이 생성되며,
ls -al total 32 drwxr-xr-x 4 ihyeong-ug wheel 128 11 4 16:41 . drwxr-xr-x 5 ihyeong-ug wheel 160 11 4 16:41 .. -rw-r--r-- 1 ihyeong-ug wheel 11309 11 4 16:41 PersonService.js -rw-r--r-- 1 ihyeong-ug wheel 2805 11 4 16:41 Person_types.js
< Person_types.js >
대략 아래와 같은 형식으로 파일이 생성됩니다.
Person = function(args) { this.name = null; this.age = null; this.email = null; if (args) { if (args.name !== undefined && args.name !== null) { this.name = args.name; } else { throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.UNKNOWN, 'Required field name is unset!'); } if (args.age !== undefined && args.age !== null) { this.age = args.age; } if (args.email !== undefined && args.email !== null) { this.email = Thrift.copyList(args.email, [null]); } } }; Person.prototype = {}; Person.prototype.read = function(input) { // 생략 }; Person.prototype.write = function(output) { // 생략 };
a Example for Python.
아래는 python 로 작성된 output 소스코드를 위한 예시입니다.
cat <<EOF > /tmp/Person.thrift struct Person { 1: required string name, 2: optional i32 age, 3: list<string> email } service PersonService { void create(1: Person person), Person get(1: string name), list<Person> getAll() } EOF thrift -gen py /tmp/Person.thrift
< 결과물 구조 >
/gen-py /__init__.py /Person /PersonService-remote /PersonService.py /__init__.py /constants.py /ttypes.py
반응형'BigData' 카테고리의 다른 글
ASCII 코드 알아보기 (2) 2023.12.22 Trino 도커로 따라하기 (0) 2023.12.03 Avro Serialization 알아보기. (0) 2023.10.05 Avro File 알아보기 (0) 2023.10.04 RabbitMQ 에 대해서 (0) 2023.04.09