Elasticsearch version conflict 에러

배치를 이용해서 Elasticsearch에 데이터를 삽입하던 중 version conflict라는 오류가 자주 발생했다. 처음에는 Elasticsearch 버전이 동일한데 왜? 오류가 나는지 몰랐다.

그래서 검색해보니 인덱스안에 document에는 각자 관리하는 version이 존재한다. 이 version은 document가 수정될 때 하나씩 올라가게 되는데 version이 10인 상태에 document에 여러 서버 모듈에서 해당 document에 업데이트를 하려고 하니 문제가 발생하였다.

그 이유는 version 10인 상태에서 작업에 들어간 두 모듈은 한 모듈이 먼저 11로 업데이트를 시키고 다음 모듈이 작업을 진행하려고 할 때 자기가 알고 있던 마지막 version인 10이 아니라 11로 바껴있는것을 보고 에러를 뱉어내는것이다. 이렇게 까지 세심하게 챙겨줄지 몰랐다. 알면 알수록 elasticsearch라는 db는 정말 매력적이다.

PUT wedul_index 
{
  "mappings": {
      "_doc": {
        "dynamic": "false",
        "properties": {
          "name": {
            "type": "text"
          }
        }
      }
  }
}

위와 같이 인덱스가 있고 document 하나가 들어있다. 여기에 age라는 값과 gender를 집어넣어보자. 이를 동시에 호출해보자.

document

그럼 document 하나에 필드를 동시에 업데이트하는 update.sh라는 스크립트를 만들어서 실행시켜보자.

curl -X POST "localhost:9200/wedul_index/_update_by_query" -H 'Content-Type: application/json' -d' { "script": { "source": "ctx._source[\u0027gender\u0027] = \u0027M\u0027"}, "query": { "match": { "name": "위들" } } } ‘
curl -X POST "localhost:9200/wedul_index/_update_by_query" -H 'Content-Type: application/json' -d' { "script": { "source": "ctx._source.age = 10", "lang": "painless" }, "query": { "match": { "name": "위들" } } } ‘

그럼 위에 설명했던 것 처럼 버전이 먼저 변경이 되면서 다음과 같은 에러를 뱉어낸다.

[{"index":"wedul_index","type":"_doc","id":"3MSd5WsB_jV9Cf9TkYLV","cause":{"type":"version_conflict_engine_exception","reason":"[_doc][3MSd5WsB_jV9Cf9TkYLV]: version conflict, current version [3] is different than the one provided [2]","index_uuid":"sJI8sBnrTP-OW8OG8YBqWA","shard":"3","index":"wedul_index"},"status":409}]

 

이를 해결하기 위해서는 retry_on_conflict 옵션을 함꼐 부여할 수 있는데 이 옵션은 version conflict이 발생했을 때, 업데이트 재시도를 몇회 할건지 지정하는 옵션이다.

좀 더 자세한 사항은 아래 elasticsearch 메뉴얼을 보면 자세히 나와있다.

참조
https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update-by-query.html
https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update.html

댓글()

Git Rebase 도중 한번 이상 충돌 해결 방법

IT 지식/Git|2018. 6. 23. 22:57

Git에서 브랜치를 rebase 하는 도중에 충돌이 여러번 발생하였을때 해결하는 방법에 대해 알아보자.

먼저 기준이 되는 브랜치 master에 test.txt라는 파일을 만들고 내용을 작성하고 커밋을 진행하자.

 

그리고 리베이스를 진행할 브랜치인 conflict 브랜치에 test.txt를 생성하고 두번 커밋을 진행하자.

그리고 master에 리베이스를 진행하면 먼저 첫번째 충돌이 발생한다.

그러면 test.txt 파일을 수정하고 나서 스테이지에 다시 올리고 액션 메뉴에서 재배치 계속을 눌러 진행한다.

그러면 두번째 충돌이 발생하고 마찬가지로 해결 후 재배치 계속을 누르면 성공적으로 리베이스가 진행된것을 확인할 수 있다.

이렇게 두번의 충돌이 발생하는 이유는 아래의 그림을 살펴보면 알겠지만 변경이 델타 1, 델타 2 두번이 이루어져있고 이를 마스터에 적용을 진행을 하면서 여러번 같은 파일에 충돌을 해소해야 하는 문제가 발생한 것이다. 

이렇게 귀찮은 짓을 반복하고 싶지 않다면 브랜치에 있는 여러 커밋들을 하나로 합친 후에 마스터 브랜치에 합치면 단 한번만 충돌을 해결할 수 있다. 

여러 상황에 대해 많이 테스트 해보고 진행해보면서 문제를 해결해 보는 능력을 길러야겠다.

 

깃은 svn보다 확실히 편하지만 어렵다.

 

 

 

댓글()

Git Rebase 도중 충돌 (conflict) 해결 방법

IT 지식/Git|2018. 6. 23. 22:24

저번부터 계속해서 rebase에 대해 알아보았다. 그러나 생각보다 rebase를 진행하다보면 충돌이 나는 경우가 많다. 

간단하게 리베이스에서 발생한 충돌을 해결해보자.

우선 master에서 c.txt를 만들고 커밋을 진행해보자.

 

그리고 conflict 브랜치에서 c.txt를 만들어서 파일내용에 conflict branch commit으로 저장하고 커밋을 하자.

 

그럼 이제 master 브랜치로 conflict 브랜치를 rebase하여 merge를 진행해보자. 그러면 다음과 같이 충돌이 발생하게 되고 rebase가 멈추는것을 볼 수 있다.

 

그럼 충돌된 내용이 무엇인지 확인해보자.

몬가 이상한것을 확인할수있다.

바로 HEAD 부분에 원래 merge중에 충돌이 발생하면 내 코드가 나오고 하단에 충돌이 발생한 코드가 나오기 마련이다. 하지만 반대로 되어있다. 

그 이유는 아래 그림을 보면 알겠지만 리베이스 도중에 리베이스에 기준이되는 master 브랜치로 head가 옮겨지면서 순서가 뒤바뀌게 되는것이다. 잘 숙지하고 오해하지 않도록!

 

그럼 충돌이 발생한 코드를 수정해보자. 충돌이 발생한 c.txt파일에 충돌내역을 수정하고 저장을 한 뒤에 스테이지에 파일을 올려놓는다. 그리고 action 메뉴에서 재배치 계속을 눌러 리베이스를 마무리한다.

 

그러면 충돌이 해소가 되고 두 개의 브랜치가 성공적으로 리베이스 작업이 완료된것을 알 수 있다.

실무에서는 더 복잡하게 게 충돌이 일어날 가능성이 크다. 다음 시간에 조금더 복잡한 상황에서 발생하는 사례를 공부해보자.

댓글()

Git 대화형 rebase를 사용한 커밋 순서변경, 합치기 등등 방법

IT 지식/Git|2018. 6. 22. 00:28

저번에 공부했었던 rebase에 대해 더 공부해보자. 이번에 공부할 내용은 대화형 rebase를 통해 커밋한 내용을 지우거나, 순서를 바꾸거나 기존 커밋에 내용을 더 추가하거나 하는 내용을 확인해보자.

 

커밋 합치기

리베이스를 진행할 때 리베이스를 진행할 브랜치에 커밋된 내용이 길다고 가정해보자. 그러면 그 커밋마다 변경된 내용이 다 달라서 master에 리베이스를 진행할 때 여러번에 conflict를 해결해야 한다.

그래서 오늘 강의해주신 강사님이 말씀하시길 브랜치의 커밋을 하나로 합치고 나서 rebase를 진행하면 좋다고 하셨다. 그럼 합쳐보자.

우선 아래 이미지를 보면 c2와 c3의 커밋을 하나로 합쳐서 아래와 같이 마스터 브랜치에 합쳐보겠다.

우선 위와 같은 상황이 되도록 브랜치를 만들어서 진행해보면 다음과 같이 히스토리를 볼 수있다.

그럼 여기서 feature 커밋과 feature 2번째 커밋을 합쳐보겠다.

우선 대화형 리베이스에 경우 앞에 있는 커밋들에 대해 조정을 하는 것이기 때문에 조정하려고 하는 커밋의 바로 직전 커밋에서 조절을 시작해야한다. 

위에 상태에서는 feature 브랜치에서 마스터 커밋위치에서 우측 클릭을 하여 대화형 리베이스 모드에 진입한다. (이 부분은 앞으로 진행할 내용들도 동일하다.)

가장 최상단의 커밋을 누르고 이전 커밋과 합치기를 누른다.

그러고 난 후 커밋을 더블클릭하면 메시지를 변경할 수있다.

 

그러면 다음과 같이 합쳐진것을 확인할 수있다.

 

특정 커밋 없애기

이번에는 특정 커밋을 제거 하고 싶을 때 하는 방법을 알아보자.

위와 같은 상황에서 feature 커밋 2를 없애보자.

마찬가지로 바로 직전 커밋인 feature 커밋 1으로 커서를 두고 대화형 리베이스 모드에 들어간다.

그리고 지우고자 하는 커밋을 선택하고 삭제한다음 OK 를 누른다.

 

그러면 다음과 같이 커밋 히스토리가 변경된 것을 알 수 있다.

커밋 순서 바꾸기

커밋의 순서를 바꾸고 싶을 때 다음과 같이 진행한다.

동일하게 그 직전에 마우스를 놓고 대화형 리베이스 모드에 들어간다.

feature commit2 와 3의 순서를 바꿔보겠다.

변경을 원하는 커밋을 누르고 하단의 화살표를 통해 순서를 바꾸고 확인을 누르면 된다.

 

중간에 커밋내용 변경하기

커밋을 진행하다 보면 파일을 빼먹을때가 있다. 이럴경우 특정 커밋에 내용을 추가해주면서 방법을 알아보자

 

바로 직전인 마스터 대화형 리베이스를 선택한다.

그리고 해당 커밋에 amend 영역을 클릭하고 확인을 누른다.

그러면 해당 commit 부분이 리베이스 될때 멈추는 것을 볼 수 있다.

그 상태에서 변경하거나 추가하고 싶은 파일을 스테이지 다음과 같이 올린다. 여기서 중요한 것은 스테이지에 올린 후에 커밋을 진행한다 (커밋 옵션에서 마지막 커밋 수정을 눌러서 진행해야 한다.)

그리고 액션 메뉴에 있는 재배치 계속을 클릭한다.

 

 

여러 경우 리베이스에 대해 공부했다.

다음에는 리베이스 도중 conflict 해결에 대해 알아보자.

 

 

댓글()