강의 Summary
ElasticSearch 소개
Lucene 기반의 오픈 소스 검색 엔진이라고 소개를 해주는데 여기서 Lucene 이란 색인과 검색 기능을 제공하는 자바 라이브러리이다 ElasticSearch 는 JSON 기반의 문서를 저장, 검색할 수 있고 추가로 분석까지 가능하다
특징
준실시간 검색 시스템 > 거의 실시간으로 검색되는 수준의 속도(refresh_interval 이라는 환경설정으로 속도를 지정하는 것도 가능-default 1초)
고가용성을 위한 클러스터 구성 > 하나 이상의 노드로 구성해서 높은 수준의 안정성을 보여주고 부하 분산이 가능
동적 스키마 생성 > RDBMS 을 사용할때를 생각해보면 스키마를 생성해야 해당 스키마에 데이터를 집어넣을 수 있는 구조였는데 여기선 동적으로 만들기 때문에 따로 미리 정의할 필요 없으
Rest API 기반의 인터페이스 > 단순하게 쏴주기만 하면 Elastic Search을 사용할 수 있다
클러스터와 노드 이해하기
클러스터란 ? 컴퓨터 클러스터란 여러대의 컴퓨터들이 연결되어 하나의 시스템처럼 동작하는 컴퓨터들의 집합을 의미
ElasticSearch도 여러대의 노드들이 클러스터 구성으로 되어있음
노드의 종류
마스터 노드 > 클러스터 상태 관리 및 메타 데이터 관리
데이터 노드 > 문서 색인 및 검색 요청 처리
코디네이팅 노드 > 검색 요청 처리
인제스트 노드 > 색인되는 문서의 데이터 전처리(데이터 수정)
마스터 노드는 하나만 존재하는 것이 아닌 마스터노드, 마스터 후보노드(Master-eligible)들(N개)로 구성이 되어있음 노드를 설정하는데 있어서 config 에서 master:true 해주면 만약에 현재 마스터 노드가 죽게되면 나머지 마스터 후보들 중에서 하나가 새로운 마스터가 됨
클러스터 구조를 가짐으로써 가지는 장점은 역시 마스터가 죽거나 문제가 생겨도 다른 마스터를 통해서 어떤 노드에 요청을 해도 동일한 응답을 주는 것이 포인트이다
사용자가 어떤 특정 데이터를 찾기 위해서 마스터노드에게 요청을 하든, 데이터 노드에게 요청을 하든, 코디네이팅 노드에게 요청을하든 모두 동일한 값을 준다는 것이다 이렇게 어떤 노드를 통하든 내부적으로 알아서 돌고돌아서 동일한 값을 전달해줄 것이기 떄문에 각각의 노드가 본연의 역할에 정확하게 맞게 동작할 수 있도록 클러스터를 구성하는 것이 아주 중요 그래서 각 역할별로 라우팅이 되게 해주도록 노드밸런싱을 통해서 부하가 가지 않도록 처리하고 각각의 노드에 맞게 라우팅되도록 구성해야 함
인덱스와 샤드
RDBMS 와의 비교를 해서 개념을 이해하면 좋음 RDBMS에서의 database == ES에서의 index RDBMS에서의 schema == ES에서의 mapping RDBMS에서의 document == ES 에서의 row
ES에서의 인덱스란 > 문서(document) 가 저장되는 논리적인 공간 (필수적으로 구성이 되어 있어야 document 을 저장하는 것이 가능) 요걸 설계하는 것이 ES 을 사용하기 위해서 고려해야하는 가장 첫 번쨰 단계이고 중요하다 인덱스를 설계하는 예시를 보여줬는데 예시를 이러했다 > 도서관 색인 서비스를 설계하는데 있어서 book, magazine, dvd 이렇게 인덱스를 세부적으로 나눌 것인지, 그냥 library 라고 인덱스를 만들고 type 으로 나눌 것인지 하나의 인덱스를 가지고 사용하게 되면 관리해야할 인덱스의 수가 적기 때문에 관리 리소스를 적게 잡아먹지만, 쿼리와 문서의 구조가 복잡해짐 여러개의 인덱스를 나누면 최적화된 쿼리와 문서 구조를 사용하는 것이 가능하지만, 관리해야할 인덱스가 그만큼 많아져서 관리 리소스가 발생할 수 있음 그래서 추천해주는 방식은 우선은 하나의 인덱스로 구성을 먼저 해두고 수요가 많아지거나 성능을 요하는 일이 생기면 그때 나누는 구성을 해야한다 약간 엔티티를 먼저 만들고 이 엔티티를 포함하는 ES 전용 DTO로 해서 우선은 먼저 저장을 하는 방식을 활용해서 구성을 해두고 나중에 성능을 더 요하거나 필요하면 그때는 직접 엔티티를 ES 의 인덱스로해서 활용하는 요러한 느낌으로 가면 좋을듯
ES에서의 샤드란 > 인덱스에 색인되는 문서가 저장되는 공간(단순하게 값을 저장하는 공간)이고 하나의 인덱스는 반드시 하나 이상의 샤드를 갖는다 종류로는
프라이머리 샤드 : 문서가 저장되는 원본 샤드, 색인과 검색 성능에 모두 영향을 준다
레플리카 샤크 : 프라이머리 샤드의 복제 샤드로, 검색 성능에 영향을 주고 클러스터 구조로 되어 있어서 프라이머리에 문제가 생기면 승격 가능
샤드의 설정은 인덱스를 설정할 떄 number_of_shards, number_of_replicas 설정을 통해서 설정하는 것이 가능한데 number_of_shards 는 진짜 프라이머리 샤드의 갯수를 지정하는 것이고 number_of_replicas 는 각 프라이머리 샤드의 replica 갯수를 의미한다 따라서 replicas 샤드의 수는 number_of_shards * number_of_replicas 이라고 볼 수 있다
샤드의 라우팅 문서들은 알아서 샤드에 골고루 저장이 되는 방식인데 알아서 골고루 저장이 되기는 하지만 요건 샤드의 갯수에 따라서 저장되는 규칙이 변경되는 방식인 점을 기억해두자 routing rule = 문서ID % 샤드의갯수 가장 중요한 결론은 이렇다 = 인덱스를 생성할 때 있어서 프라이머리 샤드의 갯수를 설정하는 것이 아주 중요하다 왜냐하면 인덱스를 생성하고 나서는 갯수를 나중에 변경할 수 없기 떄문 기본값으로는 number_of_shards 은 한 개로 설정되어 있는데 1로 그대로 사용하게되면 성능상 아주 큰 영향을 끼칠 수 있다
이렇게 프라이머리 샤드 갯수를 일일이 설정하는 것이 빡세니, 인덱스 템플릿 이라는 것을 사용해서 한꺼번에 처리하는 것이 가능하기도 하다
매핑
매핑은 위에서 잠깐 작성했던 것과 같이 RDBMS 에서의 schema 와 유사한 의미를 가지고 있다 즉, 문서의 구조를 나타내는 정보라고 볼 수 있다
매핑의 종류
동적 매핑 > 처음 색인되는 문서를 바탕으로 매핑 정보를 ES가 동적으로 생성
정적 매핑 > 문서의 매핑 정보를 미리 정의
동적 매핑은 미리 스키마를 정의할 필요가 없고 처음 문서를 자동으로 매핑을 만들어낸다 뭐 만약에 처음 등록한다고 가정했을 때 각 필드의 이름을 구분해서 각 필드의 타입을 가져와서 알아서 촤라락 등록해준다 매핑 생성해둔 다음에 타입에 대한 error 는 존재하니 주의 정적 매핑은 우선은 기존에 RDBMS 에서 하는 것 처럼 먼저 설정하는 방식이다 그래서 요런걸 같이 활용해서 어떠한 인덱스를 넣을 때 무조건적으로 필요한 건 미리 정적 매핑을 통해서 등록을 해둔 다음, 나머지 유동적이나 모호한건 동적 매핑을 통해서 등록할 수 있는 이러한 유연한 인터페이스로써 활용할 수 있다 정적 매핑은 문서의 필드들이 가지는 값에 따라서 타입을 지정할 때 사용하거나 불필요한 색인이 발생하지 않게 하기 위해서 사용한다고 인지해두자
색인 과정
색인은 인덱스를 생성하고, 매핑을 검증하고 inverted index 을 생성하고 문서를 저장하는 과정 데이터 노드를 구성하는데 있어서 프라이머리와 레플리카 샤드의 숫자를 지정해두는데, 데이터 노드의 수와 이 샤드의 사이즈를 알맞게 지정해주어야 완벽한 구성을 하는 것이 가능하다 애초에 처음부터 완벽하게 샤드의 사이즈를 맞추는 것은 불가능하다 >> 각각의 유즈케이스를 통해서 맞춰가는 것이 중요함 색인 성능에 대해서 고민을 할 때는 가능한 모든 데이터 노드들이 색인 과정에 참여할 수 있도록 클러스터 구조로써 잘 기능하고 있는지에 대해서 중점적으로 확인하라
검색 과정
아래와 같은 단계로 구성되어있음 검색어 분석 > inverted index 검색 > 결과 표시
inverted index 란, 문자열을 분석한 결과를 저장하고 있는 구조체 라고 생각 inverted index에는 token 이라고 해서 문자열 같은 경우에는 각각의 문자열에서 공백을 제외한 단어를 기준으로해서 단어들을 token 이라는 곳에서 저장을 하고 있으며 각 토큰이 어디 document, 즉 몇번째 document 에 있는지도 저장을 하고 있다
여기서 inverted index 에서 토큰을 만들어내는 놈들을 Analyzer 라고 한다 - 추후에 필요하면 커스텀이 필요하다(한글.. 도 해야하나..?) /_analyze 을 통해서 내가 원하는 대로 토크나이징이 되고 있는지에 대해서 분석 가능 검색 요청은 프라이머리 샤드에서만 가능했던 색인 과정과는 다르게 프라이머리 샤드와 레플리가 샤드 모두 사용할 수 있다 검색요청에 대해서 뭔가 클러스터 구조를 변경하고 싶을 떄는 레플리카 샤드의 숫자 조절을 통해서 구성할 수 있다, 프라이머리와는 다르게 레플리카 샤드는 동적으로 운영중에서도 숫자의 구성을 변경하는 것이 가능하니 데이터 노드에 균등하게 레플리카가 배치될 수 있도록 구성하는 것이 중요 색인 요청과 동일하게, 검색성능에 대해서 문제가 있다면 가능한 모든 데이터 노드들이 참여하고 있는지, 클러스터의 구조가 잘 기능되고 있는지에 대해서 확인이 필요
text, keyword 타입이해하기
해당 두 타입은 모두 문자열을 나타내기 위한 타입이다 text 타입 같은 경우에는 full-text search 을 위해서 토큰이 생성됨, 즉 검색을 위해서 토큰이 생성되는 방식이고 keyword 같은 경우에는 exact matching 을 위해서 토큰이 생성됨, 즉 정확하게 일치하는 것을 찾기 위해서 토큰이 생성되는 방식이다 요런거 확인하는 가장 베스트 방식은 /_analze 을 통해서 토크나이저가 어떻게 되는지에 대해서 확인하느 것이 좋음
입력한 문자열에 100% 완벽하게 맞는것을 찾고 싶을 때는 keyword 으로해서 찾으면 되고 입력한 문자열을 공백별로 찢어서 찾고 싶을 때는 standard(text인듯?) 으로 해서 찾으면 된다 그래서 keyword 으로해서 /_analyze 하면 fulltext로 토큰화된 것을 확인할 수 있고 standard(text) 으로 /_analyze 하면 각각 나뉜다 두 타입에 속도 차이는 keyword 가 fulltext으로 토큰이 하나만 만들어짐으로 속도는 더 빠르다 근데 처음에 매핑을 진행할 때, 문자열 필드가 동적으로 매핑되면 text, keyword 2개가 모두 만들어진다 그래서.. 약간 이런건 정적으로 미리 매핑설정을 통해서 필요에 따라서 미리 설정해주면 원하는 방향대로만 검색되니 미리 설정해주는게 성능상으로도 좋음
cat API 활용하기
ES 의 클러스터 구조를 모니터링하는 방식을 의미한다 cat(Compact and Aligned Text)의 약자이고 클러스터의 정보를 사람이 보기 쉽게 출력해주는 용도의 api 현재 기준으로는 20개 이상의 api 을 제공해주고 있으며 공식문서에서 지원해주는 것으로 보아 구글링해서 찾아가면 될듯함
그 중에서 가장 많이 쓰이는 걸로 골라서 보자 GET /_cat/health?v >> ES 클러스트의 전반적인 상태를 확인할 수 있음 여기서 status 라는 항목이 존재하는데 나올 수 있는 값을 리스팅을 해보면 이러하다
green : 프라이머리 샤드, 레플리카 샤드 모두 각 노드에 배치되어서 동작 중
yellow : 프라이머리 샤드는 장상적으로 동작하고있는데, 몇개의 레플리카 샤드가 배치완료되지 않은 상황이여서 색인에는 문제 없지만 검색에는 성능적으로 문제가 있을 수 있음
red : 일부의 프라이머리 샤드와 레플리카 샤드가 배치되지 않아서 불안정함으로 문서 유실이 일어날 수도 있음
GET /_cat/nodes?v >> ES 의 노드의 정보를 확인할 수 있음 여기서 중요한 node.role 에 대한 정보가 튀어나오는데 여기서 master, data, injest 등등에 대한 정보들이 적혀있음 요거 암호화처럼 되어있는데 공식문서에 있다니까 구글링해보자 리눅스에서 --help 치는거 마냥 /_cat_nodes?help 으로 리스팅으로 쭉 뽑고 /_cat/nodes?h=ip 등등 이렇게 h 키워드를 사용해서 원하는 지표를 확인하는 것이 가능한까 필요하면 참고
GET /_cat/indices?v >> 인덱스의 상태를 확인할 수 있음 사실 클러스터의 상태는 인덱스의 상태라고 볼 수 있다네 그냥 유사하다고 판단하면 될 듯
GET /_cat/shards?v >> 샤드의 상태 확인 unassigned.reason 이라는 항목이 있는데 이걸 통해서 왜 병목이 일어나는지 문제의 이유에 대해서볼 수 있다 cat health > yellow네? > cat indices > 역시 yellow네?? > cat shards 이렇게 이유를 찾아볼 수 있을듯 이 unassigned.reason의 값들의 이유에 관해서는 공홈에도 있으니 필요하면 확인해보면 될듯
주요 모니터링 지표
회사에서 직접 사용해야할 ES 는 Self-Hosted ElasticSearch 인 케이스일 꺼고 요 케이스에서는 Kibana의 Stack Monitoring 을 사용할듯 추가로 프로메테우스로도 사용은 가능하다 stack monitoring 에서는 slack 으로 이슈를 전송하던가 이런 것도 가능한 것으로 보이네
알람으로 받아봐야할 사항들 CPU Usage > 노드가 얼마나 많이 호출되고 있느냐 Disk Usage > 노드가 얼마나 많은 document 을 저장하고 있느냐 Load > 노드가 얼마나 많은 CPU와 디스크 연산을 처리하고 있느냐 JVM Heap > 노드의 JVM 이 얼마나 많은 메모리를 사용하는가 Thread > 처리량을 넘어서는 색인/검색 요청이 있는가 - 처리량을 넘어가면 큐에다가 넣어놓고 메인스레드에서 작업 끝나면 가져가서 처리하고 그러는데 이것도 넘어가면 에러뱉음
문제 원인 파악하기 위한 사항들 Memory Usage > 노드에 설치되어있는 물리적 메모리의 사용량 Disk I/O > 노드에서 발생하는 디스크 연산의 지연 시간 GC Rate > 노드에서 발생하는 GC의 발생 주기 GC Duration > 노드에서 발생하는 GC의 소요 시간 Latency > 노드에서 색인 및 검색에 소요되는 시간 Rate > 노드에서 색인 및 검색 요청이 인입되는 양
Last updated
Was this helpful?