Retention и политики хранения
1) Принципы
1. Purpose & Minimization. Храним ровно то и ровно столько, сколько нужно целям обработки.
2. Policy as Code. Ретеншен — это исполняемая политика, а не PDF.
3. Defense in Depth. TTL/ILM + шифрование + аудиты + Legal Hold.
4. Reversibility & Proof. Удаление проверяемо: логи действий, крипто-шреддинг, отчет о соблюдении.
5. Cost & Carbon Aware. Ретеншен учитывает $/ГБ-мес и углеродный след хранения/egress.
2) Классификация данных и «карта ретеншена»
Разбейте наборы на классы с целями и правовыми основаниями:- Операционные (OLTP): заказы, платежи, сессии.
- Аналитические (DWH/даты): события, лог-факты, срезы.
- Персональные (PII/финансы/здоровье): требуют специальных сроков и прав субъектов.
- Технические: логи, метрики, трейсы, артефакты CI.
- Документы/медиа: WORM/архив/легаси.
Для каждого класса задайте: владелец, цель, правовая база, сроки, уровень защиты, текущие и целевые хранилища.
3) ILM: жизненный цикл данных
Типовой конвейер:1. Ingest (hot) → NVMe/SSD, высокая частота запросов.
2. Warm → реже читается, компрессия, колоночные форматы.
3. Cold/Archive → объектное/ленточное, долгий доступ.
4. Purge/Delete → гарантированное удаление (вкл. реплики/бэкапы).
Пример ILM-профиля (YAML):yaml dataset: events_main owner: analytics purpose: "product analytics"
classification: "pseudonymized"
lifecycle:
- phase: hot; duration: 7d; storage: nvme; format: row
- phase: warm; duration: 90d; storage: ssd; format: parquet; compress: zstd
- phase: cold; duration: 365d; storage: object; glacier: true
- phase: purge; duration: 0d privacy:
pii: false dp_delete_window: 30d # SLA on personal deletions if ligaments appear
4) Политики как код (полезные скетчи)
4.1 Admission-политика (обязательные теги/TTL)
yaml policy: require-retention-tags deny_if_missing: [owner, purpose, classification, retention]
default_retention:
logs: "30d"
traces: "7d"
metrics:"90d"
4.2 Gate в CI/CD (Rego) — запрет деплоя без ретеншена
rego package policy. retention deny[msg] {
some d input. datasets[d].retention == ""
msg:= sprintf("Retention missing for dataset %s", [d])
}
4.3 S3/объектное (фрагмент lifecycle)
yaml
Rules:
- ID: logs-ttl
Filter: { Prefix: "logs/" }
Transitions:
- { Days: 7, StorageClass: STANDARD_IA }
- { Days: 30, StorageClass: GLACIER }
Expiration: { Days: 180 }
NoncurrentVersionExpiration: { NoncurrentDays: 30 }
5) Retention в потоках и очередях
Kafka:- `retention.ms`/`retention.bytes` — оконный ретеншен.
- Compaction (`cleanup.policy=compact`) — храним последнее значение ключа.
- Tiered Storage — уводим «хвост» в холодный тир.
- DLQ — отдельный ретеншен и TTL.
properties cleanup. policy=delete,compact retention. ms = 604800000 # 7d for tail removal
min. cleanable. dirty. ratio=0. 5 segment. ms=86400000
Гарантии:
- Определите ретеншен ключевых топиков ≈ бизнес-окно реплея/пересчета.
- Для событий биллинг/аудит — отдельный долгий ретеншен или WORM.
6) Базы данных и ретеншен
Реляционные:- Партиционирование по дате/диапазону, detach & drop старых партиций.
- Поля с датой — индексы для TTL-запросов.
- Темпоральные таблицы (system-versioned) + полиси purge старых версий.
sql
-- Monthly instalments
CREATE TABLE audit_events (id bigserial, occurred_at timestamptz, payload jsonb) PARTITION BY RANGE (occurred_at);
-- Cleaning over 365 days
DELETE FROM audit_events WHERE occurred_at < now() - interval '365 days';
VACUUM (FULL, ANALYZE) audit_events;
NoSQL/Time-series:
- TTL на уровне ключей (MongoDB TTL index, Redis `EXPIRE`, Cassandra TTL).
- Downsampling для метрик (сырые 7д → аггрегаты 90д → долгие 365д).
- Политики retention в TSDB (Influx/ClickHouse Materialized Views с дедуп/агрегацией).
7) Логи, метрики, трейсы
Логи: ограничить поля, маскировать ПД, TTL 7–30д, архив 90–180д.
Метрики: сырые высокочастотные — 7–14д; downsample (5m/1h) — 90–365д.
Трейсы: tail-sampling и хранение «интересных» (ошибки/хвосты) дольше.
yaml observability:
logs: { ttl: "30d", archive: "90d", pii_mask: true }
metrics: { raw: "14d", rollup_5m: "90d", rollup_1h: "365d" }
traces: { sample: "tail-10%", ttl: "7d", error_ttl: "30d" }
8) Удаление: типы и гарантии
Логическое (soft-delete): пометка записи; удобно для восстановления, не подходит под «право на удаление».
Физическое (hard-delete): фактическое удаление данных/версий/реплик.
Криптографическое (crypto-erasure): удаление/замена ключей шифрования, после чего данные не восстанавливаются.
Каскадное: сквозное удаление дериваций (кеши, индексы, аналитика).
request → locate subject data (index by subject_id) → revoke tokens & unsubscribe jobs → delete in OLTP → purge caches → enqueue erasure in DWH/lakes → crypto-shred keys (per-tenant/per-dataset) → emit audit proof (receipt)
9) Право на удаление, Legal Hold и eDiscovery
Право на удаление/исправление: SLA исполнения (например, ≤30 дней), трассируемые действия, квитанции.
Legal Hold: при юридическом запросе — заморозка удаления для указанных наборов/ключей; политика приоритета над TTL.
eDiscovery: каталог данных, полнотекстовый/атрибутивный поиск по артефактам, экспорт в согласованных форматах.
yaml legal_hold:
dataset: payments scope: ["txn_id:123", "user:42"]
from: "2025-10-31"
until: "2026-03-31"
reason: "regulatory investigation"
10) Бэкапы vs архивы vs WORM
Бэкапы — для восстановления от потери/порчи; короткий ретеншен, быстрый RTO.
Архивы — долгосрочное хранение для аудита/аналитики, дешевые, длинный доступ.
WORM — неизменяемые носители для комплаенса (финансы/отчетность); политики «write-once, read-many».
- Не рассчитывайте бэкап как «архив на века».
- Репетиции восстановления (DR-дни), отчет о времени и полноте.
- Каталог бэкапов с ретеншеном, шифрованием и ключами отдельно от хранилища.
11) Приватность и анонимизация
Псевдонимизация: отложенная привязка PII через таблицу ключей (позволяет crypto-erasure по ключу).
Анонимизация: необратимые техники (k-анонимность, шум, обобщение); документируйте метод, риск реидентификации и срок годности.
12) Мониторинг соответствия и отчетность
Контрольные панели: доля датасетов с валидным ретеншеном, объемы по фазам ILM, ошибки удаления.
Алерты: превышение целевого объема в горячем тире, «подвисшие» удаления, истекающие Legal Hold.
Отчеты: месячный аудит удаления (кол-во запросов, средний срок, неудачи), распечатка крипто-шреддинга.
13) Интеграция в процессы: гейты и ревью
Design-gate: новый датасет не проходит ревью без `owner/purpose/retention`.
Release-gate: миграции, увеличивающие ретеншен без владельца/обоснования — блокируются.
Cost-gate: объем в hot/warm превышает бюджет — триггер на ILM-ужесточение.
Security-gate: запрет включения ПД в логи/трейсы без маскировки и TTL.
14) Анти-паттерны
«Храним все навсегда — вдруг пригодится».
Жестко кодированные TTL в приложениях, не вынесенные в политики.
ПД в логах и трейcах без маскировки/TTL/удаления.
Неполное удаление (оставили в кэше/DWH/бэкапах).
Отсутствие Legal Hold — стирание данных под расследованием.
Один общий ключ шифрования на все — невозможно точечно «крипто-стереть».
Нулевая наблюдаемость: «верим, что удалили», но доказательств нет.
15) Чек-лист архитектора
1. Для каждого датасета есть owner, purpose, classification, retention, storage tier?
2. Политики ILM/TTL задекларированы как код и применяются автоматически?
3. ПД маскируются в логах/трейсах; запрещены вне «белых» наборов?
4. Есть процессы персональных удалений (SLA, аудит, квитанции)?
5. Crypto-erasure возможен (пер-тенант/пер-датасет ключи, KMS/rotation)?
6. Бэкапы: расписание, шифрование, тесты восстановления, отдельные ключи?
7. Legal Hold/eDiscovery: поддерживаются, превалируют над TTL, журналы действий ведутся?
8. Kafka/очереди: задан ретеншен/compaction/тiering, DLQ имеет отдельные политики?
9. Метрики и алерты на соблюдение ретеншена и объемы по тирами настроены?
10. Ревью и гейты в SDLC блокируют артефакты без ретеншена?
16) Мини-рецепты
16.1 ClickHouse: «отсечь хвост» старше 180 дней
sql
ALTER TABLE events DELETE WHERE event_date < today() - 180;
OPTIMIZE TABLE events FINAL;
16.2 Redis: TTL и lazy-purge
bash
SET session:123 value EX 3600
CONFIG SET maxmemory-policy allkeys-lru
16.3 Tail-sampling для трасс
yaml tail_sampling:
policies:
- name: keep-errors-and-slow latency_threshold_ms: 500 status_codes: ["5xx"]
rate_limit_per_min: 5000 default_ttl: "7d"
16.4 Crypto-erasure (идея)
keys:
dataset: users_pii key_id: kms://pii/users/tenant-42 erase(user_id=42):
rotate_or_destroy (key_id) # inability to restore former purge_indexes blocks ("user _ id = 42")
audit("crypto-erasure", user_id)
Заключение
Политики хранения — это «скелет» вашей платформы данных: они описывают, сколько живут разные классы данных, где они находятся в каждый момент, как дешевеют со временем и когда исчезают без следа — законно, прозрачно и проверяемо. Сделайте ретеншен политикой как код, соедините ILM с безопасностью и стоимостью, включите наблюдаемость и гейты — и вы получите систему, которая одновременно эффективна, комплаентна и готова к росту.