Открыть сервис

Сериализация данных

Сериализация данных — это процесс преобразования структуры данных (объектов, массивов, записей) в линейную последовательность байтов или строку, пригодную для хранения в файле, передачи по сети или записи в базу данных. Обратный процесс, восстанавливающий исходную структуру, называется десериализацией. Сериализация является фундаментальной концепцией в информатике, обеспечивающей сохранение состояния объектов между сеансами работы программы, обмен данными между различными системами и компонентами, а также взаимодействие распределённых вычислений.

История

Потребность в сериализации возникла с появлением первых компьютерных сетей и многопользовательских систем. В 1960-х годах для передачи данных между мейнфреймами использовались простые текстовые форматы, такие как фиксированные записи. С развитием объектно-ориентированного программирования в 1980-х годах возникла необходимость сохранять не только данные, но и структуру объектов, включая их взаимосвязи.

Одним из первых стандартизированных механизмов сериализации стал формат External Data Representation (XDR), разработанный компанией Sun Microsystems в 1987 году для использования в протоколе удалённого вызова процедур (RPC). В 1990-х годах с распространением языка Java компания Sun ввела встроенную сериализацию объектов (Java Object Serialization), которая автоматически преобразовывала графы объектов в поток байтов. В языке C++ сериализация не была встроенной, но широко использовались библиотеки, такие как Boost.Serialization.

В 2000-х годах с ростом популярности веб-сервисов и микросервисной архитектуры возник спрос на лёгкие, человеко-читаемые форматы. В 2001 году был опубликован стандарт JSON (JavaScript Object Notation), который стал де-факто стандартом для обмена данными в веб-приложениях. В 2004 году появился XML, который, несмотря на свою избыточность, остаётся популярным в корпоративных системах. В 2010-х годах для высокопроизводительных систем были разработаны бинарные форматы, такие как Protocol Buffers (Google, 2008), Apache Avro (2010) и FlatBuffers (Google, 2014).

Классификация

Сериализация данных может быть классифицирована по нескольким признакам.

По типу представления

  • Текстовые форматы: данные преобразуются в строку, читаемую человеком. Примеры: JSON, XML, YAML, CSV. Преимущества — удобство отладки и совместимость с различными системами. Недостатки — больший объём данных по сравнению с бинарными форматами и более низкая скорость обработки.
  • Бинарные форматы: данные преобразуются в последовательность байтов, не предназначенную для непосредственного чтения человеком. Примеры: Protocol Buffers, Avro, MessagePack, Java Serialization, Python pickle. Преимущества — высокая скорость сериализации/десериализации и компактность. Недостатки — сложность отладки и необходимость точного согласования схемы данных.

По способу описания структуры

  • Самодокументируемые форматы: структура данных (схема) встраивается в сериализованный поток вместе с данными. Примеры: XML, JSON (схема может быть описана отдельно, но часто не используется), Avro (схема хранится вместе с данными или в заголовке файла).
  • Форматы с внешней схемой: структура данных описывается отдельно, а сериализованный поток содержит только значения. Примеры: Protocol Buffers (схема описана в .proto-файле), Thrift (схема в .thrift-файле). Это позволяет уменьшить размер данных, но требует синхронизации схемы между отправителем и получателем.

По языковой привязке

  • Языкозависимые: механизмы, встроенные в конкретный язык программирования. Примеры: Java Object Serialization, Python pickle, Ruby Marshal. Они просты в использовании, но создают данные, несовместимые с другими языками.
  • Языконезависимые: форматы, которые могут быть прочитаны и записаны программами на разных языках. Примеры: JSON, XML, Protocol Buffers, Avro. Они обеспечивают интероперабельность, но требуют дополнительных библиотек.

Основные форматы

JSON

JSON (JavaScript Object Notation) — текстовый формат, основанный на синтаксисе литералов объектов JavaScript. Поддерживает четыре примитивных типа (строка, число, логическое значение, null) и два составных (объект — неупорядоченный набор пар «ключ-значение», массив — упорядоченный список). JSON является стандартом ECMA-404 и RFC 8259. Широко используется в REST API, конфигурационных файлах, веб-приложениях. Недостатки: отсутствие поддержки типов данных, таких как дата/время или двоичные данные, и ограниченная поддержка циклических ссылок.

XML

XML (eXtensible Markup Language) — текстовый формат, основанный на тегах. Поддерживает произвольные структуры, атрибуты, пространства имён и схемы (DTD, XSD). XML используется в веб-сервисах (SOAP), конфигурационных файлах (например, в Android-приложениях), документах (SVG, XHTML). Недостатки: избыточность, сложность парсинга и большой объём данных.

Protocol Buffers

Protocol Buffers (protobuf) — бинарный формат, разработанный Google. Данные описываются в .proto-файлах с помощью специального языка описания интерфейсов. Protobuf обеспечивает высокую скорость сериализации и компактность (размер данных в несколько раз меньше, чем JSON). Используется в системах с высокой нагрузкой, таких как Google Search, YouTube, а также в микросервисной архитектуре (gRPC). Недостатки: необходимость компиляции схемы и сложность отладки.

Avro

Apache Avro — бинарный формат, разработанный в рамках проекта Apache Hadoop. Ключевая особенность — схема данных хранится вместе с данными (в заголовке файла или в потоке). Avro поддерживает эволюцию схемы (добавление/удаление полей без нарушения совместимости). Широко используется в системах обработки больших данных (Apache Kafka, Apache Spark). Недостатки: меньшая скорость по сравнению с protobuf.

YAML

YAML (YAML Ain’t Markup Language) — текстовый формат, ориентированный на удобство чтения человеком. Использует отступы для обозначения вложенности. Поддерживает сложные структуры, такие как ссылки и якоря. YAML часто используется в конфигурационных файлах (Docker Compose, Kubernetes, Ansible). Недостатки: сложность парсинга и потенциальные проблемы с безопасностью (возможность выполнения произвольного кода в некоторых реализациях).

Применение

Сериализация данных используется в широком спектре задач:

  • Хранение состояния: сохранение состояния игры, настроек пользователя, кэша данных. Например, игровые движки (Unity, Unreal Engine) используют сериализацию для сохранения прогресса.
  • Сетевое взаимодействие: передача данных между клиентом и сервером, между микросервисами. Например, REST API использует JSON, gRPC — Protocol Buffers.
  • Удалённый вызов процедур (RPC): сериализация аргументов и возвращаемых значений при вызове методов удалённого объекта. Примеры: Java RMI, CORBA, gRPC.
  • Обмен данными между системами: интеграция разнородных систем, обмен данными в формате XML или JSON. Например, в банковской сфере используется ISO 20022 (XML).
  • Хранение в базах данных: сериализация сложных объектов в столбцы типа JSON или BLOB. Например, PostgreSQL поддерживает тип JSONB, MongoDB хранит документы в формате BSON.
  • Кэширование: сериализация объектов для хранения в кэш-системах, таких как Redis или Memcached.

Проблемы и ограничения

  • Циклические ссылки: при сериализации графа объектов, содержащего циклические ссылки, может возникнуть бесконечный цикл. Для решения этой проблемы используются механизмы отслеживания уже сериализованных объектов (например, в Java Serialization) или специальные форматы (например, JSON не поддерживает циклические ссылки, поэтому их необходимо обрабатывать вручную).
  • Безопасность: десериализация данных из ненадёжного источника может привести к выполнению произвольного кода (например, уязвимости в Python pickle или Java Serialization). Рекомендуется использовать безопасные форматы (JSON, Protocol Buffers) и проверять источник данных.
  • Версионирование: при изменении структуры данных (добавление/удаление полей) необходимо обеспечить обратную совместимость. Для этого используются механизмы эволюции схемы (например, в Avro и Protocol Buffers) или версионирование API.
  • Производительность: текстовые форматы (JSON, XML) медленнее бинарных (Protocol Buffers, Avro) и занимают больше места. Для высоконагруженных систем рекомендуется использовать бинарные форматы.

Интересные факты

  • Формат JSON был впервые описан Дугласом Крокфордом в 2001 году. Он был создан как подмножество JavaScript, но быстро стал независимым стандартом.
  • Protocol Buffers используются в Google для хранения данных в Bigtable и для обмена данными между сервисами. В 2008 году Google опубликовал спецификацию и реализацию для нескольких языков.
  • Apache Avro был разработан для решения проблем совместимости схем в Hadoop. Его название происходит от названия британской авиастроительной компании Avro.
  • В языке C# сериализация объектов поддерживается через атрибуты [Serializable] и [DataContract]. В .NET Core также доступен System.Text.Json для работы с JSON.
  • В языке Rust сериализация и десериализация реализуются с помощью крейта serde, который поддерживает множество форматов (JSON, YAML, BSON, MessagePack и другие).

Источники

  • ECMA-404: The JSON Data Interchange Standard
  • RFC 8259: The JavaScript Object Notation (JSON) Data Interchange Format
  • Google Developers: Protocol Buffers Documentation
  • Apache Avro Specification
  • YAML Specification v1.2
  • «Сериализация данных» в курсе «Основы программирования» (Stepik)
  • «Сериализация и десериализация» в документации Microsoft .NET

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →