Open API 통해서 데이터를 긁어온 뒤 검색 엔진에 ElasticSearch를 연동하는 토이 프로젝트를 해보고 싶어서 사용 방법을 익히기 위해 설치를 진행했다. 새로운 내용을 학습할 때 인프런을 통해 많이 찾아보는 편인데 딱히 강의랄게 없어서 공식 홈페이지를 참고하거나 구글링과 유튜브의 힘을 빌려서 진행했다. ( 처음 하는건데 따라 할만한 명확한 참고 문서를 못 찾아서 하다가 조금 늙었다 )
개발환경
OS : Mac OS 13.4 / Mac m2
JDK : 17
ES ( ElasticSearch) 다운로드 및 실행
ES는 기본적으로 JVM 위에서 돌아가기 때문에, jdk는 설치되어 있어야 한다. 본 글에서는 jdk는 이미 설치되었다는 가정하에 글을 작성한다.
jdk를 설치했다면 두 번째로 해야 할 것은 ES 파일을 다운로드하는 것이다.
https://www.elastic.co/guide/en/elasticsearch/reference/current/targz.html
하단 링크를 참고해서 가장 최신 버전인 18.2.2 버전( aarch64 )을 다운로드하여줬다. ( 하지만 결국 나중에 문제가 생겨서 7.17.18로 다운그레이드 해서 재설치했다. ^_ㅠ 유튜브에 예제들도 대부분 7 버전이 많고 8 버전부터 SSL 도 default로 세팅되어 번거로우니 나처럼 처음 ES를 처음 사용해 보는 사람이라면 7 버전을 추천한다 )
원하는 위치에 파일을 이동시키고, 압축을 푼 뒤 bin 폴더에서./elasticsearch로 ES를 실행시킬 수 있다.
- 실행 명령어
./bin/elasticsearch
- 실행 결과
✅ Elasticsearch security features have been automatically configured!
✅ Authentication is enabled and cluster connections are encrypted.
ℹ️ Password for the elastic user (reset with `bin/elasticsearch-reset-password -u elastic`):
Nh2hN*_m1UPZjiQikgPh
ℹ️ HTTP CA certificate SHA-256 fingerprint:
eaa2ffa35a1e38e092e87ae456076fc1c609e2a4143ffe039d35ca0aa2f3e8d8
ℹ️ Configure Kibana to use this cluster:
• Run Kibana and click the configuration link in the terminal when Kibana starts.
• Copy the following enrollment token and paste it into Kibana in your browser (valid for the next 30 minutes):
eyJ2ZXIiOiI4LjEyLjIiLCJhZHIiOlsiMTkyLjE2OC4xLjY6OTIwMCJdLCJmZ3IiOiJlYWEyZmZhMzVhMWUzOGUwOTJlODdhZTQ1NjA3NmZjMWM2MDllMmE0MTQzZmZlMDM5ZDM1Y2EwYWEyZjNlOGQ4Iiwia2V5IjoiSDVQTE5vNEJ1Nk82TzNuNU5XSnY6U0o5UnlVNE9USnk3bTBhSFZLUEh0USJ9
ℹ️ Configure other nodes to join this cluster:
• On this node:
⁃ Create an enrollment token with `bin/elasticsearch-create-enrollment-token -s node`.
⁃ Uncomment the transport.host setting at the end of config/elasticsearch.yml.
⁃ Restart Elasticsearch.
• On other nodes:
⁃ Start Elasticsearch with `bin/elasticsearch --enrollment-token <token>`, using the enrollment token that you generated.
ES의 default port는 9200 이므로 http://localhost:9200로 접속하면?
오류가 뜬다.
- 오류 내용
curl: (52) Empty reply from server
https로 접속해야 하는데 http로 접속해서 문제가 된 것 같아서 https://localhost:9200으로 접속했더니 user / password를 호출하는 창이 떴다.
기본적으로는 user - elastic / password - 실행 시 뜨는 Password 값을 입력하면 정상적으로 호출되는 것을 볼 수 있다.
하지만 매번 입력하기도 귀찮고 curl 호출할 때 설정해 주기 번거로워서 다음과 같이 설정파일을 변경했다.
- 설정 파일 위치
/config/elasticsearch.yml
- 체크한 부분을 false로 변경
- ES 재실행 ( ctrl + c를 통해 종료할 수 있음 )
ES ( ElasticSearch) Index 생성해 보기 - GET / PUT / DELETE
기본적으로 ES는 restfulAPI 통신을 통해 동작한다. ES를 공부하다 보니까 RDB와 비교돼서 표현되는 경우가 많은데 간단하게 표로 나타내면 다음과 같다.
RestFul | RDB |
GET | select |
PUT | update |
POST | insert |
DELETE | delete |
- GET으로 인덱스 조회하기
curl -XGET http://localhost:9200/classes
위 내용으로 classes라는 인덱스에 대한 정보를 요청하면, 초기 요청이므로 classes 라는 인덱스가 없다고 오류가 발생한다.
- PUT으로 인덱스 생성하기
PUT을 통해 classes라는 인덱스를 생성하는 요청을 실행했다.
curl -XPUT http://localhost:9200/classes
정상적으로 실행 됐다면 아래와 같은 결과가 출력된다.
{
"acknowledged": true,
"shards_acknowledged": true,
"index": "classes"
}
// GET http://localhost:9200/classes 재호출한 결과
{
"classes": {
"aliases": {},
"mappings": {},
"settings": {
"index": {
"routing": {
"allocation": {
"include": {
"_tier_preference": "data_content"
}
}
},
"number_of_shards": "1",
"provided_name": "classes",
"creation_date": "1710318094329",
"number_of_replicas": "1",
"uuid": "Bm7VKC2dRSSP5wa_pfO3vA",
"version": {
"created": "8500010"
}
}
}
}
}
- DELETE로 인덱스 삭제하기
PUT을 통해 생성한 인덱스를 DELETE를 통해 제거할 수 있다.
curl -XDELETE http://localhost:9200/classes
정상적으로 실행되었을 때 응답은 다음과 같다.
{
"acknowledged": true
}
// GET http://localhost:9200/classes 재호출한 결과
{
"error": {
"root_cause": [
{
"type": "index_not_found_exception",
"reason": "no such index [classes]",
"resource.type": "index_or_alias",
"resource.id": "classes",
"index_uuid": "_na_",
"index": "classes"
}
],
"type": "index_not_found_exception",
"reason": "no such index [classes]",
"resource.type": "index_or_alias",
"resource.id": "classes",
"index_uuid": "_na_",
"index": "classes"
},
"status": 404
}
DELETE를 통해 삭제했기 때문에 index_not_found_exception 이 발생한 것을 알 수 있다.
ES ( ElasticSearch) Document 생성해 보기 - POST
document는 주로 인덱스가 있을 때 생성하지만 인덱스가 없을 경우 인덱스명과 타입명을 명시하면 도큐먼트 생성이 바로 된다.
- POST를 통해 Document 추가하기
curl -XPOST http://localhost:9200/classes/class/1/ -d '{"title" : "algorithm", "professor" : "John"}'
하지만 나는 안 됐다.
{"error":"no handler found for uri [/classes/class/1/] and method [POST]"}
야속하게도 이 오류가 계속 발생하면서 난관에 봉착했다.
구글링을 해도 EndPoint를 잘못 입력했다는 게 제일 많은 답변이었는데 내가 봤을 때 EndPoint는 문제가 없었고 ChatGPT 가 알려준 내용은 오늘 ES 걸음마를 시작한 내게는 큰 도움이 되지 못했다.
- ChatGTP의 친절한 답변
"no handler found for uri" 오류는 Elasticsearch에서 URI에 대한 핸들러가 없을 때 발생합니다. 이 오류가 발생하는 경우에는 다음과 같은 몇 가지 가능한 원인이 있을 수 있습니다:
잘못된 URI: 요청한 URI가 올바른 Elasticsearch 엔드포인트를 가리키지 않을 수 있습니다. URI를 확인하고 올바른 엔드포인트를 지정하는지 확인하십시오.
올바른 HTTP 메서드: Elasticsearch 요청에 사용된 HTTP 메서드가 해당 엔드포인트에서 허용되지 않는 경우에도 이 오류가 발생할 수 있습니다. 예를 들어, GET 메서드로는 문서를 생성할 수 없습니다. 올바른 메서드를 사용하는지 확인하십시오.
권한 및 권한 부족: Elasticsearch 클러스터에서 요청을 실행하는 데 필요한 권한이 부족한 경우에도 이 오류가 발생할 수 있습니다. Elasticsearch에 필요한 권한을 부여하고 권한이 올바르게 구성되어 있는지 확인하십시오.
Elasticsearch 클러스터 상태: Elasticsearch 클러스터 자체의 문제로 인해 요청이 처리되지 않을 수 있습니다. 클러스터의 상태를 확인하고 문제가 있는지 확인하십시오.
잘못된 Elasticsearch 버전: 사용 중인 Elasticsearch 클러스터와 호환되지 않는 Elasticsearch 클라이언트 라이브러리를 사용하는 경우에도 이러한 유형의 오류가 발생할 수 있습니다. Elasticsearch 클러스터와 일치하는 버전의 클라이언트 라이브러리를 사용하는지 확인하십시오.
그래서 위에 적은 대로 버전을 낮췄더니 해결이 됐다.
- 18.2.2 ->7.17.18로 다운그레이드 진행
바로 된 것은 아니고
{"error":"Content-Type header [application/x-www-form-urlencoded] is not supported", "status":406}
오류가 발생해서 curl 옵션에 -H를 추가해서 다음과 같이 호출하니 문제없이 동작했다.
curl -XPOST http://localhost:9200/classes/class/1/ -d '{"title" : "algorithm", "professor" : "John"}' -H 'Content-Type: application/json'
실행 결과는 다음과 같다
// GET classes/class/1 결과 _source 하위에 데이터가 들어간 모습을 확인할 수 있디
{
"_index": "classes",
"_type": "class",
"_id": "1",
"_version": 1,
"_seq_no": 0,
"_primary_term": 1,
"found": true,
"_source": {
"title": "algorithm",
"professor": "John"
}
}
ES ( ElasticSearch) Document 수정해 보기 - _update
- _update를 통해서 document 수정하기
_update 를 사용하면 지정한 인덱스에 있는 도큐먼트를 수정할 수 있다.
crul -XPOST http://localhost:9200/classes/class/1/_update -d '{"doc" : {"unit" 1}}' -H 'Content-Type: application/json'
실행 결과는 다음과 같다.
{
"_index": "classes",
"_type": "class",
"_id": "1",
"_version": 2,
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 1,
"_primary_term": 1
}
// GET http://localhost:9200/classes/class/1 로 확인한 모습
// _source 에 Unit 이 추가 된 것을 알 수 있음
{
"_index": "classes",
"_type": "class",
"_id": "1",
"_version": 2,
"_seq_no": 1,
"_primary_term": 1,
"found": true,
"_source": {
"title": "algorithm",
"professor": "John",
"unit": 1
}
}
- 스크립트를 사용해서 수정하기
제공하는 스크립트를 사용하면 데이터를 직접 지정하지 않고 수정도 가능하다.
curl -XPOST http://localhost:9200/classes/class/1/_update -d '{"script" : "ctx._source.unit +=5"}'
예를 들어 ctx._source.unit += 5라고 실행하면 결과는 다음과 같다.
{
"_index": "classes",
"_type": "class",
"_id": "1",
"_version": 4,
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 3,
"_primary_term": 1
}
// GET http://localhost:9200/classes/class/1
{
"_index": "classes",
"_type": "class",
"_id": "1",
"_version": 4,
"_seq_no": 3,
"_primary_term": 1,
"found": true,
"_source": {
"title": "algorithm",
"professor": "John",
"unit": 7
}
}
결과 값을 보면 unit 이 7로 업데이트 된 것을 확인할 수 있다. ( 중간에 내가 한번 더 unit : 2로 업데이트 실행을 진행해서 2 + 5 = 7 이 리턴됐다. )
ES ( ElasticSearch) 벌크(bulk) 사용하기 - _bulk
벌크를 사용하면 미리 작성해 둔 json 파일을 통해 데이터를 일괄로 업데이트할 수 있다.
- 기본 명령어
curl -XPOST http://localhost:9200/_bulk?pretty --data-binary @[파일명.json] -H 'Content-Type: application/json'
- 사용 예시
curl -XPOST http://localhost:9200/_bulk?pretty --data-binary @classes.json -H 'Content-Type: application/json'
ES ( ElasticSearch) 매핑(mapping) 사용하기 - _mapping
mapping을 사용하면 데이터를 시각화할 때 도움이 된다.
- 기본 명령어
curl -XPUT "http://localhost:9200/classes/class/_mapping' -d @[매핑기재파일명.json] -H 'ContentType: application/json'
- 사용 예시
curl -XPUT 'http://localhost:9200/classes/class/_mapping' -d @classesRating_mapping.json
-H 'Content-Type: application/json'
ES ( ElasticSearch) 검색 사용하기 - _search
_search를 사용해서 원하는 데이터를 조회할 수 있다.
- 기본 명령어
http://localhost:9200/인덱스/도큐먼트/_search
http://localhost:9200/인덱스/도큐먼트/_search -d '검색할 request body' 지정
request body 에는 다양한 옵션이 제공되는데 상세 내용은 하단 링크를 참조 바란다.
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-body.html
이상으로 ElasticSearch를 사용하기 위해 기본적으로 설치해 보고 restful 기반 요청을 보내서 index와 document를 생성하고 삭제해봤다.
나... 원하는 대로 구현할 수 있을까...?
'Dev > ELK' 카테고리의 다른 글
Springboot + ElasticSearch 연동하기 ( feat. RDBMS 에서 Like 를 사용할 때 보다 검색 속도가 얼마나 향상 될까? ) (1) | 2024.03.26 |
---|---|
ElaticSearch 란 무엇일까? 동작 방식을 이해해보자 (4) | 2024.03.14 |