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

Сериализация

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

История

Первые концепции сериализации возникли в 1960-х годах с развитием систем управления базами данных и сетевых протоколов. В ранних языках программирования, таких как COBOL и FORTRAN, данные могли записываться в файлы в виде последовательных записей фиксированной длины. Однако настоящий прорыв произошёл в 1980-х годах с появлением объектно-ориентированного программирования. Язык Smalltalk ввёл понятие «сериализация» как стандартный механизм для сохранения и восстановления объектов. В 1990-х годах сериализация стала неотъемлемой частью распределённых систем, таких как CORBA (Common Object Request Broker Architecture) и Java RMI (Remote Method Invocation). С развитием веб-технологий в 2000-х годах появились текстовые форматы сериализации, такие как JSON и XML, которые стали стандартом для обмена данными между веб-сервисами.

Цели и применение

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

  • Долговременное хранение (персистентность): сохранение состояния объекта или структуры данных в файл или базу данных для последующего восстановления. Например, сохранение настроек приложения, игровых профилей или результатов вычислений.
  • Передача по сети: преобразование объекта в последовательность байтов для отправки по сети между различными узлами распределённой системы. Это лежит в основе многих протоколов, таких как HTTP, gRPC, WebSocket.
  • Кеширование и репликация: сериализованные данные могут быть легко скопированы или перемещены между серверами для повышения производительности или отказоустойчивости.
  • Межпроцессное взаимодействие (IPC): обмен данными между различными процессами на одной машине, например, через сокеты или разделяемую память.
  • Взаимодействие между разными языками программирования: сериализация в стандартный формат (например, JSON или Protobuf) позволяет программам, написанным на разных языках, обмениваться данными.

Форматы сериализации

Форматы сериализации делятся на две основные категории: текстовые (человекочитаемые) и бинарные (компактные и быстрые).

Текстовые форматы

  • JSON (JavaScript Object Notation): легковесный, основанный на синтаксисе JavaScript. Широко используется в веб-API, конфигурационных файлах и хранении данных. Поддерживает числа, строки, логические значения, массивы и объекты. Пример: {"name": "Иван", "age": 30}.
  • XML (eXtensible Markup Language): более строгий и расширяемый формат, использующий теги и атрибуты. Применяется в SOAP-веб-сервисах, конфигурационных файлах (например, .NET, Android) и документах. Пример: <person><name>Иван</name><age>30</age></person>.
  • YAML (YAML Ain’t Markup Language): формат, ориентированный на читаемость, с использованием отступов. Часто используется в конфигурационных файлах (например, Docker Compose, Kubernetes, Ansible). Пример: name: Иван age: 30.

Бинарные форматы

  • Protocol Buffers (protobuf): разработан Google. Обеспечивает высокую скорость и компактность. Требует предварительного описания структуры данных в файле .proto. Используется в gRPC, системах хранения и передачи данных.
  • Apache Avro: формат, популярный в экосистеме Hadoop. Использует JSON для описания схемы и бинарное кодирование для данных. Поддерживает эволюцию схемы.
  • MessagePack: компактный бинарный аналог JSON. Позволяет сериализовать данные в формате, похожем на JSON, но более эффективном по размеру.
  • BSON (Binary JSON): используется в MongoDB. Расширяет JSON дополнительными типами данных, такими как даты и бинарные массивы.
  • FlatBuffers: разработан Google для игр и приложений, где критична скорость доступа к данным без полной десериализации.

Специфичные для языков форматы

  • Java Serialization: встроенный механизм Java, который автоматически сериализует объекты, реализующие интерфейс Serializable. Удобен, но медленен и небезопасен.
  • Python Pickle: модуль Python для сериализации объектов. Поддерживает практически любые типы данных, но также небезопасен при работе с непроверенными данными.
  • Ruby Marshal: встроенный механизм Ruby для сериализации объектов.

Классификация по типам

  • Внутренняя сериализация: используется внутри одной программы или системы, часто в форматах, специфичных для языка (например, Java Serialization, Pickle).
  • Внешняя сериализация: предназначена для обмена данными между различными системами или языками. Использует стандартизированные форматы (JSON, XML, Protobuf, Avro).
  • Сериализация с сохранением графа объектов: поддерживает циклические ссылки и сложные структуры данных (например, Pickle, Java Serialization).
  • Сериализация с сохранением типов: сохраняет информацию о типе объекта, что позволяет восстановить его с точным соответствием (например, Pickle, Java Serialization).
  • Сериализация с эволюцией схемы: позволяет изменять структуру данных со временем, сохраняя обратную совместимость (например, Protobuf, Avro, Thrift).

Принципы работы

Процесс сериализации обычно включает следующие этапы:

  1. Анализ структуры: сериализатор анализирует объект или структуру данных, определяя её поля, их типы и значения.
  2. Преобразование: каждое поле преобразуется в последовательность байтов или символов в соответствии с правилами выбранного формата.
  3. Упаковка: все преобразованные части объединяются в единый поток данных, возможно, с добавлением метаданных (например, длины полей, маркеров начала/конца).
  4. Запись/передача: полученный поток данных записывается в файл, передаётся по сети или сохраняется в памяти.

Десериализация выполняет обратные действия: читает поток данных, интерпретирует его в соответствии с форматом и восстанавливает исходную структуру данных или объект.

Критика и ограничения

  • Безопасность: десериализация непроверенных данных может привести к уязвимостям, таким как удалённое выполнение кода (RCE). Особенно это касается форматов, которые восстанавливают произвольные объекты (например, Pickle, Java Serialization). Рекомендуется использовать безопасные форматы (JSON, Protobuf) или проверять данные перед десериализацией.
  • Производительность: текстовые форматы (JSON, XML) могут быть медленнее и занимать больше места, чем бинарные. Для высоконагруженных систем часто выбирают Protobuf или Avro.
  • Эволюция схемы: при изменении структуры данных может потребоваться поддержка обратной совместимости. Некоторые форматы (например, Java Serialization) плохо справляются с этим, что может привести к ошибкам при восстановлении старых данных.
  • Сложность отладки: бинарные форматы сложнее читать и отлаживать, чем текстовые. Для них требуются специальные инструменты для просмотра содержимого.
  • Зависимость от языка: встроенные механизмы сериализации (Java, Python) привязывают данные к конкретному языку, что затрудняет межъязыковое взаимодействие.

Примеры использования

  • Веб-API: REST API возвращает данные в формате JSON или XML. Например, сервер отправляет клиенту JSON-объект с информацией о пользователе.
  • Базы данных: документные базы данных (MongoDB) хранят данные в BSON. Реляционные базы данных могут использовать сериализацию для хранения сложных типов (например, JSON-поля в PostgreSQL).
  • Кеширование: Redis часто хранит сериализованные объекты (например, в формате JSON или MessagePack) для быстрого доступа.
  • Удалённый вызов процедур (RPC): gRPC использует Protobuf для сериализации запросов и ответов между клиентом и сервером.
  • Конфигурационные файлы: приложения часто используют YAML или JSON для хранения настроек, которые загружаются и десериализуются при запуске.
  • Игровые движки: Unity и Unreal Engine используют сериализацию для сохранения игровых сцен, состояний объектов и настроек.

Источники

  • Гамма Э., Хелм Р., Джонсон Р., Влиссидес Дж. «Приёмы объектно-ориентированного проектирования. Паттерны проектирования». — СПб.: Питер, 2020.
  • Мартин Р. «Чистая архитектура. Искусство разработки программного обеспечения». — СПб.: Питер, 2019.
  • Фаулер М. «Архитектура корпоративных программных приложений». — М.: Вильямс, 2006.
  • Документация Protocol Buffers (Google Developers).
  • Документация Apache Avro.
  • Спецификация JSON (ECMA-404).
  • Спецификация YAML (yaml.org).

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

На главную BFOmetr →