← [Раздел](README.md) · [Главная](../README.md)

# Миграции и эволюция систем

## Цель

Научиться **планировать эволюцию** облачных систем без «большого взрыва»: strangler fig, миграции схемы expand/contract, перенос данных, dual-write и критерии готовности к cutover.

## Предварительно

- [Монолит vs микросервисы](../11-patterns/monolit-vs-microservices.md)
- [Резервирование и DR](../07-nadezhnost/rezervirovanie-i-dr.md)

## Время

~85 минут

---

## Почему не big bang rewrite

| Big bang | Поэтапная эволюция |
|----------|-------------------|
| Годы без ценности | Ценность каждый квартал |
| Один рискованный cutover | Откат по частям |
| Бизнес в страхе | Параллельная работа legacy + new |

Индустрия редко рекомендует полную переписку без крайней необходимости.

---

## Strangler Fig — детальный план

### Фаза 0 — Подготовка

- Observability на монолите (trace, метрики).
- Feature flags в монолите.
- API Gateway / reverse proxy перед монолитом.

### Фаза 1 — Первый срез

Выберите **вертикаль** с чёткой границей (например «уведомления»):

```text
Gateway: /notifications/* → new-notification-svc
         /*              → legacy-monolith
```

### Фаза 2 — Данные

- Read из старой БД через API монолита (временно).
- Или CDC (Change Data Capture) в новую БД.
- Не dual-write без плана сверки.

### Фаза 3 — Cutover

- 1% трафика → 10% → 100%.
- Мониторинг error budget.
- Rollback = переключение маршрута на gateway.

### Фаза 4 — Удаление

Удалить код из монолита только когда **нулевой** трафик 30+ дней.

---

## Expand / Contract (миграции БД)

Безопасное изменение схемы при непрерывном деплое:

| Шаг | Действие | Пример |
|-----|----------|--------|
| **Expand** | Добавить nullable колонку | `email_verified BOOL NULL` |
| **Migrate** | Заполнить данные | batch job |
| **Contract** | Сделать NOT NULL, удалить старое | после всех инстансов обновлены |

**Нельзя** переименовать колонку одним deploy — старый код упадёт.

---

## Dual-write и сверка

При переносе заказов в новую БД:

```text
1. Write to old (primary)
2. Async write to new
3. Reconciliation job сравнивает counts/hashes
4. Read from new (shadow read) без влияния на user
5. Flip read to new
6. Stop write to old
```

Метрика: **replication lag** и **mismatch count** — алерт на > 0.

---

## Миграция в облако (6 R)

Классическая модель (адаптация):

| Стратегия | Описание |
|-----------|----------|
| **Rehost** | Lift-and-shift VM |
| **Replatform** | VM → managed k8s/DB |
| **Refactor** | Разбиение, 12-factor |
| **Repurchase** | SaaS вместо custom |
| **Retire** | Выключить legacy |
| **Retain** | Оставить on-prem пока |

Часто: rehost staging → replatform prod API → refactor по strangler.

---

## Версионирование API

При split сервисов:

```text
/v1/orders — legacy facade
/v2/orders — новый сервис
```

Deprecation policy: минимум 6–12 месяцев, заголовок `Sunset`, метрики использования v1.

---

## Feature flags и release

**Deploy** ≠ **Release**. Код в prod под флагом `new-checkout=false` — снижает риск cutover.

| Флаг | Тип |
|------|-----|
| Release | Вкл/выкл фичу |
| Ops | Kill switch платежей |
| Experiment | A/B |

Удаляйте старые флаги — иначе combinatorial complexity.

---

## Критерии готовности к cutover

Чеклист:

- [ ] SLO нового пути ≥ legacy 7 дней на staging
- [ ] Load test на ожидаемый пик
- [ ] Runbook rollback проверен
- [ ] Данные сверены (0 critical mismatch)
- [ ] On-call обучен
- [ ] Product sign-off

---

## Документирование миграции

ADR серия:

```markdown
ADR-MIG-001: Strangler для notifications
ADR-MIG-002: Dual-write orders (phase 1)
ADR-MIG-003: Decommission monolith order module
```

Каждый ADR — фаза с критерием «готово».

---

## Самопроверка

1. Назовите фазы strangler fig.
2. Что такое expand/contract migration?
3. Зачем shadow read перед flip?
4. Чем deploy отличается от release в контексте флагов?

---

## Дальше

→ [Кейсы из практики](keisy-iz-praktiki.md)  
← [Архитектурный review](arhitekturnyj-review.md)
