본문 바로가기
Programming/Communication

Apache Thrift

by 드로니뚜벅이 2022. 12. 5.

Apache Thrift인터페이스 정의 언어이자 이진 통신 프로토콜로서 수많은 언어를 위한 서비스의 정의 및 생성에 사용됩니다. 원격 프로시저 호출(RPC) 프레임워크를 형성하며 페이스북에서 "스케일링이 가능한 언어 간 서비스 개발"을 위해 개발된 것입니다. 크로스 플랫폼 서비스 빌드를 위해 소프트웨어 스택을 코드 생명 엔진과 결합하고 있으며 이로써 C, C++, C#, 코코아, 델파이, 얼랭, Go, 하스켈, 자바, Node.js, 오브젝티브-C, OCaml, 펄, PHP, 파이썬, 루비, 스몰토크를 포함한 다양한 언어와 프레임워크로 작성된 응용 프로그램들을 연결할 수 있습니다. 페이스북에서 개발되었으나 현재는 아파치 소프트웨어 재단의 오픈 소스 프로젝트입니다. 이 구현체는 2007년 4월 페이스북이 출시한 기술 논문에 기술되었으며 현재 아파치에서 호스팅되고 있습니다.

  • 서블릿 제공(org.apache.thrift.server.TServlet)
  • 멀티쓰레드 지원 (org.apache.thrift.server.ThreadPoolServer : worker thread 지정)
  • Async 지원 (org.apache.thrift.server. TNonblockingServer : single threaded)
  • Multi-thread Half-Sync/Half-Async지원 : org.apache.thrift.server. THsHaServer
  • Exception을 제공 (Google Protocol Buffer에는 없는 기능)
  • Set, Map 지원 (Google Protocol Buffer에는 없는 기능)

Apache thrift는 C++로 작성되어 있으나 수많은 언어를 대상으로 코드를 만들 수 있습니다. Thrift 서비스를 만들려면 이를 기술하는 thrift 파일을 작성한 다음 대상 언어로 코드를 생성한 이후 서버 시작을 위한 일부 코드를 작성하고 클라이언트로부터 이 코드를 호출해야 합니다.

 

Thrift는 다양한 프로토콜을 지원합니다.

  • TBinaryProtocol – 간단한 바이너리 형식으로 단순하지만 공간 효율성에 최적화되지 않았습니다. 텍스트 프로토콜보다 처리 속도가 빠르지만 디버그하기는 더 어렵습니다.
  • TCompactProtocol – 보다 컴팩트한 바이너리 형식; 일반적으로 더 효율적으로 처리할 수 있습니다.
  • TJSONProtocol – 데이터 인코딩에 JSON을 사용합니다.
  • TSimpleJSONProtocol – JSON을 사용하여 메타데이터를 삭제하기 때문에 Thrift에서 구문 분석할 수 없는 쓰기 전용 프로토콜입니다. 스크립팅 언어에 의한 구문 분석에 적합합니다.

Thrift가 지원되는 transport는 다음과 같습니다.

  • TSimpleFileTransport – 이 전송은 파일에 씁니다.
  • TFramedTransport – 이 전송은 비차단 서버를 사용할 때 필요합니다. 각 프레임 앞에 길이 정보가 오는 프레임으로 데이터를 보냅니다.
  • TMemoryTransport – I/O에 메모리를 사용합니다. Java 구현은 내부적으로 간단한 ByteArrayOutputStream을 사용합니다.
  • TSocket – 전송을 위해 차단 소켓 I/O를 사용합니다.
  • TZlibTransport – zlib를 사용하여 압축을 수행합니다. 다른 운송 수단과 함께 사용됩니다.

Thrift는 또한 다음과 같은 여러 서버를 제공합니다.

  • TNonblockingServer – 논블로킹 I/O를 사용하는 다중 스레드 서버(Java 구현에서는 NIO 채널 사용). TFramedTransport는 이 서버와 함께 사용해야 합니다.
  • TSimpleServer – 표준 블로킹 I/O를 사용하는 단일 스레드 서버입니다. 테스트에 유용합니다.
  • TThreadedServer - 연결 모델당 스레드와 표준 차단 I/O를 사용하는 다중 스레드 서버입니다.
  • TThreadPoolServer - 스레드 풀과 표준 차단 I/O를 사용하는 다중 스레드 서버입니다.

Thrift를 거치지 않고 빅 데이터 인프라를 배포하는 것은 거의 불가능합니다. 예를 들어 HiveServer2는 Thrift를 사용하여 빌드됩니다. 서비스를 만드는 워크플로는 다음과 같습니다.

  • Thrift의 IDL을 사용하여 정의
  • 원하는 언어로 클라이언트 스텁 생성
  • 서버 스텁 생성 및 구현
  • Thrift 서버를 사용하여 서비스

Thrift를 사용하는 이유

소프트웨어 구조가 복잡해질 경우

아키텍처는 빠르고 유연하며 확장하기 쉽고 단순해야 합니다. 그러나 서비스, 엔드포인트 및 비즈니스 로직이 많을수록 아키텍처가 더 복잡해질 수 있습니다. 여러 가지 디자인 문제가 있습니다.

첫째, 각 엔드포인트에는 Swagger 문서 및 계약 테스트가 필요합니다. API 엔드포인트가 많을수록 더 많은 문서와 테스트를 구현해야 합니다. 예를 들어 최종 사용자를 위한 공개 API와 내부 호출을 위한 단순화된 API를 지원하려면 API를 두 번 작성해야 합니다. 개발자에게 복잡성을 배가시킬 수 있는 다른 요인이 아니라면 관리가 가능할 수 있습니다.

기본 서비스가 각각 다른 언어로 된 여러 다른 서비스에서 호출되는 경우 각 언어에 대한 API SDK, 데이터 모델 및 기타 서비스에 대한 코드를 다시 작성해야 합니다. 이 재작성에는 코드 자체뿐만 아니라 단위 테스트, 문서, 지속적 통합 도구 및 기타 측면도 포함됩니다. 따라서 다국어 지원은 개발팀의 매우 높은 정확성과 주의가 필요합니다.

추가 언어가 복잡성을 추가할 수 있을 뿐만 아니라 동일한 언어의 다른 버전도 복잡성을 추가할 수 있습니다. 이전 버전과의 호환성 문제는 특히 종속성이 많은 경우 세심한 주의가 필요합니다. 또한 한 언어에 대한 라이브러리의 변경 사항을 다른 언어에 대한 라이브러리에서 놓칠 수 있습니다. 따라서 하나의 추가 종속성만으로도 상당한 복잡성이 추가될 수 있습니다.

 

이러한 모든 문제로 인해 변경하려면 상당한 엔지니어 시간이 필요하고 오류가 발생할 위험이 있습니다. 한편, 네트워크에 대한 오버헤드는 관리할 수 있어야 합니다. 각 API 호출에 대해 여러 서비스가 연속적으로 JSON 데이터를 인코딩 및 디코딩하면 부하가 높은 네트워크에 과부하가 걸리기 쉽습니다.

 

데이터를 전송할 경우

여기에서 여러 가지 사항에 유의하십시오. 먼저 요청을 하면 클라이언트는 데이터를 보내기 전에 직렬화해야 합니다. 서버는 데이터를 수신한 후 응답을 보낼 때뿐만 아니라 데이터를 역직렬화해야 합니다.
클라이언트와 서버 간의 상호 작용을 위해 올바른 통신 프로토콜과 데이터 형식을 사용하는 것이 중요합니다. 이상적으로는 데이터가 압축되고 인코딩 및 디코딩이 빨라야 하며 프로토콜이 최적화되어야 합니다.

바이너리 형식은 JSON 형식보다 확실히 더 빠릅니다.

 

바이너리를 사용할 때 문제

원시 바이너리 형식이 실제로 사용하기 더 쉬운지는 논란의 여지가 있습니다. 바이너리 형식의 사용을 용이하게 하려면 데이터에 대한 바이너리 사양을 만들고, 인코딩 및 디코딩 기능을 구현하고, 좋은 디버깅 도구를 개발하고, 좋은 문서를 작성해야 합니다.

API 통신의 성능을 향상시키더라도 다국어 마이크로서비스 통신 문제를 해결해야 합니다. 이것이 RPC가 들어오는 곳입니다. 가능한 솔루션은 데이터 모델을 언어에 구애받지 않는 방식으로 설명하여 각 언어에 대해 동일한 모델을 생성할 수 있도록 하는 것입니다. 이를 위해서는 IDL 또는 인터페이스 정의 언어를 사용해야 합니다. IDL의 데이터 모델 코드는 RPC 호출에 대한 입력으로 사용될 수 있습니다.

즉, 데이터 구조를 지원할 다양한 언어의 RPC 프레임워크도 필요합니다. 스택의 각 언어에 대한 IDL 라이브러리 및 RPC 프레임워크 개발에 대한 대안이 있습니다.

 

gRPC / Thrift 필요성

IDL을 사용하면 마이크로서비스의 통신 문제를 해결할 수 있습니다. IDL을 사용하여 하나의 모델을 만든 다음 코드 생성 도구를 사용하여 비즈니스 논리에 포함될 수 있는 대상 언어 모델을 생성할 수 있습니다. 이것은 다른 언어에서 동일한 모델을 재사용하는 문제를 해결합니다.

또한 좋은 IDL은 문서로 사용하기에 충분히 읽기 쉬우므로 Swagger 및 API 사양이 필요하지 않습니다. RPC 프레임워크를 사용하여 여러 언어에 대한 클라이언트 요청 라이브러리 복제 문제를 해결합니다. 또한 RPC가 REST API보다 훨씬 단순하기 때문에 API도 단순화합니다. RPC 프레임워크를 사용하면 자체 REST 클라이언트를 작성할 필요가 없습니다.

gRPC와 Apache Thrift는 가장 널리 사용되는 두 가지 RPC 솔루션이며 IDL을 기반으로 합니다. 마이크로서비스의 복잡한 네트워크를 관리하는 문제를 해결하는 데 도움이 됩니다.

 

 

참고사이트

 

 

 

'Programming > Communication' 카테고리의 다른 글

ttySx, ttyUSBx, ttyACMx  (0) 2023.08.15
gRPC-web 사용하기  (0) 2022.12.08
D-Bus IPC System  (0) 2022.12.05
MQTT (Message Queue Telemetry Transport): mosquitto  (0) 2022.12.05