- AWS SES

 Amazon SES는 모든 애플리케이션에 통합하여 대량으로 이메일을 전송할 수 있는 클라우드 이메일 서비스 공급자입니다. Simple Mail Transfer Protocol(SMTP) 시스템을 구현하지 않아도 됩니다.

 

- 비용 & 호출 방법

애플리케이션이 Amazon Elastic Compute Cloud(Amazon EC2)에서 실행되는 경우 Amazon SES를 사용하여 추가 비용 없이 매월 62,000개의 이메일을 전송할 수 있습니다. AWS SDK를 사용하거나, Amazon SES SMTP 인터페이스를 사용하거나, Amazon SES API를 직접 호출하여 Amazon EC2에서 이메일을 보낼 수 있습니다.

 

AWS SES 클라이언트 설정

implementation platform('software.amazon.awssdk:bom:2.3.9')
implementation 'software.amazon.awssdk:sesv2:+'
    @Bean
    public SesV2Client getAmazonSimpleEmailServiceClient() {
        AwsCredentials credentials = null;
        if (StringUtils.isNotBlank(accessKey) && StringUtils.isNotBlank(secretKey)) {
            credentials = AwsBasicCredentials.create(accessKey, secretKey);
        }
        AwsCredentialsProvider provider = StaticCredentialsProvider.create(credentials);
        return SesV2Client.builder()
                .credentialsProvider(provider)
                .region(Region.of(sesRegion))
                .build();
    }

 

이메일 구성

try {
    Content subject = Content.builder().data(sendContent.getTitle()).build();
    Content content = Content.builder().data(thymeLeafHtml).build();
    Message msg = Message.builder().subject(subject).body(Body.builder().html(content).build()).build();
    EmailContent emailContent = EmailContent.builder().simple(msg).build();
    Destination destination = Destination.builder().toAddresses("test@naver.com").build();

    SendEmailRequest emailRequest = SendEmailRequest.builder()
                                                    .destination(destination)
                                                    .content(emailContent)
                                                    .fromEmailAddress("testSender@naver.com")
                                                    .build();

    sesV2Client.sendEmail(emailRequest);
} catch (SesV2Exception e) {
            log.error("Encountered an error processing sending email.\n");
            e.printStackTrace();
            throw e;
}

 

- 예외는 어떻게? (AWS SDK 사용의 경우)

예외를 사용하는 프로그래밍 언어로 AWS SDK를 사용하는 경우 SES 호출이 MessageRejectedException을 발생시킬 수 있습니다. 

 

- MIME

Multipurpose Internet Mail Extension으로 전자 우편을 위한 인터넷 표준 포맷입니다. 전자우편은 7비트 ASCII 문자를 사용하여 전송되기 때문에, 8비트 이상의 코드를 사용하는 문자나 이진 파일들은 MIME 포맷으로 변환되어 SMTP로 전송됩니다.

 

- MIME과 AWS SES의 관계?

AWS SES(Simple Email Service)는 이메일 메시지를 전송하기 위해 MIME(Multipurpose Internet Mail Extensions) 프로토콜을 사용합니다. MIME은 이메일 메시지를 텍스트, 이미지, 오디오, 비디오 등 다양한 멀티미디어 형식으로 변환하고, 인코딩 및 디코딩을 지원하는 표준 규약입니다. 이를 통해 다양한 종류의 파일을 이메일로 전송할 수 있습니다.

 

AWS SES는 MIME 형식을 준수하는 이메일 메시지를 전송할 수 있습니다. 이를 위해 AWS SES에서는 이메일 메시지 본문과 첨부 파일을 MIME 형식으로 구성해야 합니다. 이를 위해서는 이메일 메시지의 콘텐츠 유형(Content-Type), 인코딩 방식(Content-Transfer-Encoding), 그리고 각 파트의 경계선(Boundary)을 설정해야 합니다.

 

AWS SES에서는 이러한 MIME 형식으로 구성된 이메일 메시지를 전송하기 위해 다양한 API 및 SDK를 제공합니다.

이를 통해 개발자는 자신이 사용하는 프로그래밍 언어에 맞는 인터페이스를 통해 이메일을 보낼 수 있습니다.

 

따라서, AWS SES와 MIME은 이메일 전송에서 밀접한 관계가 있으며, MIME의 규약을 준수하는 이메일 메시지를 AWS SES에서 전송함으로써 다양한 형식의 파일을 이메일로 전송할 수 있습니다.\

 

-AWS SES를 이용해 이메일을 전송할 때 quoted printable( 이메일 본문에 특수 문자나 이메일 주소와 같은 ASCII 이외의 문자가 포함될 경우, 이메일 내용을 안전하게 전송하기 위해 필요한 인코딩 방식) 을 고려해야 하나요?

 

일반적으로 AWS SES(Simple Email Service)를 사용하여 이메일을 보낼 때, quoted-printable 인코딩은 자동으로 적용됩니다. 따라서 별도로 quoted-printable 인코딩을 고려할 필요는 없습니다. AWS SES를 사용하는 경우, 이메일을 전송할 때 필요한 인코딩 방식은 자동으로 선택되므로, 이메일의 내용이 안전하게 전송되도록 보장됩니다.

 

그러나, 이메일의 특정 부분에 대해 다른 인코딩 방식을 사용하고자 하는 경우, AWS SES는 이를 수행할 수 있는 API를 제공합니다. 이를 통해 별도의 인코딩 방식을 선택할 수 있습니다. 따라서 필요에 따라 인코딩 방식을 선택하여 이메일을 전송할 수 있습니다.

 

 

Spring Cloud Config Server가 있는 EC2에 사용 가능한 용량이 없다는 문제로 해당 서버가 정상 동작하지 않자 해당 서버를 통해 설정 파일을 주입받는 모든 서버에 영향이..^^

용량이 이렇게 부족해 진 것은 불필요한 Batch작업이 해당 EC2에서 진행되고 있어서였고, 이는 처리하였다.

하지만 용량이 너무 작은 것으로 설정된 것 같긴 해서 이참에 볼륨 크기를 확장하기로.

 

아래 명령어로 파일시스템 용량을 확인해보았다. 

$ df -h

결과는 아래와 같았다. 

Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        978M     0  978M   0% /dev
tmpfs           986M     0  986M   0% /dev/shm
tmpfs           986M  101M  886M  11% /run
tmpfs           986M     0  986M   0% /sys/fs/cgroup
/dev/xvda1      8.0G  8.0G   20K 100% /
tmpfs           198M     0  198M   0% /run/user/1000
tmpfs           198M     0  198M   0% /run/user/0

AWS Console에서 해당 EC2의 스토리지의 볼륨디바이스를 보니 볼륨크기가 8Gib에 /dev/xvda로 설정되어 있는 것을 확인할 수 있었다. 

 

AWS Console에서 EBS Volume을 2배 (16Gib)로 변경해주었고, 아래 명령어로 연결된 블록 디바이스를 확인해보았다.

$ lsblk

루트 볼륨은 2배로 잘 커져 있었지만 파티션인 xvda1은 여전히 8Gib인 것을 볼 수 있을 것이다.

해당 파티션도 늘려주기 위해서 아래 명령어를 입력하였다 . 

$ sudo growpart /dev/xvda 1

그랬더니 아래와 같은 에러가...

mkdir: cannot create directory ‘/tmp/growpart.4699’: No space left on device
FAILED: failed to make temp dir

 

AWS 문서에 이와 같은 상황에서 할 수 있는 해결책을 제시해주었다. 


블록 디바이스에 남은 공간 없음 오류를 방지하려면 임시 파일 시스템 tmpfs /tmp 탑재 지점에 탑재합니다. 그러면 /tmp에 탑재된 10M tmpfs가 생성됩니다.

$ sudo mount -o size=10M,rw,nodev,nosuid -t tmpfs tmpfs /tmp

위와 같이 진행하고 아래 명령어를 입력하니 성공!

$ sudo growpart /dev/xvda 1
CHANGED: partition=1 start=4096 old: size=16773087 end=16777183 new: size=33550303 end=33554399

 

여기까지는 파티션의 크기를 늘린 것이고,

이제는 파일시스템에 변경된 파티션 크기를 적용해야 한다. 

그래서 아래의 명령어를 통해 적용해보려 했지만 에러가 뙇

$ sudo resize2fs /dev/xvda1

resize2fs 1.42.9 (28-Dec-2013)
resize2fs: Bad magic number in super-block while trying to open /dev/xvda1
Couldn't find valid filesystem superblock.

 

원인을 찾아보니 리눅스의 파일 시스템이 xfs라서 그런거라고 한다.. 아래 명령어를 입력해서 확인해 볼 수 있다. 

$ df -Th
Filesystem     Type      Size  Used Avail Use% Mounted on
devtmpfs       devtmpfs  978M     0  978M   0% /dev
tmpfs          tmpfs     986M     0  986M   0% /dev/shm
tmpfs          tmpfs     986M  101M  886M  11% /run
tmpfs          tmpfs     986M     0  986M   0% /sys/fs/cgroup
/dev/xvda1     xfs       8.0G  8.0G   20K 100% /
tmpfs          tmpfs     198M     0  198M   0% /run/user/1000
tmpfs          tmpfs     198M     0  198M   0% /run/user/0
tmpfs          tmpfs      10M     0   10M   0% /tmp

/dev/xvda1의 Type이 xfs로 되어 있다.  리눅스의 파일 시스템이 xfs일 경우 발생한다고 한다. 

 

이럴때는 resize2fs가 아닌 xfs_growfs를 써야 한다.

$ sudo xfs_growfs /dev/xvda1

아래의 메시지와 함께 정보들이 나열되면 성공!!

data blocks changed from 2096635 to 4193787

 

df -Th로 확인해보면~

Filesystem     Type      Size  Used Avail Use% Mounted on
devtmpfs       devtmpfs  978M     0  978M   0% /dev
tmpfs          tmpfs     986M     0  986M   0% /dev/shm
tmpfs          tmpfs     986M  100M  887M  11% /run
tmpfs          tmpfs     986M     0  986M   0% /sys/fs/cgroup
/dev/xvda1     xfs        16G  8.1G  8.0G  51% /
tmpfs          tmpfs     198M     0  198M   0% /run/user/1000
tmpfs          tmpfs     198M     0  198M   0% /run/user/0
tmpfs          tmpfs      10M     0   10M   0% /tmp

/dev/xvda1의 Size가 16G이고 Use%가 100%에서 51%로 줄어있는 것을 확인할 수 있다.

 

 

 

용량이 어느새 다시 찼다...

알고 보니 log 디렉토리에 로그파일이 수두룩 빽빽하게 쌓여서 용량을 다 잡아 먹고 있었던 것이다.

그래서 근본적인 해결을 하기로 하였고.

$ sudo du --/ | sort -| tail -40 | sort --r

위 명령어를 통해 용량 차지 상위 순서대로 디렉토리 리스트를 뽑아봤고,

거기서 로그 디렉토리가 압도적인 것을 확인. 

스크립트를 짜서 15일에 한번씩 로그 파일들을 정리하기로 했다. 

 

 

끝!

 

 

 

출처

https://aws.amazon.com/ko/premiumsupport/knowledge-center/ebs-volume-size-increase/

https://velog.io/@hyeonseop/ec2-%EC%9A%A9%EB%9F%89-full%EC%9D%BC-%EB%95%8C-%EB%8C%80%EC%B2%98%EB%B2%95

https://nirsa.tistory.com/231

모델 학습,데이터 결과 처리, 프로덕션 배포 및 SageMaker의 CI/CD에 대한 내용이다. 

  • SageMaker Training이란 무엇일까?
    • 완전 관리형 머신 러닝 학습 서비스
    • 데이터 과학자가 빠르고 쉽게 모델 개발 및 학습을 할 수 있도록 지원

 

두가지 타입으로 사용할 수 있다. 

고객이 준비할 건 파란 영역이며 AWS에서 제공하는 학습 컨테이너 이미지를 사용할 수도 있다. 추가로 필요한 패키지가 있는 경우는 Custom 학습 컨테이너 이미지를 직접 고객이 만들어서 올린 다음 사용할 수 있다.

 

작은 용량의 노트북 CPU를 띄워서 데이터 준비 및 코드를 작성하고, 모델 학습은 고성능 CPU에서 실행할 수 있게 한다.

 

모델 학습 환경의 구성

1. SageMaker 노트북 생성

2. 학습 코드 내 경로 수정

3. 학습 작업의 실행 노트북 작성

 

1. SageMaker 노트북 생성 

노트북 인스턴스에서 모델학습을 수행할 수 있지만, 학습의 확장성이 제한적입니다.

따라서, 별도 인스턴스를 띄워서 모델 학습을 진행하며, 이를 SageMaker Training이라고 합니다. 

비용을 절감, 학습의 확장성을 고려해서 노트북에서 학습하기 보다는 별도 인스턴스에서 학습하길 권장한다. 

학습이 끝나면 AWS에서 제공하는 학습 클러스터는 종료되고 과금되지 않는다. 

학습을 실행하게 되면 정의한 내용 대로 학습 인스턴스가 여러개 뜰 수도 있고 컨테이너 이미지가 여러개 뜰 수 있고 컨테이너들끼리 네트워크로 연결되어 분산 작업이 가능하다. 

 

동작방식은 어떻게 될까?

노트북에서 생성된 학습코드, S3에 저장된 데이터, AmazonECR에서 생성한 Custom학습 컨테이너 이미지가 학습 실행을 시작시키면 SageMaker 학습 클러스터에 복사되어 실행이 되고, 학습 종료 후 클러스터는 사라지게 된다. 

 

2. 학습 코드 내 경로 수정

 

학습코드를 노트북에 올리고, code 폴더는 자동으로 학습 클러스터의 학습 인스턴스에 자동으로 복사된다. 

경로가 너무 길면 별도 환경 변수를 활용하여 짧게 수정할 수도 있다.

 

클러스터가 종료되어도 산출물들은 저장되어야 하기 때문에 학습이 끝나면 위 경로에 자동으로 저장이 되게 한다.

3. 학습 코드 내 경로 수정

학습 클러스터의 인스턴스 종류/수 실행할 학습코드, 학습 환경 컨테이너 등을 Estimator로 정의

estimator에 정의하기
학습 클러스터에서 사용할 데이터 경로와 channel_name을 선언한 후 fit으로 실행하기
Estimator에 정의된 값에 더 알아보자
고가의 CPU, GPU를 활용해 빠르게 데이터를 가져오고 싶다 하면 Lustre를 활용하면 된다.
예상했던 것 보다 더 오래 동작하는 걸 방지하기 위해 최대 학습 수행시간을 조정한다.

작동원리

노트북에서 컨테이너 이미지를 받아와서 실행하여 디버깅을 한다. 비용 관점에서는 디버깅이 끝나면 노트북 인스턴스를 용량을 낮춰 비용을 절감한다.

 

간단하게 AWS 에서 제공하는 영상을 보면서 SageMaker가 어떤 건지 정도 알 수 있었다고 한다..

$ sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
$ sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key

이전에 Jenkins에서 키를 가져온 경우 이미 키가 있기 때문에 rpm --import가 실패합니다. 이땐 무시하고 진행하시기 바랍니다.

$ yum install epel-release # repository that provides 'daemonize'

$ yum install epel-release에서 에러가 나서 아래의 명령어로 대체

$ sudo amazon-linux-extras install epel

그리고, Jenkins 설치를 위해 자바를 설치해줍니다.

$ sudo yum install java-11-openjdk-devel
$ sudo yum install jenkins

 

 

 

jenkins를 시작하고, 잘 돌아가는지 확인합니다.

$ sudo systemctl start jenkins
$ sudo systemctl status jenkins.service

 

 

기본 포트가 8080이기 때문에 원하는 포트로 변경을 합니다.

$ sudo vim /etc/sysconfig/jenkins

JENKINS_PORT 부분을 맘에 드는 포트로 변경하고, 변경된 부분을 적용시키기 위해 서비스 재시작하면 끝!

 

$ sudo systemctl restart jenkins

 


출처: https://get.jenkins.io/redhat-stable/
출처: https://oingdaddy.tistory.com/354 

환율 정보를 가져오는 작은 서비스를 개발해야 하는데 이번 기회에 AWS Lambda 를 이용해보기로 하였다. 

참고 자료를 찾아보는데 Java를 이용해서 AWS Lambda 서비스를 만든 사례를 찾기 어려워 꽤나 헤매었다;

환율을 가져오는 자세한 로직은 제외하고, 설정 및 테스트 부분만 포스팅해보겠다.

 

 

CloudWatch Events를 Trigger로 하여 정해진 시간에 한번씩 Currency 정보를 가져오게끔 하였다. 

 

런타임 설정 

 

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.LambdaLogger;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import java.util.Map;

// Handler value: example.Handler
public class CurrencyHandler implements RequestHandler<Map<String,String>, String>{
    Gson gson = new GsonBuilder().setPrettyPrinting().create();

    @Override
    public String handleRequest(Map<String,String> event, Context context)
    {
        LambdaLogger logger = context.getLogger();

        String response = "200 OK";
        // log execution details
        logger.log("ENVIRONMENT VARIABLES: " + gson.toJson(System.getenv()));
        logger.log("CONTEXT: " + gson.toJson(context));
        // process event
        logger.log("EVENT: " + gson.toJson(event));
        logger.log("EVENT TYPE: " + event.getClass());
        return response;
    }
}

 

pom.xml

plugins {
    id 'org.springframework.boot' version '2.4.5'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
}

group = 'XXX'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

repositories {
    mavenCentral()
}

dependencies {
    implementation platform('software.amazon.awssdk:bom:2.10.73')
    implementation 'software.amazon.awssdk:lambda'
    implementation 'com.amazonaws:aws-lambda-java-core:1.2.1'
    implementation 'com.amazonaws:aws-lambda-java-events:3.1.0'
    implementation 'com.google.code.gson:gson:2.8.6'
    implementation 'org.apache.logging.log4j:log4j-api:2.13.0'
    implementation 'org.apache.logging.log4j:log4j-core:2.13.0'
    runtimeOnly 'org.apache.logging.log4j:log4j-slf4j18-impl:2.13.0'
    runtimeOnly 'com.amazonaws:aws-lambda-java-log4j2:1.2.0'
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.0'
}

test {
    useJUnitPlatform()
}

task buildZip(type: Zip) {
    from compileJava
    from processResources
    into('lib') {
        from configurations.runtimeClasspath
    }
}

 

중요한 포인트는 소스 파일을 AWS Lambda에 올릴 때 사이즈가 50MB 이 넘어가면 S3에 소스코드를 올려야 한다.

이때 zip으로 package한 결과물을 올려야 하는데 이 부분에서 애를 많이 먹었다 :,-(

배포를 jar로만 했었는데 zip으로 하는 방법도 몰랐고, 그렇게 해야하는 건 줄도 몰랐다 ^^;;;

pom.xml에 zip으로 빌드한다는 내용을 입력하고, 'gradle buildZip'를 하면 

프로젝트\build\distributions 디렉토리 내 zip으로 빌드된 파일이 생성되고 이것을 S3에 올리면 된다. 

 

  • Keyword
    • 일정한 형식으로 고정된 문자열 데이터를 색인할 때 사용
    • keyword타입의 field는..
      • aggregation, sorting, filtering에 사용된다.
      • 분리된 문자열로는 검색할 수 없다. 
  • Text
    • 사이즈가 큰 문자열을 저장할 때 사용 
    • 'Analyzer'를 통해 문자열이 분리된 토큰으로 저장되기 때문에 문자열 내 단어들로 검색할 수 있다. 
    • 전문 검색이 필요할 경우에 사용하는 것이 좋음 
    • sorting, aggregation에 사용은 가능하나 성능 문제로 사용시 주의가 필요하다. 
      • Text & Keyword
        • 타입은 text이지만 aggregation 이나 sorting을 해야하는 경우에는 아래와 같이 사용한다. 
        • city의 타입은 text이지만 city.raw 필드의 type은 키워드로 준다. 
PUT my_index
{
  "mappings": {
    "properties": {
      "city": {
        "type": "text",
        "fields": {
          "raw": { 
            "type":  "keyword"
          }
        }
      }
    }
  }
}

PUT my_index/_doc/1
{
  "city": "New York"
}

PUT my_index/_doc/2
{
  "city": "York"
}

GET my_index/_search
{
  "query": {
    "match": {
      "city": "york" 
    }
  },
  "sort": {
    "city.raw": "asc" 
  },
  "aggs": {
    "Cities": {
      "terms": {
        "field": "city.raw" 
      }
    }
  }
}

 

(참고 : https://www.elastic.co/guide/en/elasticsearch/reference/6.5)

 

  • Near Real Time
    • Elasticsearch 는 실시간 검색 플랫폼
    • 인덱스 생성 시점부터 검색 가능 시간까지 약간의 대기 시간 (보통 1 초)이 있긴 하다.

 

  • Cluster
    • 모든 데이터를 보유하고 있는 노드들의 집합
    • 모든 노드에 검색할 수 있고, 연합된 인덱싱을 제공한다.
    • 클러스터의 default 이름은 "elasticsearch"
    • 노드가 클러스터의 이름으로 클러스터에 join하게끔 설정되어 있을 수 있으니, 클러스터 이름을 중요시하자!
    • 다른 환경에서 같은 클러스트 이름을 쓰게 되면 노드가 엉뚱한 클러스터에 join되는 결과를 맞볼 수 있으니 같은 이름을 쓰지 않게 주의하자.
    • Cluster 건강한지 확인하기 (ㅋㅋ)
      • GET /_CAT/health?v
        • Green : 굿
        • Yellow : 몇몇 replicas(아래 설명 참고)가 아직 할당되지 않은 상태
        • Red : 일부 데이터 not avliable

 

  • Node
    • 클러스터의 일부로써, 데이터를 저장하고 검색하는 기능을 하는 단일 서버
    • 노드이름은 중요하다 (클러스터 이름과 마찬가지로)
      • 왜 ? 나의 네트워크의 이름은 네트워크의 어떤 서버가 Elasticsearch 클러스터의 어떤 노드에 해당하는지 식별하려는 관리 목적에 중요합니다.
    • 클러스터 안에 여러개의 노드를 가질 수 있음 
    • 노드 하나로 운영할 땐 굳이 클러스터 구성 설정을 따로하지 않아도 된다. 
    • 관계형 데이터베이스와는 다르게 하나의 서버에 데이터가 다 저장되는 것이 아니라 여러개의 노드에 데이터가 저장되고 이것이 전부 모여 엘라스틱서치 서버를 만들게 된다. 
      • 데이터노드 : 데이터가 저장되는 노드로 샤드가 배치되는 곳이다. 
      • 마스터 노드 : 인덱스 샌성/삭제와 같은 클러스터 관련 전반적인 작업을 하는 곳이다.
      • 인제스트 노드 : 데이터를 전처리해준다.
      • 코디네이팅 노드 : 요청을 분산시켜준다.

 

  • Index
    • 관계형 데이터베이스의 '데이터베이스' 와 비슷
    • 차이라면 엘라스틱서치는 여러 인덱스를 동시에 검색할 수 있게 하였음 (=Multi Tenancy)

 

 

  • Shard
    • 인덱스 내부에 쪼개진 데이터들
    • 왜 쪼개나?
      • 대량의 데이터를 저장하면 단일 노드 서버의 하드웨어 용량을 초과할 수 있기 때문에
      • 엘라스틱 서치는 대량의 데이터를 다루는 서비스이기 때문에 데이터가 많아지면 노드를 구분하고, 구분하면서 데이터들이 쪼개지게 된다. 
      • 이렇게 쪼개면 볼륨을 분할하는 효과를 가져오기 때문에 성능/처리량이 증가한다. 
    • 프라이머리 샤드
      • 데이터의 원본
    • 레플리카 샤드
      • 프라이머리 샤드의 복제본
      • 중요함! Whay?
        • 샤드나 노드가 실패할 경우 고가용성을 제공하는데 이런 이유로 레플리카 샤드는 원본/기본 샤드와 동일한 노드에 할당되지 않는다.
        • 이 뜻은 무엇이냐면..
          • 검색 볼륨/처리량을 향상 시키는 동안에도 끊김 없이 처리 가능하다는 뜻
          • 왜냐하면 그동안 레플리카 샤드한테 처리하라고 시키면 되기 때문 

 

  • Document
    • 데이터 최소 단위
    • row
    • JSON Object

 

 

  • Field
    • 관계형 데이터베이스의 '열(Column)'
    • 관계형 데이터베이스의 열과 다른점?
      • 하나의 필드가 여러 개의 데이터 타입을 가질 수 있음

 

  • Mapping
    • 데이터 타입 지정 등의 필드 속성 정의

 

 

엘라스틱 공식문서를 참고하여 짧은 영어 실력으로 번역하고 이해한 내용을 정리하였습니다.

초보 개발자이니 틀린 부분이 있다면 언제든지 얘기해주세요 ^^

(참고 : https://www.elastic.co/guide/en/elasticsearch/reference/6.5)

  • Pretty Results
    • 요청할 때 ?pretty=true 를 붙여주면 JSON 결과를 보기 좋게 변경해준다. 
  • Human readable output
    • query string에 ?human=false 를 붙여주면 사람이 사용하는 용도가 아닌 모니터링 도구에 의해 사용될 때 의미 있는 통계 결과가 나온다.  
  • Date Math
    • gt & lt -> range query에서 사용
    • from & to -> aggregations 에서 사용 
    • +1h , -1d , /d 
      • ex) now-1h
    • y = years, M = months, w = weeks, d = days, h = hours, H = hours, m = minutes, s = seconds
  • Response Filtering
    • Elasticsearch가 반환하는 응답 개수?내용?을 줄이기 위해 filter_path를 사용하는데 딱 필요한 데이터만 받고 싶을때 사용 가능함
    • 사용 예) took, hits._id 만 필요로 하는 경우
      • GET /_search?q=elasticsearch&filter_path=took,hits.hits._id,hits.hits._score
      • Response
        • { "took" : 3, "hits" : { "hits" : [ { "_id" : "0", "_score" : 1.6375021 } ] } }
    • wildcard (* , **) 사용 가능
    • - 사용가능
      • GET /_count?filter_path=-_shards
  • Flat Setting
    • ?flat_settings=true 해주면 결과가 flat하게 나온다 (기계가 더 이해하기 쉬운 버젼으로)
    • 근데 flat_settings=false (기본) 이랑 비교해봤을 때 나름의 매력이 또 있는 것 같음 ㅋㅋ
  • Enabling stack traces
    • 에러가 났을 때 ?size=surprise_me를 query string에 붙여 주면 아래와 같은 stacktrace를 확인할 수 있다.
    • Request
      • POST /twitter/_search?size=surprise_me&error_trace=true
    • Response
{
  "error": {
    "root_cause": [
      {
        "type": "illegal_argument_exception",
        "reason": "Failed to parse int parameter [size] with value [surprise_me]",
        "stack_trace": "Failed to parse int parameter [size] with value [surprise_me]]; nested: IllegalArgumentException..."
      }
    ],
    "type": "illegal_argument_exception",
    "reason": "Failed to parse int parameter [size] with value [surprise_me]",
    "stack_trace": "java.lang.IllegalArgumentException: Failed to parse int parameter [size] with value [surprise_me]\n    at org.elasticsearch.rest.RestRequest.paramAsInt(RestRequest.java:175)...",
    "caused_by": {
      "type": "number_format_exception",
      "reason": "For input string: \"surprise_me\"",
      "stack_trace": "java.lang.NumberFormatException: For input string: \"surprise_me\"\n    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)..."
    }
  },
  "status": 400
}
  • Request body in query string
    • POST request가 아닌데 request body가 있고, 이를 허용하지 않는 라이브러리의 경우에는 request body를 source query string으로 파라미터를 보내면 된다. 
    • 이때 반드시 source_content_type을 명시해 주기 (예를 들면 application/json)
  • Content-Type Requirements
    • request body 보낼 때 content-type header 명시해주기

 

 

엘라스틱 공식문서를 참고하여 짧은 영어 실력으로 번역하고 이해한 내용을 정리하였습니다.

초보 개발자이니 틀린 부분이 있다면 언제든지 얘기해주세요 ^^

(참고 : https://www.elastic.co/guide/en/elasticsearch/reference/6.5)

+ Recent posts