Что такое идемпотентность?

«Что такое идемпотентность?» — вопрос из категории Распределенные системы, который задают на 33% собеседований Data Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Идемпотентность — это свойство операции, при котором её многократное выполнение (с одинаковыми входными данными) приводит к тому же результату, что и однократное выполнение. Это фундаментальное понятие для построения надежных распределенных систем и сетевых протоколов.

Почему это критично в распределенных системах? В условиях сетевых сбоев, таймаутов и ретраев клиент не может быть уверен, была ли его первая операция выполнена. Идемпотентность позволяет безопасно повторять запрос.

Примеры:

  • HTTP-метод PUT: Обновление ресурса с конкретным ID. Сколько раз ни отправляй запрос PUT /users/123 { "name": "Alice" }, в итоге у пользователя 123 будет имя "Alice".
  • Операция "установить значение" (в отличие от "инкрементировать").
  • Удаление записи по ID: Повторные вызовы DELETE /items/456 возвращают тот же результат (успех или "не найдено"), не вызывая новых побочных эффектов.

Пример неидемпотентной операции: POST /transfer_money { "from": "acc1", "to": "acc2", "amount": 100 }. При повторной отправке из-за таймаута деньги могут быть списаны дважды.

Как добиться идемпотентности на практике?

  1. Использование уникальных ключей операций (idempotency keys): Клиент генерирует уникальный ключ для каждой логической операции и отправляет его с запросом. Сервер, увидев тот же ключ повторно, возвращает сохраненный результат первой операции, не выполняя логику заново.
    # Пример заголовка запроса
    headers = {
        'Idempotency-Key': '550e8400-e29b-41d4-a716-446655440000',
        'Content-Type': 'application/json'
    }
  2. Проектирование операций как идемпотентных: Использовать PUT вместо POST для обновлений, проектировать бизнес-логику так, чтобы проверять состояние системы перед изменением (например, "установить статус 'обработан', если текущий статус 'новый'").
  3. Использование оптимистичных блокировок (версий): Обновление происходит только если версия сущности не изменилась с момента её чтения клиентом.

Идемпотентность vs Атомарность: Атомарность гарантирует, что операция выполнится либо полностью, либо не выполнится вовсе. Идемпотентность гарантирует, что повторение успешно выполненной операции не изменит результат. Вместе они обеспечивают надежность.

Видео-ответы