Podczas pracy nad przekształcaniem danych w coś użytecznego, będzie musiało przechodzić pomiędzy różnymi systemami i prawdopodobnie będzie przechowywane w plikach w różnych punktach. Wszystkie te operacje wymagają pewnego rodzaju serializacji, zwłaszcza że różne etapy przetwarzania prawdopodobnie będą wymagać różnych języków i interfejsów API. Gdy masz do czynienia z bardzo dużą liczbą rekordów, wybory dotyczące sposobu ich reprezentowania i przechowywania mogą mieć ogromny wpływ na wymagania dotyczące pamięci i wydajność.
JSON
Chociaż jest to dobrze znane większości programistów internetowych, JSON (JavaScript Object Notation) dopiero niedawno pojawił się jako popularny format przetwarzania danych. Jego największą zaletą jest to, że mapuje ona trywialnie do istniejących struktur danych w większości języków i ma układ, który jest wystarczająco restrykcyjny, aby utrzymać kod parsowania i projekt schematu prosty, ale z wystarczającą elastycznością, aby wyrazić większość danych w dość naturalny sposób. Jego prostota wiąże się jednak z pewnymi kosztami, szczególnie w zakresie wielkości magazynu. Jeśli reprezentujesz listę obiektów odwzorowujących klucze do wartości, najbardziej intuicyjnym sposobem byłoby użycie indeksowanej tablicy tablic asocjacyjnych. Oznacza to, że ciąg znaków każdego klucza jest przechowywany wewnątrz każdego obiektu, co wiąże się z dużą liczbą zduplikowanych ciągów, gdy liczba unikalnych kluczy jest mała w porównaniu do liczby wartości. Oczywiście są na to ręczne sposoby, zwłaszcza że reprezentacje tekstowe zwykle kompresują się dobrze, ale wiele innych podejść do serializacji będę mówić o próbie połączenia elastyczności JSON z mechanizmem przechowywania, który jest bardziej wydajny pod względem przestrzeni.
BSON
Pierwotnie stworzony przez zespół za MongoDB i nadal używany w silniku pamięci, specyfikacja BSON (Binary JSON) może reprezentować dowolny obiekt JSON w postaci binarnej. Co ciekawe, głównym celem projektu nie była wydajność przestrzenna, ale szybkość konwersji. Dużo czasu analizowania można zapisać podczas ładowania i zapisywania, przechowując liczby całkowite i podwójne w ich natywnych reprezentacjach binarnych, a nie jako ciągi tekstowe. Istnieje również natywna obsługa typów, które nie mają odpowiednika w JSON, jak bloby surowych informacji binarnych i dat.
Thrift
Dzięki rozwiązaniu Thrift możesz wstępnie zdefiniować zarówno strukturę obiektów danych, jak i interfejsy, z których będziesz korzystać, aby z nimi współdziałać. System generuje następnie kod do serializacji i deserializacji danych i funkcji pośredniczących, które implementują punkty wejścia do interfejsów. Generuje wydajny kod dla szerokiej gamy języków, a pod maską oferuje wiele opcji bazowego formatu danych bez wpływu na warstwę aplikacji. Okazało się, że jest popularnym językiem IDL (Interface Definition Language) dla projektów infrastruktury Open Source, takich jak Cassandra i HDFS. Jednak dla mniejszych zespołów pracujących przy lekkich projektach może wydawać się nieco przytłaczający. Podobnie jak języki napisane statycznie, użycie predefiniowanego IDL wymaga poświęcenia trochę czasu w zamian za solidną dokumentację, przyszłe zapobieganie błędom i wzrost wydajności. To sprawia, że wybór jest bardzo zależny od oczekiwanego czasu życia i liczby programistów w twoim projekcie.
Avro
Nowszy konkurent do Thrift, a także pod parasolem Apache, Avro oferuje podobne funkcjonalność, ale z bardzo różnymi kompromisami w zakresie projektowania. Nadal definiujesz schemat swoich danych i interfejsów, z których będziesz korzystać, ale zamiast być trzymany osobno w każdym programie, schemat jest przesyłany wraz z danymi. Dzięki temu można napisać kod, który może obsługiwać dowolne struktury danych, a nie tylko typy znane podczas tworzenia programu. Ta elastyczność wiąże się z kosztem przestrzeni i wydajności podczas kodowania i dekodowania informacji. Schematy Avro są definiowane przy użyciu JSON, który może wydawać się nieco nieporęczny w porównaniu do bardziej specyficznych dla domeny IDL, chociaż istnieje eksperymentalna obsługa bardziej przyjaznego dla użytkownika formatu znanego jako Avro IDL.
Bufory protokołów
Stosowanie systemu opartego na otwartych źródłach, którego Google używa wewnętrznie w większości swoich projektów, to stos buforów protokołów to IDL podobny do oszczędzania. Jedną różnicą jest to, że Thrift zawiera kod klienta sieciowego i kod serwera w wygenerowanych stubach, podczas gdy protobuf ogranicza swój zakres do czystego serializowania i deserializacji. Największym wyróżnikiem tych dwóch projektów jest prawdopodobnie ich baza deweloperów. Chociaż kod jest open source, Google jest głównym źródłem i współudziałem w buforowaniu protokołów, podczas gdy Thrift to bardziej klasyczny projekt oparty na tłumie. Jeśli Twoje wymagania skłaniają się ku stabilności i solidnej dokumentacji, bufory protokołów będą atrakcyjne, natomiast jeśli potrzebujesz bardziej otwartego podejścia opartego na społeczności, Thrift będzie o wiele bardziej atrakcyjny.