Apache Thrift, Google Protocol Buffers, MessagePack, ASN.1 및 Apache Avro의 주요 차이점은 무엇입니까?


124

이들 모두는 이진 직렬화, RPC 프레임 워크 및 IDL을 제공합니다. 나는 그것들과 특징 (성능, 사용 용이성, 프로그래밍 언어 지원)의 주요 차이점에 관심이 있습니다.

다른 유사한 기술을 알고 있다면 답변에 언급하십시오.



@Zenikoder : 해당 링크에는 쿼리 된 형식 5 개 중 2 개에 대한 정보가 없습니다.
그냥 내 정확한 OPINION

그게 도움이 될 수 있습니까 : slideshare.net/IgorAnishchenko/pb-vs-thrift-vs-avro ?
thoroc

2
RPC를 모르는 사람들을 위해-원격 Prodecure Call, IDL-인터페이스 정의 언어
garg10may

답변:


97

ASN.1 은 ISO / ISE 표준입니다. 매우 읽기 쉬운 소스 언어와 바이너리 및 사람이 읽을 수있는 다양한 백엔드가 있습니다. 국제 표준 (그리고 오래된 것입니다!)이기 때문에 소스 언어는 약간 부엌 같지만 (대서양이 약간 젖어있는 것과 거의 같은 방식으로) 매우 잘 지정되어 있고 상당한 지원을받습니다. . (충분히 파고 들고 FFI에서 사용할 수있는 좋은 C 언어 라이브러리가없는 경우 이름을 지정한 모든 언어에 대한 ASN.1 라이브러리를 찾을 수 있습니다.) 이것은 표준화 된 언어이며 집착 적으로 문서화되고 몇 가지 좋은 튜토리얼도 있습니다.

중고품 은 표준이 아닙니다. 원래는 Facebook에서 왔으며 나중에 오픈 소스였으며 현재 최상위 수준의 Apache 프로젝트입니다. 문서화가 잘되어 있지 않습니다. 특히 튜토리얼 레벨에서 제가보기에는 다른 이전의 노력이 아직하지 않은 (그리고 어떤 경우에는 더 나은) 어떤 것도 추가하지 않는 것 같습니다. 공평하게 말하면, 그것은 높은 프로필의 비 주류 언어를 포함하여 즉시 지원하는 다소 인상적인 언어를 가지고 있습니다. IDL도 막연하게 C와 비슷합니다.

프로토콜 버퍼 는 표준이 아닙니다. 더 넓은 커뮤니티에 출시되는 Google 제품입니다. 기본적으로 지원되는 언어 측면에서 약간 제한적이지만 (C ++, Python 및 Java 만 지원) 다른 언어에 대한 타사 지원 (매우 가변적 인 품질)이 많습니다. Google은 프로토콜 버퍼를 사용하여 거의 모든 작업을 수행하므로 전투 테스트를 거친 전투 강화 프로토콜입니다 (ASN.1만큼 전투 강화되지는 않았지만. Thrift보다 훨씬 더 나은 문서를 제공하지만 Google 제품은 불안정 할 가능성이 매우 높습니다 (신뢰할 수 없다는 의미가 아니라 끊임없이 변화하는 의미에서). IDL도 C와 비슷합니다.

위의 모든 시스템은 어떤 종류의 IDL에 정의 된 스키마를 사용하여 인코딩 및 디코딩에 사용되는 대상 언어에 대한 코드를 생성합니다. Avro는 그렇지 않습니다. Avro의 타이핑은 동적이며 해당 스키마 데이터는 런타임에 인코딩 및 디코딩 모두에 직접 사용됩니다 (이는 처리 비용이 분명하지만 동적 언어에 대한 몇 가지 명백한 이점 및 태그 유형이 필요하지 않음 등). . 스키마는 JSON을 사용하므로 이미 JSON 라이브러리가있는 경우 새 언어로 Avro를 지원하는 것이 좀 더 쉬워집니다. 다시 말하지만, 대부분의 바퀴를 재창조하는 프로토콜 설명 시스템과 마찬가지로 Avro도 표준화되지 않았습니다.

개인적으로 내 애정 / 증오 관계에도 불구하고 대부분의 RPC 및 메시지 전송 용도로 ASN.1을 사용할 것입니다. 실제로 RPC 스택이있는 것은 아니지만 (여러분이 만들어야하지만 IOC가이를 만듭니다 충분히 간단합니다).


3
자세한 설명 감사합니다. 하지만 버전 관리는 어떻습니까? protobuf가이를 처리 할 수 ​​있다고 들었습니다. 다른 라이브러리는 어떻습니까? 그리고 어떻게 공통적으로 사용할 수 있습니까? 또한 Avro는 이제 JSON 외에 C와 유사한 구문으로 IDL을 가지고있는 것 같습니다.
andreypopp 2011 년

2
ASN.1은 ...확장 마커를 통한 수동 버전 관리 또는 EXTENSIBILITY IMPLIED모듈 헤더를 통한 자동 버전 관리를 지원합니다 . 프로토콜 버퍼 (IIRC)는 수동 버전 관리를 지원합니다. 묵시적 확장 성과 같은 것을 지원하는지 (그리고 그것을 찾기에는 너무 게으른 지) 모르겠습니다. Thrift는 일부 버전 관리도 지원하지만 묵시적인 확장 성이없는 수동 프로세스라고 생각합니다.
그냥 내 정확한 OPINION

7
레코드의 경우 프로토콜 버퍼는 항상 숫자로 필드를 명시 적으로 인코딩하며, 추가 필드가있는 경우 라이브러리 수준에서 오류가 발생하지 않으며, 누락 된 필드가 선택 또는 명시 적으로 표시되어 있으면 오류가 아닙니다. 따라서 모든 프로토콜 버퍼 메시지에는 EXTENSIBILITY IMPLIED.
Kevin Cathcart 2012

IOC에 의해-당신은 제어 역전을 의미합니까? XML-RPC 확장과 같은 PHP에서 RPC 스택에 대해 무엇을 사용합니까? 아니면 스스로 뭔가를 써야할까요?
Stann

4
Avro는 정의 된 스키마에서 동적으로 작업하거나 상용구 클래스를 생성 할 수 있기 때문에 더 유연합니다. 제 경험상 매우 강력합니다. 그 강점은 RPC 생성기를 포함한 다양한 기능에 있습니다 (Thrift의 공통 기능입니다).
Paolo Maresca 2014

38

우리는 방금 직렬화기에 대한 내부 연구를 수행했습니다. 여기에 몇 가지 결과가 있습니다 (향후 참조 용으로도 사용).

Thrift = 직렬화 + RPC 스택

가장 큰 차이점은 Thrift는 단순한 직렬화 프로토콜이 아니라 현대 SOAP 스택과 같은 완전한 RPC 스택이라는 것입니다. 따라서 직렬화 후 개체 TCP / IP를 통해 시스템간에 전송 될 수 있습니다 (필수 사항은 아님). SOAP에서는 사용 가능한 서비스 (원격 메소드) 및 예상 인수 / 객체를 완전히 설명하는 WSDL 문서로 시작했습니다. 이러한 개체는 XML을 통해 전송되었습니다. Thrift에서 .thrift 파일은 사용 가능한 메서드, 예상 매개 변수 개체를 완전히 설명하며 개체는 사용 가능한 직렬화 기 중 하나를 통해 직렬화됩니다 ( Compact Protocol효율적인 이진 프로토콜을 사용하여 프로덕션에서 가장 많이 사용됨 ).

ASN.1 = 그랜드 아빠

ASN.1은 80 년대 텔레콤에 의해 설계되었으며 CompSci에서 나온 최근 시리얼 라이저에 비해 제한된 라이브러리 지원으로 인해 사용하기 가 어색 합니다. DER (바이너리) 인코딩과 PEM (ascii) 인코딩의 두 가지 변형이 있습니다. 둘 다 빠르지 만 DER는 둘 중 더 빠르고 크기 효율적입니다. 사실 ASN.1 DER는 30 년 동안 설계된 시리얼 라이저를 쉽게 따라 잡을 수 있습니다 (때로는 이길 수 있습니다).그 자체로 잘 설계된 디자인에 대한 증거입니다. 매우 작고 프로토콜 버퍼 및 Thrift보다 작으며 Avro만이 이길 수 있습니다. 문제는 지원할 훌륭한 라이브러리가 있으며 현재 Bouncy Castle은 C # / Java에 가장 적합한 것으로 보입니다. ASN.1은 보안 및 암호화 시스템의 왕이며 사라지지 않을 것이므로 '미래 보장'에 대해 걱정하지 마십시오. 그냥 좋은 라이브러리를 얻으십시오 ...

MessagePack = 팩 중간

나쁘지는 않지만 가장 빠르지도, 가장 작지도, 가장 잘 지원되지도 않습니다. 그것을 선택할 생산 이유가 없습니다.

흔한

그 외에도 상당히 유사합니다. 대부분은 기본 TLV: Type-Length-Value원칙의 변형입니다 .

프로토콜 버퍼 (Google에서 생성됨), Avro (Apache 기반, Hadoop에서 사용됨), Thrift (Facebook에서 생성됨, 현재 Apache 프로젝트) 및 ASN.1 (Telecom에서 생성됨)은 모두 직렬화 기에서 데이터를 처음 표현하는 수준의 코드 생성을 포함합니다. 특정 형식의 경우 직렬 변환기 "컴파일러"가 code-gen단계 를 통해 해당 언어에 대한 소스 코드를 생성합니다 . 그런 다음 앱 소스는 이러한 code-gen클래스를 IO에 사용합니다. 특정 구현 (예 : Microsoft의 Avro 라이브러리 또는 Marc Gavel의 ProtoBuf.NET)을 사용하면 앱 수준 POCO / POJO 개체를 직접 장식 한 다음 라이브러리에서 코드 생성 클래스 대신 이러한 장식 된 클래스를 직접 사용할 수 있습니다. 객체 복사 단계 (애플리케이션 레벨 POCO / POJO 필드에서 코드 생성 필드로)를 제거하므로 성능이 향상되는 것을 확인했습니다.

일부 결과 및 함께 재생할 라이브 프로젝트

이 프로젝트 ( https://github.com/sidshetye/SerializersCompare )는 C # 세계의 중요한 serializer를 비교합니다. 자바 사람들은 이미 비슷한 것을 가지고 있습니다 .

1000 iterations per serializer, average times listed
Sorting result by size
Name                Bytes  Time (ms)
------------------------------------
Avro (cheating)       133     0.0142
Avro                  133     0.0568
Avro MSFT             141     0.0051
Thrift (cheating)     148     0.0069
Thrift                148     0.1470
ProtoBuf              155     0.0077
MessagePack           230     0.0296
ServiceStackJSV       258     0.0159
Json.NET BSON         286     0.0381
ServiceStackJson      290     0.0164
Json.NET              290     0.0333
XmlSerializer         571     0.1025
Binary Formatter      748     0.0344

Options: (T)est, (R)esults, s(O)rt order, (S)erializer output, (D)eserializer output (in JSON form), (E)xit

Serialized via ASN.1 DER encoding to 148 bytes in 0.0674ms (hacked experiment!)

3
ASN.1에는 BER (Basic Encoding Rules), PER (Packed Encoding Rules) 및 XER (XML Encoding Rules)도 있습니다. DER는 각 데이터에 대해 고유 한 인코딩을 보장하기 때문에 주로 암호화에 사용되는 BER의 변형입니다. BER과 PER 모두 DER보다 더 효율적일 수 있습니다. 대부분의 라이브러리는 DER을 처리합니다. 일부는 모든 BER 구성을 올바르게 처리하지 않습니다. 자세한 내용을 알고 싶은 분들을 위해 : luca.ntop.org/Teaching/Appunti/asn1.html
Joe Steele

JER (JavaScript Object Notation Encoding Rules)도 있습니다. ECN (Encoding Control Notation)을 사용하여 고유 한 인코딩 규칙을 정의 할 수도 있습니다. 다운로드 링크가있는 좋은 사양 목록 : oss.com/asn1/resources/standards-define-asn1.html
Dmitry

There are two variants, DER (binary) encoding and PEM (ascii) encoding. PEM은 BEGIN END 주석 안에있는 base-64로 인코딩 된 바이너리 데이터 일뿐입니다. 이 바이너리 데이터는 DER 인코딩을 사용하여 생성되었을 수 있으므로 PEM과 DER를 비교하는 것이 이상합니다.
RafalS

14

성능 관점에 추가하여 Uber는 최근 엔지니어링 블로그에서 다음과 같은 여러 라이브러리를 평가했습니다.

https://eng.uber.com/trip-data-squeeze/

그들을위한 승자? 압축을위한 MessagePack + zlib

우리의 목표는 인코딩 프로토콜과 압축 알고리즘의 조합을 가장 빠른 속도로 가장 압축 된 결과로 찾는 것이 었습니다. 우리는 Uber New York City (JSON으로 텍스트 파일에 넣음)에서 2,219 개의 의사 난수 익명 여행에 대해 인코딩 프로토콜 및 압축 알고리즘 조합을 테스트했습니다.

여기서 교훈은 귀하의 요구 사항이 귀하에게 적합한 라이브러리를 결정한다는 것입니다. Uber의 경우 메시지 전달의 스키마없는 특성으로 인해 IDL 기반 프로토콜을 사용할 수 없었습니다. 이것은 많은 옵션을 제거했습니다. 또한 그들에게는 원시 인코딩 / 디코딩 시간뿐만 아니라 저장된 데이터의 크기도 중요합니다.

크기 결과

크기 결과

속도 결과

여기에 이미지 설명 입력


13

ASN.1의 가장 큰 점은 ist가 구현이 아닌 사양을 위해 설계되었다는 것입니다. 따라서 "실제"프로그래밍 언어에서 구현 세부 사항을 숨기거나 무시하는 데 매우 유용합니다.

ASN.1-Compiler가 인코딩 규칙을 asn1- 파일에 적용하고 두 실행 코드에서 생성하는 작업입니다. 인코딩 규칙은 ECN (EnCoding Notation)으로 제공되거나 BER / DER, PER, XER / EXER과 같은 표준화 된 규칙 중 하나 일 수 있습니다. 즉, ASN.1은 유형 및 구조이고 인코딩 규칙은 유선 인코딩을 정의하며 마지막으로 컴파일러는이를 프로그래밍 언어로 전송합니다.

무료 컴파일러는 내가 아는 한 C, C ++, C #, Java 및 Erlang을 지원합니다. (비싸고 특허 / 라이센스를 많이 사용하는) 상용 컴파일러는 매우 다재다능하며 일반적으로 절대적으로 최신이며 때로는 더 많은 언어를 지원하지만 사이트 (OSS Nokalva, Marben 등)를 참조하십시오.

이 기술을 사용하여 완전히 다른 프로그래밍 문화의 당사자 (예 : "내장 된"사람과 "서버 농부") 간의 인터페이스를 지정하는 것은 놀랍도록 쉽습니다. asn.1- 파일, 인코딩 규칙 (예 : BER 및 예 : UML 상호 작용 다이어그램) . 구현 방법에 대해 걱정할 필요가 없습니다. 모두가 "자신의 것"을 사용하게하십시오! 나를 위해 그것은 아주 잘 작동했습니다. Btw .: OSS Nokalva의 사이트에서 ASN.1에 대한 무료 다운로드 책을 두 개 이상 찾을 수 있습니다 (하나는 Larmouth, 다른 하나는 Dubuisson).

IMHO의 대부분의 다른 제품은 직렬화 문제로 많은 공기를 펌핑하는 또 다른 RPC 스텁 생성기 일뿐입니다. 글쎄요, 필요하다면 괜찮을 수도 있습니다. 하지만 나에게 그들은 Sun-RPC의 재발 명 (80 세기 후반부터)처럼 보이지만, 그것도 잘 작동했습니다.


7

Microsoft의 Bond ( https://github.com/Microsoft/bond )는 성능, 기능 및 문서에서 매우 인상적입니다. 그러나 현재 (2015 년 2 월 13 일) 현재 많은 대상 플랫폼을 지원하지 않습니다. 나는 그것이 매우 새롭기 때문이라고 추측 할 수 있습니다. 현재 python, c # 및 c ++ 지원합니다. MS가 모든 곳에서 사용하고 있습니다. 나는 본드를 사용하는 ac # 개발자가 protobuf를 사용하는 것보다 낫기 때문에 그것을 시도했지만, 중고품도 사용했고, 내가 직면 한 유일한 문제는 문서에 관한 것이었고, 어떻게 일이 수행되는지 이해하기 위해 많은 것을 시도해야했습니다.

Bond의 리소스는 다음과 같습니다 ( https://news.ycombinator.com/item?id=8866694 , https://news.ycombinator.com/item?id=8866848 , https://microsoft.github.io/ bond / why_bond.html )


5

성능 측면에서 하나의 데이터 포인트는 jvm-serializers 벤치 마크입니다. 매우 구체적이고 작은 메시지이지만 Java 플랫폼을 사용하는 경우 도움이 될 수 있습니다. 일반적으로 성능이 가장 중요한 차이는 아닐 것이라고 생각합니다. 또한 저자의 말을 복음으로 받아들이지 마십시오. 광고 된 많은 클레임은 가짜입니다 (예를 들어 msgpack 사이트에는 일부 모호한 클레임이 있습니다. 빠를 수 있지만 정보는 매우 개략적이며 사용 사례는 그리 현실적이지 않습니다).

한 가지 큰 차이점은 스키마를 사용해야하는지 여부입니다 (적어도 PB, Thrift, Avro는 선택 사항 일 수 있음, ASN.1도 생각합니다. MsgPack, 반드시 그런 것은 아닙니다).

또한 : 제 생각에는 계층화 된 모듈 식 디자인을 사용할 수있는 것이 좋습니다. 즉, RPC 계층은 데이터 형식, 직렬화를 지시해서는 안됩니다. 불행히도 대부분의 후보자는 이들을 단단히 묶습니다.

마지막으로, 데이터 형식을 선택할 때 오늘날 성능은 텍스트 형식의 사용을 배제하지 않습니다. 엄청나게 빠른 JSON 파서 (그리고 매우 빠른 스트리밍 xml 파서)가 있습니다. 스크립팅 언어의 상호 운용성과 사용 편의성을 고려할 때 바이너리 형식과 프로토콜이 최선의 선택이 아닐 수 있습니다.


경험을 공유 해주셔서 감사합니다.하지만 여전히 바이너리 형식이 필요하고 (정말 방대한 양의 데이터가 있습니다) 아마도 Avro를 고수 할 것입니다.
andreypopp 2011 년

그럼 말이 되겠네요. 사용할 형식에 관계없이 압축을 사용하고 싶을 수 있습니다 (LZF는 gzip / deflate에 비해 압축 / 압축 해제가 매우 빠르기 때문에 좋습니다).
StaxMan 2011 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.