Poznaj Bond, Microsoft Bond — nowe ramy serializacji danych

Opublikowany: 2022-03-11

Microsoft Bond to nowa platforma serializacji dla danych schematycznych stworzona przez firmę Microsoft.

Przypomnijmy, gdzie serializacja danych jest najczęściej używana:

  • Trwałość danych w plikach, strumieniach, NoSQL i BigData.
  • Transmisja danych w sieciach, IPC itp.

Zwykle aplikacje te mają do czynienia z danymi w schemacie, gdzie schemat oznacza:

  • Struktura: hierarchia, relacje, porządek.
  • Semantyczny: wiek w liczbie lat od urodzenia.

platforma serializacji danych obligacji firmy Microsoft

W rzeczywistości wszystkie dane mają schemat, nawet jeśli są niejawnie zdefiniowane lub obsługiwane przez gotowy język programowania. Jeśli chodzi o złożone struktury danych, kończymy na pisaniu obiektów wspierających transfer danych (DTO) i kodu odpowiedzialnego za IO, często w różnych językach. Gdy tylko rośnie i ewoluuje, utrzymanie wszystkich tych elementów szybko staje się koszmarem. Tutaj wygrywają struktury serializacji.

Przede wszystkim każda struktura serializacji definiuje abstrakcję dla definicji schematu danych, która nie jest powiązana z określonym językiem programowania lub platformą. Ta abstrakcja jest znana jako DSL (język specyficzny dla domeny).

Mając takie DSL możemy zdefiniować schemat danych dla konkretnej aplikacji. Z kolei definicję można wyrazić w wielu formach, ale często struktury serializacji obsługują pojedynczą formę, która jest dobrze dopasowana do jego DSL. Zbyt skomplikowane? Oto jeden dobrze znany przykład: XSD i XML.

XSD definiuje DSL, XML jest (zalecany) do definiowania dokumentów zgodnych ze schematem XSD. Ale możesz również użyć „xsd.exe” do wygenerowania klas DTO zgodnych z XSD, stąd wygenerowane klasy są po prostu inną formą. Zauważ, że możesz wygenerować XML z DTO i na odwrót i będą one semantycznie identyczne, ponieważ semantyka jest wspólna: jest zdefiniowana za pomocą XSD. Podsumowując, struktura serializacji zapewnia DSL, której można używać do definiowania schematów danych w określonym formacie, który jest najlepiej obsługiwany przez daną platformę.

Abstrakcyjny schemat danych zostanie ostatecznie zmaterializowany w zestaw jednostek wyrażonych w języku programowania. Wszystkie struktury serializacji zapewniają specjalne narzędzia zwane generatorami kodu.

Generują cały kod pomocniczy dla docelowych języków programowania, który jest potrzebny klientom do pracy z danymi schematyzowanymi: DTO, proxy itp. Jest to ostatecznie wymagane w przypadku języków z silnym typowaniem, podczas gdy może być opcjonalne w przypadku języków z typami kaczymi (dynamicznymi). .

Ostatnią, ale nie mniej ważną kwestią jest trwałość danych na przewodzie. Rzeczywiste dane zostaną ostatecznie zserializowane do nieprzetworzonych bajtów (lub tekstu) i z powrotem zserializowane.

Wszystkie struktury serializacji danych zapewniają tutaj inną abstrakcję zwaną protokołami. Protokół definiuje zestaw reguł, które definiują sposób serializacji lub deserializacji danych strukturalnych zgodnie z jego schematem. Każdy protokół jest zwykle implementowany dla wszystkich języków programowania i platform obsługiwanych przez daną strukturę serializacji. Im więcej obsługiwanych języków/platform programowania, tym więcej implementacji będzie dostarczać.

Wyobraź sobie, że framework chce obsługiwać protokół JSON, a następnie musi zapewniać czytnik/zapis JSON dla powiedzmy C#, C++, Windows, Linux itp.

Podsumowując: każda nowoczesna platforma serializacji danych zapewnia:

  • Abstrakcje: DSL i protokoły.
  • Narzędzia do generowania kodu.
  • Implementacje protokołów.

Microsoft Bond to nowoczesna platforma serializacji danych. Zapewnia wydajne protokoły DSL i elastyczne, generatory kodu dla C++ i C#, wydajne implementacje protokołów dla systemów Windows, Linux i Mac OS X.

Przez kilka lat Bond pozostawał technologią wyłącznie do użytku wewnętrznego, ale dzięki inicjatywie Microsoft Open Source, Bond został udostępniony na GitHub: Microsoft Bond.

Konkurenci w zakresie serializacji danych

Rywalizacja między gigantami oprogramowania doprowadziła do pojawienia się szeregu platform serializacji:

  • Google Inc. — bufory protokołów Google
  • Facebook Inc. — Thrift, który jest teraz utrzymywany przez Apache
  • Oprogramowanie Apache Foundation — Avro

Oczywiście wszystkie są niezgodne, co jest w porządku, chyba że utworzysz publiczny interfejs API za pomocą jednego z nich.

Każdy z nich ma zalety i wady, więc możesz wybierać spośród nich w zależności od swoich potrzeb.

Dlaczego Bond?

Oficjalna odpowiedź na to pytanie jest tutaj: „Dlaczego Bond”.

Oto krótkie podsumowanie:

  • Bond obsługuje bogaty system typów, w tym generyki.
  • Bond obsługuje wersjonowanie schematu i zgodność dwukierunkową.
  • Bond obsługuje manipulację schematem w czasie wykonywania.
  • Bond obsługuje różne kolekcje: „wektor , mapa , lista ”.
  • Bond obsługuje leniwą serializację z bezpiecznym typem: „bonded”
  • Bond obsługuje protokoły wtykowe (formaty) z marshalingiem i transkodowaniem

Ważną informacją jest to, że Bond postępuje zgodnie ze strategią „płać za grę”. Im więcej funkcji dodasz/użyjesz, tym więcej płacisz za rozmiar i szybkość. Daje to programistom dużą elastyczność.

Bądźmy szczerzy i wymieńmy również wady:

  • Bond jest ukierunkowany na stos Microsoftu z obsługą C++ i C#, ale nie obsługuje Javy (jeszcze).
  • Bond nie obsługuje typu związku („jedenof” w protobuf).

A co z wydajnością?

Jeśli chodzi o porównywanie jednego frameworka do drugiego, programiści często szukają porównań wydajności. Przypomnijmy jednak, że te struktury składają się z DSL, generatorów kodu i protokołów. Jeśli weźmiesz pod uwagę tylko wydajność protokołów, przegapisz funkcje oferowane przez DSL i codegens. Czasami posiadanie lepszego DSL jest o wiele ważniejsze niż kilkuprocentowa różnica w szybkości serializacji.

Oprócz szybkości, ważne może być również kodowanie efektywne w przestrzeni obsługiwane przez niektóre protokoły. Zachęcam do porównania wydajności/przestrzeni z danymi specyficznymi dla Twojej domeny. To jedyny sposób na oszacowanie wszystkich korzyści, jakie możesz uzyskać z określonego frameworka.

wiązanie microsoft

Ten artykuł zawiera projekt demonstracyjny, który demonstruje użycie platformy Bond, odczytując wszystkie rekordy z dziennika zdarzeń aplikacji systemu Windows, serializując je jako obiekty Bond i ponownie je deserializując.

Aby zbudować i uruchomić demo, nie musisz instalować żadnego oprogramowania innego niż Visual Studio.

Korzystanie z Microsoft Bond

Zdobywanie więzi

Sprawdź oficjalny przewodnik na temat zdobywania obligacji na swoją platformę (platformy).

W przypadku projektów .NET jest to tak proste, jak:

 install-package Bond.CSharp

Pakiet zawiera:

  • Generator kodu (gbc.exe) w folderze bin
  • Biblioteki .NET
  • Zadania MSBuild

Przepływ pracy

Przepływ pracy obejmuje następujące kroki:

  • Naucz się DSL i zdefiniuj schemat danych, pisząc plik(i) „.bond”.
  • Użyj generatora kodu („gbc.exe”), aby uzyskać DTO dla swojego języka programowania.
  • Odwołaj się do wygenerowanych plików oraz bibliotek wykonawczych Bond w swoim projekcie.

Rozważ użycie zadań programu MSBuild dostarczonych z platformą, aby zautomatyzować etap generowania kodu.

Przegląd funkcji DSL

Kiedy zaczniesz pisać swój pierwszy plik „.bond”, będziesz musiał znać jego składnię i funkcje. Odwiedź oficjalną stronę dokumentacji opisującą szczegółowo IDL. Przyjrzyjmy się tylko podstawowym funkcjom:

  • Moduły: schemat można podzielić na różne pliki, które są zawarte w instrukcji „import”.
  • Przestrzeń nazw: mają takie samo znaczenie, jak mają C++/C#.
  • Struktury zdefiniowane przez użytkownika: jednostka definicji typu użytkownika.
  • Deklaracja do przodu jest przydatna w przypadku rekurencyjnych struktur danych.
  • Podstawowe typy: „bool, uint8(do 64), int8(do 64), float, double, string, wstring”.
  • Rodzaje kontenerów: „blob, lista , wektor , ustawić , map<K, T>, dopuszczalna ”.
  • Niestandardowe aliasy i mapowanie, np. jeśli chcesz mieć „DateTime” w C#, ale zaznaczenie („int64”) na przewodzie.
  • Atrybuty niestandardowe: przydatne do generowania niestandardowego kodu.

Znudzony? Oto przykład:

 namespace MyProject struct MyRecord { 0: string Name = "Noname"; 1: vector<double> Constants; }

gdzie „0” i „1” to liczby porządkowe pól (mogą być dowolnymi liczbami całkowitymi o dowolnym tempie), a = "Noname" jest (opcjonalną) wartością domyślną.

Generowanie kodu

Framework Bond zapewnia narzędzie do generowania kodu napisane w Haskell. Oto jak wygenerować kod C# i C++ ze schematu „.bond” w wierszu poleceń:

 gbc c# example.bond gbc c++ example.bond

Obsługiwane protokoły (formaty)

Po wyjęciu z pudełka Bond obsługuje trzy rodzaje protokołów:

  • Oznaczone protokoły: „CompactBinary” i „FastBinary”

Otagowane protokoły przeplatają metadane schematu w ładunku. To sprawia, że ​​ładunek samoopisuje się, co pozwala konsumentom na jego interpretację nawet bez znajomości schematu używanego przez producenta.

  • Nieoznakowane protokoły: „SimpleBinary”

Protokoły nieoznakowane serializują tylko dane, a zatem wymagają, aby konsumenci znali schemat ładunku za pośrednictwem jakiegoś mechanizmu pozapasmowego. Protokoły nieoznakowane są często używane w scenariuszach przechowywania, ponieważ pozwalają na jednorazowe przechowywanie schematu (np. w tabeli systemowej w bazie danych), eliminując w ten sposób narzut metadanych z wielu rekordów korzystających z tego samego schematu.

  • Protokoły oparte na DOM: „SimpleJson” i „SimpleXml”

Protokół DOM analizuje cały ładunek do modelu obiektów danych w pamięci, który jest następnie odpytywany podczas deserializacji. Zazwyczaj ten rodzaj protokołu jest używany do implementacji kodowania tekstowego, takiego jak JSON lub XML.

Dla każdego protokołu biblioteka uruchomieniowa Bond zapewnia odpowiednie klasy Reader i Writer, które wykonują zadanie rzeczywistej serializacji.

Korzystanie z protokołów jest dość proste i nieco trudniejsze niż słynne „JsonConvert.SerializeObject()”:

 var record = new MyRecord { Name = "FooBar", Constants = { 3.14, 6.28 } }; var output = new OutputBuffer(); var writer = new CompactBinaryWriter<OutputBuffer>(output); Serialize.To(writer, record); var input = new InputBuffer(output.Data); var reader = new CompactBinaryReader<InputBuffer>(input); record = Deserialize<Example>.From(reader);

Co dalej?

Jeśli kochasz Bonda i masz dużo wolnego czasu na kodowanie, rozważ wykorzystanie jednego z tych elementów do rozwoju. Nie będę wyliczał wszystkich korzyści, jakie możesz uzyskać dzięki wniesieniu wkładu, ale wiem, że wielu programistów szuka pomysłów, do których mógłby się przyczynić:

  • Zaimplementuj port do Javy. Zastąp Javę innymi popularnymi językami do wyboru.
  • Zaimplementuj import/eksport schematu Bond do wymiany z innymi DSL (np. „.proto <=> .bond”).

Cokolwiek zdecydujesz się zrobić w sprawie Bonda, polecam najpierw skontaktować się z Adamem Sapkiem. Jest liderem tego projektu i poprowadzi Cię z tym, czego najbardziej wymaga rynek.