Learning Platform
Глоссарий Troubleshooting
Урок 07.05 · 30 мин
Средний
Text FormatsUse CasesConfigREST APILanding ZoneJSON LinesLoggingConversionETLDecision Framework

Когда использовать текстовые форматы

Не всё — аналитика

Предыдущий урок показал, почему текстовые форматы плохи для аналитических запросов. Но аналитика — не единственный use case для данных. Текстовые форматы остаются лучшим выбором в целом ряде сценариев, где их преимущества (читаемость, совместимость, простота) перевешивают недостатки.

Текстовые форматы: плохо для аналитики, хорошо для…
Плохо дляТекстовые форматы не подходят для: аналитических запросов (full scan), долговременного хранения (overhead), distributed processing (splittability), типизированных данных (schema-on-read).
Хорошо дляТекстовые форматы идеальны для: конфигурации (человек читает и редактирует), API (универсальная совместимость), interchange (формат-посредник), logging (append-only), audit (юридическая читаемость).

Use case 1: Конфигурационные файлы

Конфигурации — идеальная ниша для текстовых форматов. Файл маленький (десятки KB), читается и редактируется человеком, не участвует в аналитических запросах:

Форматы конфигураций: сравнение
ФорматФормат конфигурационного файла.
ПлюсыПреимущества формата для конфигураций.
МинусыНедостатки формата.
ПримерыИзвестные конфигурации в этом формате.
JSONJSON для конфигураций: структурированный, но без комментариев (RFC 8259 запрещает).
Структурированный, вложенность, широкая поддержка парсеров.
Нет комментариев (!) — нельзя пояснить, зачем параметр. Trailing commas — syntax error.
package.json (npm), tsconfig.json, .eslintrc.json, VS Code settings.
XMLXML для конфигураций: многословный, но с XSD-валидацией и IDE autocomplete.
XSD-валидация, комментарии, IDE autocomplete по schema.
Многословность: открывающий + закрывающий тег. Простой параметр = 3 строки.
pom.xml (Maven), web.xml, AndroidManifest.xml, Spring XML.
YAMLYAML: читаемый (indentation-based), комментарии, но whitespace-sensitive и gotchas (Norway problem).
Комментарии (#), минимальный синтаксис, многострочные строки, anchors.
Whitespace-sensitive (пробелы vs табы). 'NO' → boolean false. Implicit typing gotchas.
docker-compose.yml, Kubernetes manifests, GitHub Actions, Ansible.
TOMLTOML: designed for config. Явные типы, комментарии, нет YAML-gotchas. Относительно новый.
Явные типы (datetime, integer, float). Комментарии. Нет implicit typing проблем.
Менее известен. Глубокая вложенность неудобна.
Cargo.toml (Rust), pyproject.toml (Python), Hugo config.
NOTE

JSON для конфигураций — компромисс. RFC 8259 запрещает комментарии, но многие инструменты используют JSONC (JSON with Comments) или JSON5. TypeScript (tsconfig.json) и VS Code используют JSONC — стандартный JSON-парсер их не прочитает.

Use case 2: REST API и interchange

JSON — де-факто стандарт для REST API. Преимущества: универсальная поддержка (каждый язык имеет JSON-парсер), самоописание (ключи = имена полей), читаемость для отладки:

API interchange: почему JSON, а не бинарный
REST API (JSON)REST API: HTTP + JSON. Клиент отправляет JSON-запрос, сервер возвращает JSON-ответ. Простота, читаемость, curl-friendly.
gRPC (Protobuf)gRPC: HTTP/2 + Protobuf. Бинарный формат, schema required, code generation. Быстрее, но сложнее отлаживать.
JSON для APIcurl, Postman, browser DevTools — всё показывает JSON без инструментов. Новый разработчик может изучить API через curl. Schema не обязательна.
Protobuf для APIProtobuf: меньший payload, быстрее сериализация, strict schema. Но: нужен .proto файл, code generation, специальный клиент. Не отлаживается через curl.

Use case 3: ETL Landing Zone

Landing zone — промежуточное хранилище для сырых данных перед трансформацией. CSV и JSON Lines — стандартные форматы для landing zone:

Landing Zone: текстовые форматы как формат приёмки
Внешние источникиИсточники данных: внешние партнёры присылают CSV, API возвращают JSON, legacy-системы экспортируют XML. Формат определяется источником, не нами.
S3: landing/raw/Landing zone (raw): данные в исходном формате. S3 bucket с партициями по дате. Никаких трансформаций — сырые файлы как есть.
ETL: validate + convertETL: валидация, очистка, типизация, конверсия в Parquet/Delta. Schema enforcement на этом этапе. Ошибки логируются, не игнорируются.
S3: curated/ (Parquet)Curated zone: данные в Parquet/Delta Lake. Типизированные, партиционированные, с statistics. Готовы для аналитики.
Зачем сохранять raw?Raw данные — источник истины. Если ETL содержит баг, можно перезапустить от raw. Если schema изменилась, можно re-process. Compliance: аудитор может проверить исходные данные.
TIP

Паттерн raw → staging → curated: raw (CSV/JSON as-is), staging (validated + typed, still text or Avro), curated (Parquet/Delta, partitioned, ready for queries). Каждый слой — отдельный S3 prefix. Raw хранится дешёво (S3 Infrequent Access), curated — в горячем хранилище.

Use case 4: Structured Logging (JSON Lines)

JSON Lines — идеальный формат для structured logging: append-only, одна запись = одна строка, parseable, но при этом human-readable:

Structured Logging: JSON Lines
ApplicationПриложение пишет структурированные логи: timestamp, level, message, context (user_id, request_id, duration_ms). Каждая запись — JSON-объект на одной строке.
stdout (JSONL)stdout/stderr: JSON Lines. Контейнер (Docker) перехватывает stdout и forwarded в logging pipeline.
Fluentd / VectorLog aggregator: Fluentd, Vector, Filebeat. Парсит JSON Lines, обогащает (pod name, node), отправляет в storage.
Elasticsearch / LokiLog storage: Elasticsearch, Loki, CloudWatch, S3. Индексируется для полнотекстового поиска и аналитики.
Пример structured logОдна строка — один JSON-объект. Все поля типизированы. Machine-parseable и human-readable одновременно.
Почему JSON Lines для логов, а не CSV или бинарный
ФорматФормат для логирования.
ПлюсыПреимущества для logging.
МинусыНедостатки для logging.
JSONLJSON Lines: одна JSON-запись на строку.
Self-describing (ключи = поля). Произвольная вложенность (context objects). grep + jq для анализа. Стандарт для ELK/Loki/CloudWatch.
Overhead ключей. 1M логов/сек → ~100 MB/сек текста.
PlaintextPlaintext: неструктурированный текст.
Простой. cat/grep/tail работают.
Нет структуры: парсить regex'ами. Разные формати от разных сервисов. Не machine-parseable.
CSVCSV для логов: фиксированные столбцы.
Компактнее JSON (нет ключей). Табличная структура.
Нет вложенности. Нельзя добавить новое поле без изменения header. Context objects не помещаются.
BinaryProtobuf/Avro для логов: бинарный формат.
Компактный. Типизированный.
Не human-readable. cat/grep не работают. Нужен десериализатор. Отладка в production — проблема.

Use case 5: Audit trails и compliance

Аудиторские записи (audit logs) часто требуют человеко-читаемый формат по юридическим причинам: аудитор должен иметь возможность прочитать файл без специального софта:

Audit Trails: требования compliance
Требования аудитаРегуляторы (SOX, PCI DSS, HIPAA) требуют: полноту записей, неизменяемость, читаемость без специальных инструментов, долговременное хранение (7+ лет).
Почему текстТекстовый формат (JSON Lines, CSV) удовлетворяет требованию читаемости: аудитор открывает файл в текстовом редакторе и видит содержимое. Бинарный формат требует специальный reader — который может быть недоступен через 7 лет.

Стратегии конверсии: текст → columnar

Текстовые форматы — временные. Данные поступают в текстовом формате и конвертируются в columnar как можно раньше:

CSV → Parquet Pipeline
CSV в S3 landingВнешний партнёр ежедневно загружает CSV в S3 bucket. Файлы в landing zone: s3://data/landing/partner/2024-01-15/data.csv.
Spark: CSV → validate → ParquetSpark job (scheduled): читает CSV, применяет explicit schema (StructType), валидирует (reject bad rows), партиционирует по date, записывает Parquet.
Parquet в curated zoneParquet в curated zone. Партиционировано по date. Column statistics. Ready for Trino/Spark/DuckDB queries.
Spark conversion codeКлючевые моменты: (1) explicit schema — не inferSchema, (2) mode=FAILFAST для early error detection, (3) partitionBy для efficient queries.
JSON → Delta Lake Ingestion
Kafka → JSONL в S3Kafka topic с JSON-событиями. Consumer выгружает в S3 как JSON Lines.
Auto Loader / StreamingAuto Loader (Databricks) или Spark Structured Streaming: мониторит S3 path, читает новые JSONL файлы, применяет schema, пишет в Delta Lake.
Delta Lake TableDelta Lake table: Parquet data files + Delta Log (JSON transaction log). ACID, time travel, schema enforcement.
Schema enforcementDelta Lake отклоняет записи, не соответствующие schema. В отличие от CSV/JSON landing (schema-on-read), Delta обеспечивает schema-on-write: ошибки ловятся при ingestion.
Quality checksExpectations (Databricks) или Great Expectations: validate data quality при ingestion. Null checks, range checks, uniqueness. Fail-fast при нарушении.

Decision framework: какой формат выбрать

Дерево выбора формата
Кто читает данные?Первый вопрос: кто будет читать данные? Человек (конфиги, отладка) или машина (ETL, аналитика)?
ЧеловекЧеловек редактирует: конфигурации, шаблоны, документы. Читаемость важнее компактности.
МашинаМашина обрабатывает: ETL, аналитика, ML. Эффективность важнее читаемости.
Человек → текстКонфиги: YAML/TOML (с комментариями). API response debug: JSON. Audit: JSON Lines/CSV. Документы: XML/Markdown.
Паттерн доступа?Машина читает: какой паттерн доступа? Транспорт (point-to-point), или аналитика (scan/aggregate)?
Транспорт → row-basedПередача записей между системами. Одна запись = одна единица обработки. Row-based форматы: Avro, Protobuf, JSON.
Аналитика → columnarSELECT/WHERE/GROUP BY на больших данных. Column pruning, predicate pushdown, encoding. Columnar форматы: Parquet, ORC.
Текстовые форматы: матрица решений
СценарийUse case для данных.
ФорматРекомендуемый формат.
ПочемуПричина выбора.
АльтернативаЧто использовать, если основной формат не подходит.
ConfigКонфигурация приложения.
TOML: явные типы, комментарии, нет gotchas.
Комментарии + explicit types + no YAML gotchas.
YAML (с осторожностью) или JSON5 (с комментариями).
APIREST API response/request.
JSON: universal standard.
Универсальность: каждый язык, curl, DevTools.
Protobuf (gRPC) для internal services. MessagePack для performance.
LoggingStructured logs.
JSON Lines: append-only, parseable, grep-friendly.
Structured + append-only + splittable.
Plaintext (legacy) → migrate to JSONL.
ExchangeData exchange с внешними партнёрами.
CSV: minimal requirements. Партнёр может создать CSV в Excel.
Минимальные требования к producer'у.
Parquet (если партнёр поддерживает). JSON Lines для сложных структур.
StorageДолговременное хранение для аналитики.
Parquet: columnar, encoded, compressed.
Column pruning + statistics + encoding + compression.
ORC (Hive ecosystem). Delta/Iceberg (table format).

Паттерн: конверсия при ingestion

Ключевой паттерн data engineering: конвертировать из текстового в columnar как можно раньше. Чем ближе к источнику — тем меньше данных обрабатывается в неэффективном формате:

Conversion at ingestion: минимизация текстового пути
Anti: CSV stays in lakeАнтипаттерн: CSV файлы лежат в S3 месяцами. Каждый запрос — full scan. Overhead × миллионы запросов.
30 TB I/O / month100 запросов/день × 10 GB scan × 30 дней = 30 TB I/O в месяц. При конверсии в Parquet: 30 TB → 1 TB.
OK: Convert at ingestionПравильно: CSV → Parquet при ingestion. CSV сохраняется в archive (cold storage), Parquet — в hot storage для запросов.
1 TB I/O / monthCSV → Parquet один раз при загрузке. Все запросы идут к Parquet. 30x экономия I/O.

Итог

Текстовые форматы — не устаревшие, а нишевые. Конфигурации, API, logging, audit, interchange — это легитимные и оптимальные сценарии для CSV, JSON, XML. Ключевое правило: данные поступают в текстовом формате → конвертируются в columnar при первой возможности → живут в Parquet/Delta для аналитики. Текстовый формат — формат входа, не формат хранения.

Проверьте понимание

Результат: 0 из 0
Концептуальный
Вопрос 1 из 4. JSON Lines (NDJSON) — рекомендуемый формат для structured logging. Почему не CSV и не Protobuf?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 5