КатегорииElasticsearch

Elasticsearch — Урок 4.3 Конкуренция при обновлении

Ранее мы обсуждали, что операция обновления должна сначала получить старый документ, применить изменения и переиндексировать документ. Если в процессе извлечения и изменения данных, кто-то еще изменить их, данные изменения будут утеряны и заменены вашими. Чтобы решить эту проблему, Elasticsearch увеличивает версию документа для каждой операции.

Если версия документа была изменена между извлечением и повторной индексацией документа, операция завершается с ошибкой. Приведем пример:

POST example4/person/2/_update 
{ 
  "doc" : {
     "name" : "name update 3"
  } 
}

Ответ на предыдущую операцию выглядит следующим образом:

{
 "_index": "example4",
 "_type": "person",
 "_id": "2",
 "_version": 4,
 "result": "updated",
 "_shards": {
   "total": 2,
   "successful": 1,
   "failed": 0
 }
}

Вы можете видеть из предыдущего ответа, что версия документа равна 4. Для следующего обновления мы можем указать версию:

PUT example4/person/2?version=4
{
 "id": 2,
 "name": "name update 1",
 "age": "55",
 "gender": "M",
 "email": "user2@gmail.com",
 "last_modified_date" : "2017-02-18"
}

Операция выполняется только в том случае, если текущая версия равна 4. Вот успешный ответ:

{
 "_index": "example4",
 "_type": "person",
 "_id": "2",
"_version": 5,
 "result": "updated",
 "_shards": {
   "total": 2,
   "successful": 1,
   "failed": 0
 }
}

Если вы сейчас попытаетесь запустить обновление с версией 4, вы увидите ответ 409 HTTP response code, как показано ниже:

{
 "error": {
  "root_cause": [
   {
      "type": "version_conflict_engine_exception",
      "reason": "[person][2]: version conflict, current version [5] is ...",
      "index_uuid": "9rcbu7LZR42te04D_G9r-g",
      "shard": "0",
      "index": "example4"
    }
   ],
   "type": "version_conflict_engine_exception",
   "reason": "[person][2]: version conflict, current version [5] is ...",
   "index_uuid": "9rcbu7LZR42te04D_G9r-g",
   "shard": "0",
   "index": "example4"
  },
  "status": 409
}

Чтобы избежать сбоя из-за конфликта, вы можете попросить Elasticsearch повторить попытку. Количество попыток до завершения операции может быть задано с помощью retry_on_conflict, как показано ниже:

 POST example4/person/2/_update?retry_on_conflict=3
 {
   "doc": {
     "name": "name update 2"
   }
 }

В данном случае будет предпринято три попытки применить изменения.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *