Что такое идемпотентная операция?


Ответы:


964

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

В математике идемпотентная операция - это операция, в которой f (f (x)) = f (x) . Например, abs()функция идемпотентна, потому что abs(abs(x)) = abs(x)для всех x.

Эти немного отличающиеся определения могут быть согласованы, если учесть, что x в математическом определении представляет состояние объекта, а f - операция, которая может изменять этот объект. Например, рассмотрим Pythonset и его discardметод. discardМетод удаляет элемент из набора, и ничего не делает , если элемент не существует. Так:

my_set.discard(x)

имеет точно такой же эффект, что и одна и та же операция дважды:

my_set.discard(x)
my_set.discard(x)

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

См. Статью Wikipedia об идемпотентности для получения дополнительной информации.


Приведенный выше ответ ранее содержал несколько неверных и вводящих в заблуждение примеров. Комментарии ниже, написанные до апреля 2014 года, относятся к более старой редакции.


6
Пример: так как в ответе выше указано, что Idempotent operations are often used in the design of network protocolsвот соответствующий пример ** GET не предполагает изменений на сервере, поэтому GET является идемпотентным. В контексте HTTP / сервлет это означает, что один и тот же запрос может быть выполнен дважды без негативных последствий. ** ПОЧТА НЕ является идемпотентом.
KNU

1
Является ли «лицо без гражданства» синонимом «идемпотента»?
Михаил Ософски

2
@MichaelOsofsky: Нет, в setпримере Python в ответе заданный объект явно имеет состояние, а также предлагает некоторые идемпотентные операции, такие как discard.
Грег Хьюгилл

1
@MichaelOsofsky, discardтакже может быть реализованы таким образом , лица без гражданства, охватывая состояние в возвращаемом значении: discard([my_set, x]) = [my_new_set, x]. Так что вы можете сделать discard(discard([my_set, x])). Обратите внимание, что [my_new_set, x]это только один аргумент, а его тип - 2-кортеж.
Пейсер

2
@ Зеленый При использовании термина « тот же эффект» в контексте импотенции это означает, что результат тот же, а не действие . Повторный вызов discard(x)будет иметь тот же эффект, что и первый вызов: набор больше не будет содержать x. Вычисление идемпотентности - это надежность системы. Так как вещи могут выйти из строя (например, сбой в сети), когда обнаруживается сбой, как вы восстанавливаетесь? Самое простое восстановление состоит в том, чтобы просто сделать это снова, но это работает, только если сделать это снова идемпотентно. Например discard(x), идемпотент, но pop()это не так. Все дело в восстановлении после ошибок.
Андреас

138

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

Об идемпотентности много говорят в контексте веб-сервисов «RESTful». REST стремится максимально использовать HTTP для предоставления программам доступа к веб-контенту и обычно устанавливается в отличие от веб-сервисов на основе SOAP, которые просто туннелируют службы стиля вызовов удаленных процедур внутри HTTP-запросов и ответов.

REST организует веб-приложение в «ресурсы» (например, пользователя Twitter или изображения Flickr), а затем использует HTTP-глаголы POST, PUT, GET и DELETE для создания, обновления, чтения и удаления этих ресурсов.

Идемпотентность играет важную роль в REST. Если вы ПОЛУЧАЕТЕ представление ресурса REST (например, ПОЛУЧАЕТЕ изображение jpeg из Flickr), и операция завершается неудачей, вы можете просто повторять GET снова и снова, пока операция не завершится успешно. Для веб-службы не имеет значения, сколько раз получено изображение. Аналогичным образом, если вы используете веб-сервис RESTful для обновления информации в своей учетной записи Twitter, вы можете ставить новую информацию столько раз, сколько требуется для получения подтверждения от веб-службы. Положить его в тысячу раз - это то же самое, что и положить его один раз. Аналогично, УДАЛЕНИЕ REST-ресурса тысячу раз аналогично удалению его один раз. Таким образом, идемпотентность значительно упрощает создание веб-службы, устойчивой к ошибкам связи.

Дополнительное чтение: веб-сервисы RESTful Ричардсона и Руби (идемпотентность обсуждается на стр. 103-104) и диссертация Роя Филдинга по REST . Филдинг был одним из авторов HTTP 1.1, RFC-2616, в котором говорится об идемпотентности в разделе 9.1.2 .


Четко и понятно. Но это всего лишь одна интерпретация идемпотента.
Пейсер

10
«Идемпотентность» - сильно перегруженное слово, потому что оно звучит грандиозно и содержит достаточно символов, чтобы пройти проверку на сесквипедалианцах. Если бы Бенджамин Пирс выбрал более простое звучащее слово, у нас сегодня не было бы этого вопроса.
Pacerier

2
Как это понять: Точно так же УДАЛЕНИЕ REST-ресурса тысячу раз - это то же самое, что удаление его один раз ? Вы не можете удалить ресурс снова, если он уже удален.
Зеленый

1
@ Зеленый, но вы не удаляете его в первый раз. Вы отправляете запрос на удаление . Важным моментом является то, что вы можете отправить столько запросов, сколько захотите.
Caleth

1
@JimFerrans Я вижу. Я подумал, что может быть какая-то связанная с функциональностью причина (встроенная в сам HTTP), почему PUT можно переслать без забот, а POST - нет. Теперь кажется, что мы просто обязаны соответствовать стандартам HTTP, и поведение полностью основано на том, как реализован сервер
mangusta

109

Независимо от того, сколько раз вы вызываете операцию, результат будет одинаковым.


8
Я слышал идемпотент, определенный как одно или оба из нижеприведенного: 1) Для данного набора входов он всегда будет возвращать один и тот же выход. 2) Не вызывает побочных эффектов. Мой вопрос: если функция соответствует # 1, но не # 2, потому что это приводит к побочному эффекту, не связанному с вычислениями (например, записывает запрос в хранилище данных), все еще считается идемпотентом?
Кит Беннетт

12
Результат вызова операции должен включать состояние системы, поэтому, если операция имеет некоторый кумулятивный побочный эффект, она не идемпотентна; однако, если побочный эффект оставляет систему в одном и том же состоянии, независимо от того, сколько раз вызывается операция, он может быть идемпотентным.
Роберт

4
Коротко и мило, я люблю такой ответ. Не уверен, почему я должен постоянно искать этот термин, он просто не остается со мной.
Prancer

1
@KeithBennett, второе определение неверно. «Отсутствие побочного эффекта» не означает идемпотент. Идемпотентные функции могут иметь побочные эффекты. Например, MySQL truncateи delete.
Pacerier

Результат будет таким же (то есть состояние системы), но ответ может отличаться (т. Е. Коды состояния HTTP в службе REST).
Г. Штайгерт

50

Идемпотентность означает, что применение операции один раз или несколько раз имеет одинаковый эффект.

Примеры:

  • Умножение на ноль. Независимо от того, сколько раз вы делаете это, результат все равно равен нулю.
  • Установка логического флага. Независимо от того, сколько раз вы делаете это, флаг остается установленным.
  • Удаление строки из базы данных с заданным идентификатором. Если вы попробуете это снова, ряд все еще ушел.

Для чистых функций (функций без побочных эффектов) из идемпотентности следует, что f (x) = f (f (x)) = f (f (f (x))) = f (f (f (f (x))) ) = ...... для всех значений х

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

Обратите внимание, что в мире, где происходят параллельные действия, вы можете обнаружить, что операции, которые вы считали идемпотентными, перестали быть таковыми (например, другой поток может сбросить значение логического флага в приведенном выше примере). В основном, когда у вас есть параллелизм и изменчивое состояние, вы должны гораздо более тщательно обдумывать идемпотентность.

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


1
Если для чистых функций f(x) = f(f(x)), вы имеете в виду, что f(x){return x+1;}это не чистая функция? потому что f(x) != f(f(x)): f(1)дает 2, в то время как f(2)дает 3.
Pacerier

1
@Pacerier Нет, @mikera говорит о чистых и идемпотентных последствиях f(x) = f(f(x)). Но, как упомянул @GregHewgill, для того, чтобы это определение имело смысл, вы должны рассматривать его xкак объект и fкак операцию, которая изменяет состояние объекта (то есть: выходные данные fявляются мутированными x).
Джастин Дж. Старк

24

Идемпотентная операция выдает результат в одном и том же состоянии, даже если вы вызываете его более одного раза, при условии, что вы передаете одни и те же параметры.


1
Не звучит логично на всех. stackoverflow.com/questions/1077412/…
Зеленый

2
Я думаю, вы можете сбивать с толку идемпотента и детерминизма .
Suncat2000

16

Просто хотел выбросить реальный случай использования, который демонстрирует идемпотентность. Скажем, в JavaScript вы определяете группу классов моделей (как в модели MVC). Способ, которым это часто реализуется, функционально эквивалентен чему-то вроде этого (базовый пример):

function model(name) {
  function Model() {
    this.name = name;
  }

  return Model;
}

Затем вы можете определить новые классы следующим образом:

var User = model('user');
var Article = model('article');

Но если бы вы попытались получить Userкласс через model('user')откуда-то еще в коде, он потерпел бы неудачу:

var User = model('user');
// ... then somewhere else in the code (in a different scope)
var User = model('user');

Эти два Userконструктора будут разными. Это,

model('user') !== model('user');

Чтобы сделать его идемпотентным , вы просто добавили бы некоторый механизм кэширования, например так:

var collection = {};

function model(name) {
  if (collection[name])
    return collection[name];

  function Model() {
    this.name = name;
  }

  collection[name] = Model;
  return Model;
}

Добавляя кеширование, каждый раз, когда вы это делаете, model('user')это будет один и тот же объект, и поэтому он идемпотентен. Так:

model('user') === model('user');

10

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

ПРИМЕРЫ (КОНТЕКСТ ВЕБ-ПРИЛОЖЕНИЯ):

IDEMPOTENT: выполнение нескольких идентичных запросов имеет тот же эффект, что и создание одного запроса. Сообщение в системе обмена сообщениями электронной почты открывается и помечается как «открытое» в базе данных. Можно открыть сообщение много раз, но это повторное действие приведет только к тому, что это сообщение будет в «открытом» состоянии. Это идемпотентная операция. В первый раз, когда один PUT обновляет ресурс, используя информацию, которая не соответствует ресурсу (состоянию системы), состояние системы будет изменяться по мере обновления ресурса. Если один PUT неоднократно обновляет ресурс, то информация в обновлении будет совпадать с информацией, уже имеющейся в системе, при каждом PUT, и никакого изменения состояния системы не произойдет. Повторные PUT с той же информацией являются идемпотентными:

NON-IDEMPOTENT: если операция всегда вызывает изменение состояния, например, отправку одного и того же сообщения пользователю снова и снова, в результате чего новое сообщение каждый раз отправляется и сохраняется в базе данных, мы говорим, что операция не является IDEMPOTENT.

NULLIPOTENT: Если операция не имеет побочных эффектов, таких как просто отображение информации на веб-странице без каких-либо изменений в базе данных (другими словами, вы только читаете базу данных), мы говорим, что операция NULLIPOTENT. Все GET должны быть нулевыми.

Говоря о состоянии системы, мы, очевидно, игнорируем безнадежно безвредные и неизбежные эффекты, такие как регистрация и диагностика.


9

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

Неидемпотентные операции: операции, которые могут нанести некоторый вред, если будут выполнены несколько раз. (Поскольку они изменяют некоторые значения или состояния)
Пример: операция, которая снимается с банковского счета


3
На самом деле неправильный ответ! для операции Идемпотент сказать "не иметь побочных эффектов" неправильно. для неидемпотентных операций высказывание «причинить какой-то вред» - это запутанный ответ.
Саид Мохташам

9

Довольно подробный и технический ответ. Просто добавив простое определение.

Идемпотент = перезапускаемый

Например, Createсама операция не гарантируется без ошибок, если выполняется более одного раза. Но если есть операция, CreateOrUpdateто она заявляет о перезапуске (идемпотентности).


3
Это обманчивое определение. повторное использование не гарантирует идемпотентности. Операция может быть повторно запущена, и при каждом запуске она может добавлять дополнительные эффекты к результату, чтобы она не была идемпотентной.
Саид Мохташам

7

Идемпотентная операция над множеством оставляет его члены неизменными при применении один или несколько раз.

Это может быть унарная операция, такая как absolute (x), где x принадлежит множеству натуральных чисел. Здесь absolute (absolute (x)) = x.

Это может быть бинарная операция, например объединение множества с самим собой всегда будет возвращать один и тот же набор.

ура


Идемпотентная операция - это операция, в которой f (f (x)) = f (x). «оставляет своих членов без изменений» - неправильный ответ.
Саид Мохташам

7

Любая операция заключается в том, что каждый n-й результат приведет к выводу, совпадающему со значением 1-го результата. Например, абсолютное значение -1 равно 1. Абсолютное значение абсолютного значения -1 равно 1. Абсолютное значение абсолютного значения абсолютного значения -1 равно 1. И так далее.

Читайте также: Когда было бы действительно глупо использовать рекурсию?


1
это содержательный ответ даже через 10 лет. +1
ОСШ

3

Хорошим примером понимания идемпотентной операции может быть запирание автомобиля с помощью дистанционного ключа.

log(Car.state) // unlocked

Remote.lock();
log(Car.state) // locked

Remote.lock();
Remote.lock();
Remote.lock();
log(Car.state) // locked

lockэто идемпотентная операция. Даже если при каждом запуске возникает какой-либо побочный эффект lock, например мигание, автомобиль все еще находится в заблокированном состоянии, независимо от того, сколько раз вы выполняли блокировку.


1

мой 5с: в интеграции и в сети идемпотентность очень важна. Несколько примеров из реальной жизни: представьте, мы доставляем данные в целевую систему. Данные доставляются последовательностью сообщений. 1. Что произойдет, если последовательность будет смешана в канале? (Как сетевые пакеты всегда делают :)). Если целевая система идемпотентна, результат не будет отличаться. Если целевая система зависит от правильного порядка в последовательности, мы должны реализовать повторный секвенсор на целевом сайте, который восстановил бы правильный порядок. 2. Что будет, если появятся дубликаты сообщения? Если канал целевой системы не подтверждает своевременно, исходная система (или сам канал) обычно отправляет другую копию сообщения. В результате мы можем получить дубликаты сообщений на стороне целевой системы. Если целевая система идемпотентна, это заботится об этом, и результат не будет отличаться. Если целевая система не идемпотентна, мы должны реализовать дедупликатор на стороне целевой системы канала.


Идемпотентность отдельных запросов, отправляемых отдельно от любых других запросов (или любых других событий, которые изменяют состояние системы), не совпадает с переупорядочением запросов. HTTP-запрос PUT и HTTP-запрос DELETE должны быть индивидуально идемпотентными, но это не означает, что порядок вызова PUT и DELETE для одного и того же URL-адреса не имеет значения, поскольку запрос PUT может иметь побочные эффекты!
Робин Грин

1

Короче говоря , операции Идемпотента означают, что операция не приведет к различным результатам независимо от того, сколько раз вы выполняете операции Идемпотента.

Например, согласно определению спецификации HTTP, GET, HEAD, PUT, and DELETEидемпотентны операции; Однако POST and PATCHэто не так. Вот почему иногда POSTзаменяется на PUT.


-4

Retry-сейф.

Обычно это самый простой способ понять его значение в информатике.


1
Повторить подразумевает что-то, что не удалось в первый или предыдущий раз. Не совсем то же самое.
Лассе В. Карлсен

Кто отредактировал мой вопрос и получил голос против? Это не тот текст, который я разместил ??
Текнопаул

Вы можете проверить журнал редактирования, нажав на ссылку под вашим ответом, которая гласит «отредактировано X часов назад» или аналогичное.
Лассе В. Карлсен
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.