Wszystkie zapewniają serializację binarną, struktury RPC i IDL. Interesują mnie kluczowe różnice między nimi oraz ich cechy (wydajność, łatwość obsługi, obsługa języków programowania).
Jeśli znasz inne podobne technologie, podaj je w odpowiedzi.
Wszystkie zapewniają serializację binarną, struktury RPC i IDL. Interesują mnie kluczowe różnice między nimi oraz ich cechy (wydajność, łatwość obsługi, obsługa języków programowania).
Jeśli znasz inne podobne technologie, podaj je w odpowiedzi.
Odpowiedzi:
ASN.1 to standard ISO / ISE. Ma bardzo czytelny język źródłowy i różnorodne zaplecze, zarówno binarne, jak i czytelne dla człowieka. Będąc międzynarodowym standardem (i to starym!), Język źródłowy jest nieco zlewozmywakowy (mniej więcej w taki sam sposób, w jaki Ocean Atlantycki jest trochę mokry), ale jest bardzo dobrze określony i ma przyzwoitą ilość wsparcia . (Prawdopodobnie możesz znaleźć bibliotekę ASN.1 dla dowolnego języka, który nazwiesz, jeśli będziesz wystarczająco mocno kopać, a jeśli nie, są dostępne dobre biblioteki języka C, których możesz używać w FFI.) Jest to język ustandaryzowany, obsesyjnie udokumentowany i ma również kilka dobrych samouczków.
Oszczędność nie jest standardem. Pochodzi z Facebooka, a później był open-source i obecnie jest projektem Apache najwyższego poziomu. Nie jest to dobrze udokumentowane - zwłaszcza poziomy samouczków - i moim (wprawdzie krótkim) spojrzeniem nie wydaje się dodawać niczego, czego inne poprzednie wysiłki jeszcze nie robią (aw niektórych przypadkach lepsze). Aby być uczciwym, ma dość imponującą liczbę języków, które obsługuje po wyjęciu z pudełka, w tym kilka bardziej znanych języków spoza głównego nurtu. IDL jest również nieco podobny do C.
Bufory protokołów nie są standardem. Jest to produkt Google, który jest udostępniany szerszej społeczności. Jest nieco ograniczony pod względem języków obsługiwanych po wyjęciu z pudełka (obsługuje tylko C ++, Python i Java), ale ma wiele wsparcia dla innych języków (o bardzo zmiennej jakości). Google prawie całą swoją pracę wykonuje przy użyciu buforów protokołów, więc jest to sprawdzony w boju, zahartowany w boju protokół (choć nie tak zahartowany w boju jak ASN.1. Ma znacznie lepszą dokumentację niż Thrift, ale będąc Produkt Google, jest wysoce prawdopodobne, że będzie niestabilny (w sensie ciągłych zmian, a nie zawodności). IDL jest również podobny do C.
Wszystkie powyższe systemy używają schematu zdefiniowanego w pewnego rodzaju IDL do generowania kodu dla języka docelowego, który jest następnie używany do kodowania i dekodowania. Avro tego nie robi. Pisanie Avro jest dynamiczne, a jego dane schematu są używane bezpośrednio w czasie wykonywania zarówno do kodowania, jak i dekodowania (co ma pewne oczywiste koszty przetwarzania, ale także pewne oczywiste korzyści w porównaniu z dynamicznymi językami i brakiem potrzeby znakowania typów itp.) . Jego schemat wykorzystuje JSON, co sprawia, że obsługa Avro w nowym języku jest nieco łatwiejsza w zarządzaniu, jeśli istnieje już biblioteka JSON. Ponownie, podobnie jak w przypadku większości systemów opisu protokołów opracowanych na nowo, Avro również nie jest znormalizowany.
Osobiście, pomimo mojej relacji miłości / nienawiści, prawdopodobnie użyłbym ASN.1 do większości celów RPC i transmisji wiadomości, chociaż tak naprawdę nie ma stosu RPC (musiałbyś go stworzyć, ale MKOl to robi wystarczająco proste).
...
znaczników rozszerzeń lub automatyczne EXTENSIBILITY IMPLIED
w nagłówku modułu. Bufory protokołów, IIRC, obsługują ręczne przechowywanie wersji. Nie wiem, czy obsługuje coś takiego, jak domniemana rozszerzalność (i jestem zbyt leniwy, aby to sprawdzić). Oszczędność obsługuje również niektóre wersje, ale ponownie wydaje mi się, że jest to proces ręczny bez domniemanej rozszerzalności.
EXTENSIBILITY IMPLIED
.
Właśnie przeprowadziliśmy wewnętrzne badanie dotyczące serializatorów, oto kilka wyników (również do mojego przyszłego odniesienia!)
Największą różnicą jest to, że Thrift to nie tylko protokół serializacji, to pełny stos RPC, który przypomina współczesny stos SOAP. Zatem po serializacji obiekty mogą (ale nie wymagane) być przesyłane między maszynami przez TCP / IP. W SOAP rozpoczęto od dokumentu WSDL, który w pełni opisuje dostępne usługi (metody zdalne) i oczekiwane argumenty / obiekty. Obiekty te zostały przesłane przez XML. W Thrift plik .thrift w pełni opisuje dostępne metody, oczekiwane obiekty parametrów, a obiekty są serializowane za pomocą jednego z dostępnych serializatorów (z Compact Protocol
wydajnym protokołem binarnym, najbardziej popularnym w produkcji).
ASN.1 został zaprojektowany przez ludzi z branży telekomunikacyjnej w latach 80-tych i jest niewygodny w użyciu z powodu ograniczonej obsługi bibliotek w porównaniu do ostatnich serializatorów, które pojawiły się w CompSci. Istnieją dwa warianty, kodowanie DER (binarne) i kodowanie PEM (ascii). Oba są szybkie, ale DER jest szybszy i bardziej efektywny pod względem rozmiaru. W rzeczywistości ASN.1 DER może z łatwością nadążyć (a czasem pokonać) serializatory, które zostały zaprojektowane od 30 latsama w sobie jest świadectwem dobrze zaprojektowanego projektu. Jest bardzo kompaktowy, mniejszy niż bufory protokołu i oszczędność, pokonany tylko przez Avro. Problemem jest posiadanie wspaniałych bibliotek do obsługi i obecnie Bouncy Castle wydaje się być najlepszym rozwiązaniem dla C # / Java. ASN.1 jest królem zabezpieczeń i systemów kryptograficznych i nie zniknie, więc nie martw się o „przyszłe zabezpieczenia”. Po prostu zdobądź dobrą bibliotekę ...
Nie jest zły, ale nie jest ani najszybszy, ani najmniejszy, ani najlepiej obsługiwany. Nie ma powodu produkcyjnego, aby go wybrać.
Poza tym są dość podobne. Większość z nich to warianty podstawowej TLV: Type-Length-Value
zasady.
Bufory protokołów (pochodzące z Google), Avro (oparte na Apache, używane w Hadoop), Thrift (pochodzące z Facebooka, obecnie projekt Apache) i ASN.1 (pochodzące z Telecom) - wszystkie obejmują pewien poziom generowania kodu, w którym najpierw wyrażasz swoje dane w serializatorze -specyficznym formacie, wtedy "kompilator" serializatora wygeneruje kod źródłowy dla twojego języka poprzez code-gen
fazę. Twoje źródło aplikacji następnie używa tych code-gen
klas na potrzeby IO. Zwróć uwagę, że niektóre implementacje (np. Biblioteka Avro firmy Microsoft lub ProtoBuf.NET Marca Gavela) umożliwiają bezpośrednie dekorowanie obiektów POCO / POJO na poziomie aplikacji, a następnie biblioteka bezpośrednio używa tych ozdobionych klas zamiast klas kodu genowego. Widzieliśmy, że oferuje to zwiększenie wydajności, ponieważ eliminuje etap kopiowania obiektu (z pól POCO / POJO na poziomie aplikacji do pól generowania kodu).
Ten projekt ( https://github.com/sidshetye/SerializersCompare ) porównuje ważne serializatory w świecie C #. Ludzie z Java mają już coś podobnego .
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!)
There are two variants, DER (binary) encoding and PEM (ascii) encoding
. Należy pamiętać, że PEM to po prostu dane binarne zakodowane w formacie base-64 wewnątrz komentarzy BEGIN END. Te dane binarne mogły zostać wygenerowane przy użyciu kodowania DER, więc dziwne jest porównywanie PEM i DER.
Dodając perspektywę wydajności, Uber niedawno ocenił kilka z tych bibliotek na swoim blogu inżynieryjnym:
https://eng.uber.com/trip-data-squeeze/
Zwycięzca dla nich? MessagePack + zlib do kompresji
Naszym celem było znalezienie kombinacji protokołu kodowania i algorytmu kompresji z najbardziej kompaktowym wynikiem przy największej szybkości. Przetestowaliśmy kombinacje protokołów kodowania i algorytmów kompresji podczas 2219 pseudolosowych anonimowych podróży z Ubera w Nowym Jorku (umieszczonych w pliku tekstowym jako JSON).
Lekcja jest taka, że to Twoje wymagania decydują o wyborze odpowiedniej biblioteki. W przypadku Ubera nie mogli używać protokołu opartego na IDL ze względu na pozbawiony schematu charakter przekazywania wiadomości. To wyeliminowało wiele opcji. Również dla nich liczy się nie tylko czas surowego kodowania / dekodowania, ale także rozmiar danych w spoczynku.
Wyniki rozmiaru
Wyniki prędkości
Jedną wielką rzeczą w ASN.1 jest to, że jest on zaprojektowany dla specyfikacji, a nie implementacji. Dlatego bardzo dobrze ukrywa / ignoruje szczegóły implementacji w każdym „prawdziwym” języku programowania.
Zadaniem kompilatora ASN.1 jest zastosowanie reguł kodowania do pliku asn1 i wygenerowanie z obu z nich kodu wykonywalnego. Reguły kodowania mogą być podane w notacji kodowania (ECN) lub mogą być jedną z ustandaryzowanych, takich jak BER / DER, PER, XER / EXER. Czyli ASN.1 to Typy i Struktury, Reguły Kodowania definiują kodowanie na kablu, a co nie mniej ważne, Kompilator przenosi je do twojego języka programowania.
Darmowe kompilatory obsługują C, C ++, C #, Java i Erlang zgodnie z moją wiedzą. Komercyjne kompilatory (bardzo drogie i oparte na patentach / licencjach) są bardzo wszechstronne, zwykle absolutnie aktualne i obsługują czasami nawet więcej języków, ale zobacz ich strony (OSS Nokalva, Marben itp.).
Zaskakująco łatwo jest określić interfejs między stronami o zupełnie różnych kulturach programowania (np. "Osadzeni" ludzie i "rolnicy serwerów") przy użyciu tych technik: plik asn.1, zasada kodowania np. BER i np. Diagram interakcji UML . Nie martw się, jak to jest zaimplementowane, niech wszyscy używają „swoich rzeczy”! U mnie to działa bardzo dobrze. Przy okazji: Na stronie OSS Nokalva można znaleźć co najmniej dwie darmowe książki o ASN.1 (jedną autorstwa Larmouth, a drugą Dubuissona).
Większość innych produktów IMHO stara się być tylko kolejnymi generatorami odgałęzień RPC, pompując dużo powietrza do problemu serializacji. Cóż, jeśli tego potrzeba, może być dobrze. Ale dla mnie wyglądają jak nowe wynalazki Sun-RPC (z końca lat 80-tych), ale hej, to też działało dobrze.
Microsoft Bond ( https://github.com/Microsoft/bond ) jest imponujący pod względem wydajności, funkcjonalności i dokumentacji. Jednak obecnie nie obsługuje wielu platform docelowych (13 lutego 2015 r.). Mogę tylko przypuszczać, że to dlatego, że jest bardzo nowy. obecnie obsługuje Python, C # i C ++. Jest używany przez stwardnienie rozsiane wszędzie. Wypróbowałem to, dla mnie jako programisty ac # używanie bond jest lepsze niż używanie protobuf, jednak użyłem też oszczędności, jedyny problem, z jakim miałem do czynienia, dotyczył dokumentacji, musiałem spróbować wielu rzeczy, aby zrozumieć, jak się wszystko dzieje.
Niewiele zasobów na temat Bond jest następujących ( https://news.ycombinator.com/item?id=8866694 , https://news.ycombinator.com/item?id=8866848 , https://microsoft.github.io/ bond / why_bond.html )
Jeśli chodzi o wydajność, jednym punktem danych jest test porównawczy jvm-serializerów - są to dość specyficzne, małe komunikaty, ale mogą pomóc, jeśli używasz platformy Java. Myślę, że generalnie wydajność często nie będzie najważniejszą różnicą. Ponadto: NIGDY nie traktuj słów autorów jako ewangelii; wiele reklamowanych twierdzeń jest fałszywych (na przykład witryna msgpack zawiera podejrzane twierdzenia; może być szybka, ale informacje są bardzo pobieżne, a przypadek użycia niezbyt realistyczny).
Jedną dużą różnicą jest to, czy należy użyć schematu (PB, przynajmniej Thrift; Avro może być opcjonalny; myślę, że ASN.1 również; MsgPack, niekoniecznie).
Poza tym: moim zdaniem dobrze jest móc korzystać z warstwowej, modułowej konstrukcji; to znaczy warstwa RPC nie powinna dyktować formatu danych, serializacji. Niestety większość kandydatów ściśle je łączy.
Wreszcie, przy wyborze formatu danych, dzisiejsza wydajność nie wyklucza stosowania formatów tekstowych. Istnieją niesamowicie szybkie parsery JSON (i całkiem szybkie parsery strumieniowe XML); a biorąc pod uwagę interoperacyjność z języków skryptowych i łatwość użycia, formaty i protokoły binarne mogą nie być najlepszym wyborem.