사용자 지정 생성
개발 및 테스트
대기 없는 도메인(가용 영역 수 조절 가능)
가용 영역: 2-AZ
엔진 옵션: 2.7(최신)
인스턴스 유형: t3.small.search
노드 수: 2
노드당 EBS 스토리지 크기: 10
네트워크: 퍼블릭 액세스
세분화된 액세스 제어
마스터 사용자 생성
- 마스터 이름: skybluelee
- 마스터 암호: 대문자, 소문자, 숫자, 특수문자 포함.
- 액세스 정책: 세분화된 액세스 제어만 사용
AWS KMS 키 선택: AWS 소유 키 사용
고급 클러스터 설정 - 최대 절 수: 1024
도메인 엔드포인트를 복사하여 확인하면 OpenSearch는 http를 기반으로 API 호출이 되므로
{
"name" : "",
"cluster_name" : "",
"cluster_uuid" : "",
"version" : {
"distribution" : "opensearch",
"number" : "2.7.0",
"build_type" : "tar",
"build_hash" : "unknown",
"build_date" : "2023-06-28T07:07:20.444435752Z",
"build_snapshot" : false,
"lucene_version" : "9.5.0",
"minimum_wire_compatibility_version" : "7.10.0",
"minimum_index_compatibility_version" : "7.0.0"
},
"tagline" : "The OpenSearch Project: https://opensearch.org/"
}
와 같은 정보를 확인할 수 있음.
OpenSearch 대시보드 URL을 입력하면
를 확인할 수 있음.
대시보드를 클릭하면 데이터(나의 경우 기본으로 제공하는 sample data)를 대시 보드로 확인이 가능하며
Create Dashboard를 클릭하여 원하는 형식으로 시각화 가능
우측 상단의 시계 모양을 클릭하여 날짜 조정 가능.
해당 데이터를 클릭하면 Table, JSON 형태로 확인 가능.
REST API 형태로 원하는 값을 얻을 수 있음.
데이터가 존재하더라도 최초에는 보이지 않으므로 Create Index Patterns를 사용해야 함.
PUT /movie/_doc/1
{
"movieCode": 1,
"movieName": "기생충",
"movieEnName": "Parasite",
"prdtYear": "2019",
"repNationName": "Korea",
"regGenreName": "Drama"
}
{
"_index": "movie",
"_id": "1",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 2,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1
}
위의 예시와 같이 dynamic(schemaless) 보다는 어떠한 형태로 만들 것인지 사전에 정의함.
GET movie
{
"movie": {
"aliases": {},
"mappings": {
"properties": {
"movieCode": {
"type": "long"
},
"movieEnName": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"movieName": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"prdtYear": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"regGenreName": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"repNationName": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
},
"settings": {
"index": {
"creation_date": "1691126296150",
"number_of_shards": "5",
"number_of_replicas": "1",
"uuid": "xFHy8bE-QrOBR_pqDN-PSA",
"version": {
"created": "136287827"
},
"provided_name": "movie"
}
}
}
}
전체 데이터가 매우 많은데 아래와 같이 특정 값만 얻을 수 있다.
GET movie/_mapping
{
"movie": {
"mappings": {
"properties": {
"movieCode": {
"type": "long"
},
"movieEnName": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"movieName": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"prdtYear": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"regGenreName": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"repNationName": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
/_mapping, /_settings, ...
등 내부 값을 통해 설정 가능.
PUT /movie/_doc/1
{
"movieCode": 2,
"movieName": "기생충",
"movieEnName": "Parasite",
"prdtYear": "2019",
"repNationName": "Korea",
"regGenreName": "Drama"
}
{
"_index": "movie",
"_id": "1",
"_version": 2,
"result": "updated",
"_shards": {
"total": 2,
"successful": 2,
"failed": 0
},
"_seq_no": 2,
"_primary_term": 1
}
기존의 값을 수정하고 PUT하면 version이 변경되고, 검색하면 하나의 레코드만 발견(덮어 씌워짐).
여러번 색인을 하더라도 _id
(RDS의 PK)를 기준으로 멱등성을 보장.
GET _cat/indices?s=i:desc
green open opensearch_dashboards_sample_data_ecommerce p1Fw0EmgTr6jdCsO1sVpBA 1 1 4675 0 8.6mb 4.2mb
green open movie xFHy8bE-QrOBR_pqDN-PSA 5 1 1 0 15.2kb 7.6kb
green open .opensearch-observability lWwoVHXtQeqpyH9fuKgv_g 1 1 0 0 416b 208b
green open .opendistro_security mN2IbVM8SsS1p7oxfehVRg 1 1 10 4 144.9kb 74.8kb
green open .kibana_1 s4WstkjUSRqv2k5eV6DmEg 1 1 39 0 67.1kb 30.2kb
DELETE movie
{
"acknowledged": true
}
GET _cat/indices?s=i:desc
green open opensearch_dashboards_sample_data_ecommerce p1Fw0EmgTr6jdCsO1sVpBA 1 1 4675 0 8.6mb 4.2mb
green open .opensearch-observability lWwoVHXtQeqpyH9fuKgv_g 1 1 0 0 416b 208b
green open .opendistro_security mN2IbVM8SsS1p7oxfehVRg 1 1 10 4 144.9kb 74.8kb
green open .kibana_1 s4WstkjUSRqv2k5eV6DmEg 1 1 39 0 67.1kb 30.2kb
movie index가 사라진 것을 확인.
GET _template
를 통해 확인
"index": false,
의 경우 데이터 확인은 가능하나 해당 데이터를 filtering하는 것은 불가능하다. 위처럼 지정하는 경우 저장 공간을 줄이는 이점이 있다.
POST _template/movie_template
{
"index_patterns": ["movie*"],
"aliases": {
"movie": {}
},
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0
},
"mappings": {
"dynamic": false,
"properties": {
"movieCode": {"type": "long"},
"movieName": {"type": "keyword"},
"movieEnName": {"type": "keyword", "index": false},
"prdtYear": {"type": "keyword", "index": false},
"repNationName": {"type": "keyword", "index": false},
"regGenreName": {"type": "keyword", "index": false},
"eventTime": {"type": "date", "format": "yyyy-MM-dd HH:mm:ss"}
}
}
}
{
"acknowledged": true
}
GET _template/movie_template
를 통해 확인 가능.
PUT /movie-test-1/_doc/1
{
"movieCode": 1,
"movieName": "기생충",
"movieEnName": "Parasite",
"prdtYear": "2019",
"repNationName": "Korea",
"regGenreName": "Drama",
"eventTime": "2023-01-01 00:00:00"
}
GET movie-test-1
{
"movie-test-1": {
"aliases": {
"movie": {}
},
"mappings": {
"dynamic": "false",
"properties": {
"eventTime": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
},
"movieCode": {
"type": "long"
},
"movieEnName": {
"type": "keyword",
"index": false
},
"movieName": {
"type": "keyword"
},
"prdtYear": {
"type": "keyword",
"index": false
},
"regGenreName": {
"type": "keyword",
"index": false
},
"repNationName": {
"type": "keyword",
"index": false
}
}
},
"settings": {
"index": {
"creation_date": "1691131690706",
"number_of_shards": "1",
"number_of_replicas": "0",
"uuid": "GP4RQQHbR9ySO3Ngc8-AXQ",
"version": {
"created": "136287827"
},
"provided_name": "movie-test-1"
}
}
}
}
template에서 ["movie*"]
를 사용해 movie로 시작하면 해당 template을 사용하도록 하였고, movie-test-1이 지정한 template 형태로 나옴.
GET _cat/indices?s=i:desc
...
샤드 수/ 레플리카 수 / document 수
green open movie-test-1 GP4RQQHbR9ySO3Ngc8-AXQ 1 0 1 0 5.2kb 5.2kb
...
GET movie/_search
{
"took": 91,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 1,
"hits": [
{
"_index": "movie-test-1",
"_id": "1",
"_score": 1,
"_source": {
"movieCode": 1,
"movieName": "기생충",
"movieEnName": "Parasite",
"prdtYear": "2019",
"repNationName": "Korea",
"regGenreName": "Drama",
"eventTime": "2023-01-01 00:00:00"
}
}
]
}
}
aliases
를 movie로 주었기 때문에 movie에 대해 검색해도 값이 제대로 나옴.
Create Index Pattern
-> next step
event time 지정하여 생성
Discover에서 새로운 Index 생성 확인.
Create policy -> Visual editor의 경우
{
"policy": {
"description": "movie policy",
"default_state": "hot",
"states": [
{
"name": "hot", // hot 상태일 경우
"actions": [
{
"replica_count": {
"number_of_replicas": 1 // replica를 1로 설정하고
}
}
],
"transitions": [
{
"state_name": "cold",
"conditions": {
"min_index_age": "1d" // 1일이 지나면 cold로 이동
}
}
]
},
{
"name": "cold",
"actions": [
{
"replica_count": {
"number_of_replicas": 0 // cold 상태일 경우 replica는 0
}
}
],
"transitions": []
}
],
"ism_template": {
"index_patterns": [
"movie*"
]
}
}
}
원하는 index를 지정하고 Apply policy를 사용하여 지정한 policy에 지정.
PUT _ingest/pipeline/movie_pipeline
{
"description": "movie ingest",
"processors": [
{
"date_index_name" : {
"field" : "eventTime",
"date_formats": ["yyyy-MM-dd HH:mm:ss"], // template 값과 동일하게
"index_name_prefix" : "movie-", // movie로 시작
"index_name_format": "yyyy-MM", // 월 까지만 적용
"date_rounding" : "M" // Month로 뒤의 Day는 삭제
}
}
]
}
추가 date 관련 parameter는 Date index name processor 참조.
GET _ingest/pipeline/
{
"movie_pipeline": {
"description": "movie ingest",
"processors": [
{
"date_index_name": {
"field": "eventTime",
"date_formats": [
"date_time_no_millis"
],
"index_name_prefix": "movie-",
"index_name_format": "yyyy-MM",
"date_rounding": "M"
}
}
]
}
}
POST _template/movie_template
{
"index_patterns": ["movie*"],
"aliases": {
"movie": {}
},
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0,
**"default_pipeline": "movie_pipeline"**
},
"mappings": {
"dynamic": false,
"properties": {
"movieCode": {"type": "long"},
"movieName": {"type": "keyword"},
"movieEnName": {"type": "keyword", "index": false},
"prdtYear": {"type": "keyword", "index": false},
"repNationName": {"type": "keyword", "index": false},
"regGenreName": {"type": "keyword", "index": false},
"eventTime": {"type": "date", "format": "yyyy-MM-dd HH:mm:ss"}
}
}
}
default_pipeline
에 ingest로 생성한 movie_pipeline을 지정.
PUT /movie-test-1/_doc/1
{
"movieCode": 1,
"movieName": "기생충",
"movieEnName": "Parasite",
"prdtYear": "2019",
"repNationName": "Korea",
"regGenreName": "Drama",
"eventTime": "2023-01-01 00:00:00"
}
{
"_index": "movie-2023-01",
"_id": "1",
"_version": 1,
"result": "created",
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1
}
pipeline을 통해 인덱스가 movie-
+ yyyy-MM
인 상태로 생성됨.
GET _cat/indices?s=i:desc
green open opensearch_dashboards_sample_data_ecommerce p1Fw0EmgTr6jdCsO1sVpBA 1 1 4675 0 8.6mb 4.2mb
green open movie-2023-01 bOLMXoYbRFKqxP0jPFG8Yw 1 0 1 0 5.2kb 5.2kb
green open .opensearch-observability lWwoVHXtQeqpyH9fuKgv_g 1 1 0 0 416b 208b
green open .opensearch-notifications-config AXJlByS2Qd-3WqNhQe4tPw 1 1 0 0 416b 208b
green open .opendistro_security mN2IbVM8SsS1p7oxfehVRg 1 1 10 4 144.9kb 74.8kb
green open .opendistro-job-scheduler-lock p3ifnN_OQBa0ltK3Ydj3Rg 5 1 1 1 54.8kb 49.1kb
green open .kibana_1 s4WstkjUSRqv2k5eV6DmEg 1 1 40 0 73.4kb 36.7kb
alias를 주었으므로 GET movie/_search, GET movie-2023-01/_search
두 명령어로 위에서 생성한 데이터를 검색할 수 있음.
주로 ingest할 때 제대로 동작하는지 시간을 확인하는 용도로 사용. 기존 데이터에 있는 date값이 아니라 ingest하는 시간을 삽입.
PUT _ingest/pipeline/movie_pipeline
{
"description": "movie ingest",
"processors": [
{
"date_index_name" : {
"field" : "eventTime",
"date_formats": ["yyyy-MM-dd HH:mm:ss"],
"index_name_prefix" : "movie-",
"index_name_format": "yyyy-MM",
"date_rounding" : "M"
},
"set": {
"field": "indexedTime",
"value": "{{_ingest.timestamp}}"
}
}
]
}
set 부분이 추가됨.
GET movie-2023-01/_search
{
"took": 22,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 1,
"hits": [
{
"_index": "movie-2023-01",
"_id": "1",
"_score": 1,
"_source": {
"repNationName": "Korea",
"movieEnName": "Parasite",
"indexedTime": "2023-08-04T08:24:04.508968667Z",
"prdtYear": "2019",
"regGenreName": "Drama",
"eventTime": "2023-01-01 00:00:00",
"movieCode": 1,
"movieName": "기생충"
}
}
]
}
}
데이터를 확인하면 indexedTime에 현 시간을 확인할 수 있음.
데이터에서는 IndexedTime을 확인할 수 있으나 최초에 index pattern을 생성할 때
Time field로 eventTime만을 지정하였기에 IndexedTime을 확인할 수 없음. 따라서 새로운 index pattern을 생성해야 함.
POST _template/movie_template
{
"index_patterns": ["movie*"],
"aliases": {
"movie": {}
},
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0,
"default_pipeline": "movie_pipeline"
},
"mappings": {
"dynamic": false,
"properties": {
"movieCode": {"type": "long"},
"movieName": {"type": "keyword"},
"movieEnName": {"type": "keyword", "index": false},
"prdtYear": {"type": "keyword", "index": false},
"repNationName": {"type": "keyword", "index": false},
"regGenreName": {"type": "keyword", "index": false},
"eventTime": {"type": "date", "format": "yyyy-MM-dd HH:mm:ss"},
"IndexedTime": {"type": "date"}
}
}
}
IndexedTime이 template에 존재하지 않아 index pattern create에 들어가도 값이 나오지 않음. 따라서 미리 수정.
Time field에 IndexedTime를 사용하여 Discover에서 IndexedTime를 기준으로 데이터를 확인할 수 있음.
글 재미있게 봤습니다.