AWS elasticsearch 에서 스냅샷 생성 및 복원

AWS elasticsearch 에서는 자동백업을 지원하지만 이걸 복원하려면 AWS Support에 직접 요청하는 방식이라 원하는 시점에 복원하지 못할 수 도 있습니다. 또한 elasticsearch 버전을 올리기위해 마이그레이션을 할때는 새로운 elasticsearch를 생성하고 직접 백업 및 복원을 해야합니다.

그래서 이번 글은 AWS elasticsearch 스냅샷 생성 및 복원에 대해 처음부터 끝까지 적어봤습니다. IAM Role 설정같은데서 헷갈려서 제가 좀 헤맨 부분이 있어 다른분들한테도 도움이 될것 같네요.

사전작업

  1. 백업파일이 위치할 S3 파일을 생성
  2. IAM Role 생성
  3. IAM Policy 생성후 2번에서 생성한 Role에 추가

1. S3 버킷 생성

my-es-snapshot 버킷을 생성. 이건 그냥 버킷만 생성하면 됩니다 ~ 될수 있으면 elasticsearch 와 같은 region 으로 맞춰주는게 좋겠지요?

2. IAM Role 생성

IAM 메뉴 접속후 “Role > Create New Role” 을 이용해 새로운 Role을 생성. Role 이름은 아무거나 정하고 여기서는 “esSnapshotRole”로 지정. “Select Role Type”에서는 “Amazon EC2” 선택. 그다음 Attach Policy 에서는 아무것도 선택하지 않고 “Next Step”

이렇게 하면 Role 이 생성됩니다.

3. IAM Policy 생성후 연결

IAM 메뉴 접속후 “Policies > Create Policy” 버튼을 클릭.
“Create Your Own Policy”를 선택하고 “Policy Document”에 다음 내용을 붙어녛기 합니다

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "s3:ListBucket"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::my-es-snapshot"
            ]
        },
        {
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject",
                "iam:PassRole"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::my-es-snapshot/*"
            ]
        }
    ]
}

여기서 my-es-snapshot 은 S3 버킷 이름으로 본인의 상황에 맞게 변경합니다

이렇게 생성된 Policy 의 상세화면에 들어가서 “Attached Entities” 에서 Attach 버튼을 클릭해 앞서 생성한 IAM Role에 연결합니다

스냅샷 저장소 생성

AWS Elasticsearch 같은경우 스냅샷 저장소 생성은 curl 명령어를 이용해서는 불가능합니다. 맥의 경우를 가정하면 터미널을 실행후 아래 명령어를 실행합니다.(윈도우 사용자분들은 알아서 자알 ~ 파이썬 설치하고 pip 뭐 이런거 동작하게 설치하면 될거에요)

$ sudo pip install boto

이 다음에 snapshot.py 라는 파일을 만들고 아래 내용을 붙여넣기후 저장

from boto.connection import AWSAuthConnection

class ESConnection(AWSAuthConnection):

    def __init__(self, region, **kwargs):
        super(ESConnection, self).__init__(**kwargs)
        self._set_auth_region_name(region)
        self._set_auth_service_name("es")

    def _required_auth_capability(self):
        return ['hmac-v4']

if __name__ == "__main__":

    client = ESConnection(
            region='ap-northeast-2',
            host='search-xxx-yyyy.ap-northeast-2.es.amazonaws.com',
            aws_access_key_id='xxxxx',
            aws_secret_access_key='yyyyy', is_secure=False)

    print 'Registering Snapshot Repository'
    resp = client.make_request(method='POST',
            path='/_snapshot/s3_repository',
            data='{"type": "s3","settings": { "bucket": "my-es-snapshot","region": "ap-northeast-2","role_arn": "arn:aws:iam::xxxx:role/esSnapshotRole"}}')
    body = resp.read()
    print body
region, host, aws_access_key_id, aws_secret_access_key, path, data 등은 본인의 상황에 맞게 변경합니다.
  • region=’ap-northeast-2′
    • 이건 서울의 경우. 다른 지역에 있는 elasticsearch 라면 변경이 필요
  • host=’search-xxx-yyyy.ap-northeast-2.es.amazonaws.com’
    • AWS elasticsearch 주소
  • aws_access_key_id=’xxxxx’, aws_secret_access_key=’yyyyy’
    • AWS elasticsearch 에 접근권한이 있는 계정의 인증정보
  • path=’/_snapshot/s3_repository’
    • elasticsearch 에 생성할 스냅샷 저장소 경로. s3_repository 부분을 원하는 이름으로 변경
  • “bucket”: “my-es-snapshot”
    • 앞서 생성한 S3 버킷 이름
  • “region”: “ap-northeast-2”
    • S3 버킷의 region
  • “role_arn”: “arn:aws:iam::xxxx:role/esSnapshotRole”
    • 앞서 생성한 IAM Role의 ARN 문자열. Role 상세페이지에서 “Role ARN” 속성으로 확인가능
설정을 본인에 맞게 변경후 터미널에서 다음 명령어를 실행합니다
$ python snapshot.py

실행후 별다른 에러 없으면 스냅샷 저장소 생성 성공 ~

맥의 경우에는 파이썬이 설치되어 있어서 별도의 파이썬 설치가 필요없지만 윈도우라면 알아서 잘 설치하고 진행하면 됩니다.

스냅샷 생성

아래 명령어를 터미널에서 실행해서 새로운 스냅샷을 생성합니다.
$ curl -XPUT 'https://search-xxx-yyy.ap-northeast-2.es.amazonaws.com/_snapshot/s3_repository/first_snapshot'

위의 명령어는 앞서 생성한 s3_repository 스냅샷 저장소에 first_snapshot 이라는 스냅샷을 생성합니다.

위 명령어의 결과는 바로 반환되고 뒤에서는 스냅샷을 생성하고 있다. 완료여부를 확인하려면 다음 명령어를 실행합니다.

$ curl -XGET 'https://search-xxx-yyy.ap-northeast-2.es.amazonaws.com/_snapshot/s3_repository/first_snapshot'
이거의 반환값의 “state” 항목이 “SUCCESS” 이면 스냅샷 생성이 완료된것입니다. 참고로 스냅샷 생성이 완료되지 않았을때는 아무런 에러없이 오랫동안 반환이 안되요

스냅샷 복원

아래 명령어를 이용해 복원을 시작한다
$ curl -XPOST 'https://search-xxx-yyyy.ap-northeast-2.es.amazonaws.com/_snapshot/s3_repository/first_snapshot/_restore'

스냅샷 생성때와 마찬가지로 실행하자마자 반환값이 나오지만 뒤에서 계속 복원이 진행중인 상태입니다.

복원이 진행중일때는 클러스터 상태가 Red 이고 완료되면 원래의 클러스터 상태로 돌아오므로 클러스터 상태를 통해 복원이 완료되었는지 확인할 수 있습니다

아래 명령어가 클러스터 상태 확인하는 명령어

$ curl -XGET 'https://search-xxx-yyyy.ap-northeast-2.es.amazonaws.com/_cluster/health'

다른 elasticserach 로 스냅샷을 복원하는 경우

elasticsearch 를 마이그레이션 하거나 다른 elasticsearch 클러스터에 복원하려는 경우 새로운 elasticserach 에 스냅샷 저장소만 생성하면 됩니다. 스냅샷 저장소를 앞서 생성한 스냅샷 저장소와 동일한 옵션으로 생성하면 같은 S3를 바라보게 되므로 복원도 바로 됩니다

참고자료

게시글의 아마존, iTunes 링크들을 통해 구매를 하시면 제휴(Affiliate) 프로그램에 의해 저에게 일정 금액이 적립될 수 있습니다. ^_____^

kibana 혹은 elasicsearch 에서 unique count 정확하게 보기

사용자 pv 확인을 위해 kibana를 사용중이었는데 kibana의 unique 갯수와 kibana와 동일한 쿼리로 추출하는 일일 접속자의 id 목록의 갯수와 맞지 않는 현상이 발생했다.

es에서 갯수를 계산할때 대략적인 수치를 사용한다는것을 알고는 있었지만 대략 5000 vs 4500 정도로 오류의 편차가 너무 커서 이를 해결하고자 방법을 찾던중 실마리를 찾았다.

unique 갯수를 추출하기 위해 cardinality aggregation을 사용하는데 이 수치에는 어느정도의 에러 수치가 있고 이를 해결하기위해서는 precision_threshold 옵션 수치를 수정하면 된다. precision_threshold 수치가 높으면 더 많은 메모리와 자원을 사용하고 속도는 느리지만 정확한 값을 얻을수 있고 낮으면 메모리와 자원도 적게 쓰고 속도도 빠르지만 부정확한 데이터를 얻게 된다.

precision_threshold 값의 기본값이 얼마인지는 모르겠지만 내가 문제 생겼던 서비스의 경우 수치가 10,000 이하이기 때문에 precision_threshold 값을 10,000으로 설정했더니 정확한 데이터를 얻을수 있었다.

kibana에서 precision_threshold 값을 입력하기 위해서는 Y-Axis > Advanced > JSON Input 에 다음과 같이 입력한다.

{"precision_threshold": 10000}

precision_threshold 입력하기

그런데 이값을 적용하고 나면 정말 느려진다 =_= 정확한 수치가 중요한 경우가 아니라면 굳이 입력하지 않고 흐름을 보는데만 확인하고 필요할때만 입력하는게 좋을것 같다.

참고자료

게시글의 아마존, iTunes 링크들을 통해 구매를 하시면 제휴(Affiliate) 프로그램에 의해 저에게 일정 금액이 적립될 수 있습니다. ^_____^