Сериализация
Сериализация — в информатике это процесс преобразования структуры данных или состояния объекта в последовательную форму (обычно в виде потока байтов или строки), пригодную для сохранения в файл, передачи по сети или хранения в базе данных. Обратный процесс — восстановление объекта из последовательной формы — называется десериализацией (или демаршализацией). Сериализация позволяет сохранять и восстанавливать сложные структуры данных, передавать объекты между различными программами или компонентами системы, а также обеспечивать долговременное хранение состояния приложения.
История
Первые концепции сериализации возникли в 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).
Принципы работы
Процесс сериализации обычно включает следующие этапы:
- Анализ структуры: сериализатор анализирует объект или структуру данных, определяя её поля, их типы и значения.
- Преобразование: каждое поле преобразуется в последовательность байтов или символов в соответствии с правилами выбранного формата.
- Упаковка: все преобразованные части объединяются в единый поток данных, возможно, с добавлением метаданных (например, длины полей, маркеров начала/конца).
- Запись/передача: полученный поток данных записывается в файл, передаётся по сети или сохраняется в памяти.
Десериализация выполняет обратные действия: читает поток данных, интерпретирует его в соответствии с форматом и восстанавливает исходную структуру данных или объект.
Критика и ограничения
- Безопасность: десериализация непроверенных данных может привести к уязвимостям, таким как удалённое выполнение кода (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 →