개발/Elasticsearch
aws elasticsearch snapshot 으로 데이터 백업 with java
보리ing
2021. 2. 9. 19:00
지금 서비스하고 있는 aws elasitcsearch 버전이 6.8인데 7.7에서 힙 메모리 사용이 확 개선되어, 가장 최신 버전인 7.9 버전으로 마이그레이션 하려고 한다.
1. s3 bucket 생성
-snapshot 저장할 s3 bucket 생성한다.
2. IAM - 역할 생성
iam - 역할 - 역할 만들기
ec2 선택해서 다음 - 다음 - 다음 역할이름 입력하여 역할 만들기 완료
3. 역할에 신뢰관계 설정
생성한 역할에 신뢰 관계 - 신뢰 관계 편집
ec2 대신 es로 변경
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "es.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
신뢰 정책 업데이트
4. 해당 역할에 정책 연결
정책 연결 - 정책생성을 통해 정책을 정의해도 되고, 인라인 정책에 추가해도 된다.
인라인 정책 추가 - json
사용 bucket명은 testsnapshot-bucket
{
"Version": "2012-10-17",
"Statement": [{
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::testsnapshot-bucket"
]
},
{
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::testsnapshot-bucket/*"
]
}
]
}
이제 iam 작업은 다 끝났다.
5. snapshot repository 생성
현 프로젝트에 gradle에 추가되어있는 관련 디펜던시
'org.springframework.boot' version '2.2.8.RELEASE' 환경
implementation group: 'org.springframework.cloud', name: 'spring-cloud-starter-aws', version: '2.2.1.RELEASE'
implementation 'org.springframework.data:spring-data-elasticsearch:3.2.8.RELEASE'
implementation 'software.amazon.awssdk:auth:2.13.42'
a.kibana
PUT _snapshot/my-snapshot-repo-name
{
"type": "s3",
"settings": {
"bucket": "s3-bucket-name",
"base_path": "es-snapshot/test",
"region": "region",
"role_arn": "arn:aws:iam::123456789012:role/TheSnapshotRole",
"compress" : "true"
}
}
와같이 입력하여 생성 할 수 있다곤 하는데 되지 않아 java로 작업 하였다.
{
"Message": "User: anonymous is not authorized to perform: iam:PassRole on resource: "
}
와 같은 에러 메세지 발생
b. java
private static String region = "ap-northeast-2";
private static String serviceName = "es";
private static String aesEndpoint = "old 엔드포인트"
private static String newAesEndpoint = "new 엔드포인트"
private static String snapshotRepository = "/_snapshot/whitelabel_backup";
private static String snapshotSettings = "{ \"type\": \"s3\", \"settings\": { \"bucket\": \"testsnapshot-bucket\", \"region\": \"ap-northeast-2\", \"base_path\": \"es-snapshot/test\", \"compress\":\"true\", \"role_arn\": \"위에서 생성한 역할"\ } }";
static final AWSCredentialsProvider credentialsProvider = new DefaultAWSCredentialsProviderChain();
public String doSnapshot() throws IOException {
RestClient esClient = esClient(serviceName, region);
// Register a snapshot repository
HttpEntity entity = new NStringEntity(snapshotSettings, ContentType.APPLICATION_JSON);
Request request = new Request("PUT", snapshotRepository);
request.setEntity(entity);
// request.addParameter(name, value); // optional parameters
Response response = esClient.performRequest(request);
System.out.println(response.getStatusLine().getStatusCode());
System.out.println(response.toString());
return response.toString();
}
public static RestClient esClient(String serviceName, String region) {
AWS4Signer signer = new AWS4Signer();
signer.setServiceName(serviceName);
signer.setRegionName(region);
HttpRequestInterceptor interceptor = new AWSRequestSigningApacheInterceptor(serviceName, signer, credentialsProvider);
return RestClient.builder(HttpHost.create(aesEndpoint)).setHttpClientConfigCallback(hacb -> hacb.addInterceptorLast(interceptor)).build();
}
public static RestClient newEsClient(String serviceName, String region) {
AWS4Signer signer = new AWS4Signer();
signer.setServiceName(serviceName);
signer.setRegionName(region);
HttpRequestInterceptor interceptor = new AWSRequestSigningApacheInterceptor(serviceName, signer, credentialsProvider);
return RestClient.builder(HttpHost.create(newAesEndpoint)).setHttpClientConfigCallback(hacb -> hacb.addInterceptorLast(interceptor)).build();
}
status code 200이 나오면 정상 처리
kibana에서
GET _snapshot
으로
{
"cs-automated" : {
"type" : "s3"
},
"whitelabel_backup" : {
"type" : "s3",
"settings" : {
"bucket" : "testsnapshot-bucket",
"base_path" : "es-snapshot/test",
"region" : "ap-northeast-2",
"role_arn" : "생성한 역할",
"compress" : "true"
}
}
}
확인 가능
6. elasticsearch snapshot 해당 s3에 저장
public void moveToS3() throws IOException {
RestClient esClient = esClient(serviceName, region);
// Save indexes into S3 repository
String takeSnapShot = "{\n \"indices\": \"*\",\n \"ignore_unavailable\": true,\n \"include_global_state\": false\n}";
HttpEntity entity = new NStringEntity(takeSnapShot, ContentType.APPLICATION_JSON);
Request request = new Request("PUT", snapshotRepository + "/snapshot-all");
request.setEntity(entity);
Response response = esClient.performRequest(request);
System.out.println(response.toString());
}
7. 5.b와 같은 방법으로 새 elasticsearch server snpashot repository 생성
8. 새 서버에 백업 데이터 복구
public void EsRestore() throws IOException {
RestClient esClient = newEsClient(serviceName, region);
// Restoring snapshot as ES indices
String takeSnapShot = "{\n \"indices\": \"test-index\",\n \"ignore_unavailable\": true,\n \"include_global_state\": false\n}";
HttpEntity entity = new NStringEntity(takeSnapShot, ContentType.APPLICATION_JSON);
Request request = new Request("POST", snapshotRepository + "/snapshot-all/_restore");
request.setEntity(entity);
Response response = esClient.performRequest(request);
System.out.println(response.toString());
}