ElasticSearch - 충돌 처리

10974 단어 elasticsearch
index API를 사용하여 문서를 업데이트할 때 원본 문서를 한 번에 읽고 전체 문서를 다시 인덱스할 수 있습니다. 최근의 인덱스 요청이 승리합니다. 마지막 문서가 인덱스되더라도 ElasticSearch에 유일하게 저장됩니다.만약 다른 사람이 이 문서를 동시에 변경한다면, 그들의 변경은 잃어버릴 것이다.
이것은 문제가 없을 때가 많다. 아마도 우리의 주 데이터 저장은 관계형 데이터베이스일 것이다. 우리는 그것을 Elastic Search에 복사해서 검색할 수 있게 할 뿐이다. 아마도 두 사람이 같은 문서를 동시에 변경할 확률이 매우 적거나 우리의 업무에 있어서 간혹 변경을 잃어버리는 것도 큰 문제가 아니지만 때로는 변경을 잃어버리는 것이 매우 심각하다.
데이터베이스 영역에서 일반적으로 두 가지 방법은 동시 업데이트를 할 때 업데이트가 손실되지 않도록 하는 데 사용된다.
  • 비관적 병발 제어: 이런 방법은 관계형 데이터베이스에 광범위하게 사용되고 변경 충돌이 발생할 수 있다고 가정하기 때문에 충돌을 방지하기 위해 자원에 접근하는 것을 막는다.전형적인 예는 한 줄의 데이터를 읽기 전에 그것을 잠그고 자물쇠를 놓은 라인만 이 줄을 수정할 수 있도록 하는 것이다.
  • 낙관적 병행 제어: Elastic Search에서 사용하는 이런 방법은 충돌이 발생할 수 없고 시도하고 있는 조작을 막지 않는다고 가정한다.그러나 원본 데이터가 읽기와 쓰기에서 수정되면 업데이트가 실패합니다.응용 프로그램은 다음에 충돌을 어떻게 해결해야 할지 결정할 것이다.예를 들어 새로운 데이터를 업데이트하거나 사용하거나 관련 보고 상황을 사용자에게 보고할 수 있다
  • 낙관적 병발 제어


    ElasticSearch는 분산되어 있습니다.문서를 만들거나 업데이트하거나 삭제할 때, 새 버전의 문서는 그룹의 다른 노드로 복사해야 합니다.ElasticSearch도 비동기적이고 병발적이다. 이것은 이러한 복제 요청이 병렬적으로 발송되고 목적을 달성할 때 순서가 혼란스러울 수도 있다는 것을 의미한다.ElasticSearch는 문서의 이전 버전이 새 버전을 덮어쓰지 않도록 하는 방법이 필요합니다.
    우리가 이전에 소개한 GET, DELETE 요청을 할 때, 우리가 출력한 모든 문서에는 _version 버전 번호가 있고, 문서가 수정될 때 버전 번호가 점차 증가한다.ElasticSearch는 이 _version 를 사용하여 변경이 정확한 순서로 실행될 수 있도록 합니다.이전 버전의 문서가 새 버전 이후에 도착하면 간단하게 무시할 수 있습니다.
    우리는 응용 프로그램에서 서로 충돌하는 변경이 데이터의 분실을 초래하지 않도록 _version 를 사용할 수 있다.우리는 문서를 수정할 _version 을 지정함으로써 이 목적을 달성한다.이 버전이 현재 버전 번호가 아니라면 요청이 실패합니다
    다음은 한 걸음 한 걸음 간단한 조작을 통해 설명할 것이다.
  • 블로그 글 만들기
  • curl -XPUT "http://localhost:9200/csdn/blog/1" -d '
    {
        "title":"test"
        "desc":" "
    }
    '

    이 때 응답체가 우리에게 알려준다 _version 는 1
  • 블로그 내용 수정, 버전 지정 수정
  • curl -XPUT "http://localhost:9200/csdn/blog/1?version=1"

    이 때 응답체가 우리에게 _version 가 이미 2로 점차적으로 증가했다는 것을 알려줄 것이다
  • 그러나 우리가 다시 같은 요청체, 즉version=1을 사용하면 ElasticSearch는 409 오류를 되돌려줍니다. 왜냐하면 이때_version는 이미 2
  • 이기 때문입니다.
    {
        "error": {
            "root_cause": [
                {
                    "type": "version_conflict_engine_exception",
                    "reason": "[blog][1]: version conflict, current version [2] is different than the one provided [1]",
                    "index_uuid": "3t42ZzdSRoO8RPkL0jDYbg",
                    "shard": "3",
                    "index": "csdn"
                }
            ],
            "type": "version_conflict_engine_exception",
            "reason": "[blog][1]: version conflict, current version [2] is different than the one provided [1]",
            "index_uuid": "3t42ZzdSRoO8RPkL0jDYbg",
            "shard": "3",
            "index": "csdn"
        },
        "status": 409
    }

    모든 문서의 업데이트나 API 삭제는 version 파라미터를 받아들일 수 있습니다. 이것은 코드에서 낙관적인 병행 제어를 사용할 수 있도록 하는 현명한 방법입니다.

    외부 시스템에서 버전 제어 사용


    흔히 볼 수 있는 설정은 다른 데이터베이스를 주요 데이터로 저장하고 ElasticSearch를 사용하여 데이터 검색을 하는 것이다. 이것은 주 데이터베이스의 모든 변경 사항이 ElasticSearch로 업데이트되어야 한다는 것을 의미한다. 만약에 여러 프로세스가 같은 데이터를 동시에 변경한다면 이전에 설명한 것과 유사한 병행 문제를 만날 수 있다.
    ElasticSearch에서 검색 문자열을 추가하는 방식으로 같은 버전 번호를 다시 사용할 수 있습니다. 버전 번호는 0보다 큰 정수이고 version_type=external 자바에서 long 형식의 정수보다 작아야 합니다.
    외부 버전 번호 처리 방식은 우리가 이전에 논의한 내부 버전 번호와 약간 다르다. ElasticSearch는 현재 9.2E+18 와 요청에서 지정한 버전 번호가 같은지 확인하는 것이 아니라 현재 _version 가 지정한 버전 번호보다 작은지 검사하는 것이다.요청이 성공하면 외부 버전 번호가 문서의 새 _version 로 저장됩니다.
    다음은 한 걸음 한 걸음 간단한 조작을 통해 설명할 것이다.
  • 블로그 글을 만들고 버전은 1
  • curl -XPUT "http://localhost:9200/csdn/blog/1?version=1&version_type=external" -d '
    {
        "title":"test"
        "desc":" "
    }
    '

    다음과 같은 데이터가 제공됩니다.
    {
      "_index" : "csdn",
      "_type" : "blog",
      "_id" : "1",
      "_version" : 1,
      "result" : "created",
      "_shards" : {
        "total" : 2,
        "successful" : 1,
        "failed" : 0
      },
      "created" : true
    }
  • 이 블로그를 업데이트하고 버전 번호를 2
  • 로 업그레이드
    curl -XPUT "http://localhost:9200/csdn/blog/1?version=2&version_type=external" -d '
    {
        "title":"test1"
        "desc":" 1"
    }
    '

    다음과 같은 데이터가 제공됩니다.
    {
      "_index" : "csdn",
      "_type" : "blog",
      "_id" : "1",
      "_version" : 2,
      "result" : "updated",
      "_shards" : {
        "total" : 2,
        "successful" : 1,
        "failed" : 0
      },
      "created" : false
    }
  • 2단계 작업을 다시 수행하고 버전이 변하지 않으면 오류가 발생합니다. 외부 버전 번호로 인해 현재_version
  • 보다 커야 합니다.
    {
      "error" : {
        "root_cause" : [
          {
            "type" : "version_conflict_engine_exception",
            "reason" : "[blog][1]: version conflict, current version [2] is higher or equal to the one provided [2]",
            "index_uuid" : "3t42ZzdSRoO8RPkL0jDYbg",
            "shard" : "3",
            "index" : "csdn"
          }
        ],
        "type" : "version_conflict_engine_exception",
        "reason" : "[blog][1]: version conflict, current version [2] is higher or equal to the one provided [2]",
        "index_uuid" : "3t42ZzdSRoO8RPkL0jDYbg",
        "shard" : "3",
        "index" : "csdn"
      },
      "status" : 409
    }

    좋은 웹페이지 즐겨찾기