일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- jdbc
- 도메인 주도 개발 시작하기
- Spring Batch
- JPA
- 자동처리
- cicd
- 30기
- 교육기획팀
- 이펙티브자바
- 영속성
- GitHub Actions
- 자바 ORM 표준 JPA 프로그래밍
- ddd
- scheduling messages with rabbitmq
- 교육기획팀원
- reactive operaton
- rabbitmq-delayed-message-exchange
- JPQL
- delayed message plugin
- 밋업프로젝트
- RESTClient
- 객체지향 쿼리 언어
- kusitms
- Domain Driven Design
- 한국대학생it경영학회
- 최범균
- Spring
- java
- 큐시즘
- springboot
- Today
- Total
코딩은 마라톤
[Elastic Search] 시스템 구조 및 데이터 처리 본문
근황...
요즘 블로그 쓰는게 뜸하죠...
제가 이번주부터 회사 인턴으로 백엔드 개발자로 근무하게 되었습니다 !!!!!
많이 부족한 실력이지만 개인 공부도 열심히 하고 회사 일도 꼼꼼하게 해서 3개월 뒤에 좋은 개발자가 되었음 좋겠습니다~!
P.S 회사에서 사용하는 제 영어 이름은 Koi (코이) 입니다. 책에서 읽고 저의 모토랄까나.. 가치관과 가장 잘 맞는다고 생각해서 지었습니당
https://www.onday.or.kr/wp/?p=13410 (고른 이유가 궁금하시다면 이 글을 읽어보세요!)
회사에는 좋은 개발자들과 제가 성장할 수 있는 환경을 충분히 제공해주신 만큼 열심히 노력해서 코이처럼 대인이 되었음 좋겠습니다.
또한 성장에 그치지 않고 주변의 개발을 꿈꾸는 분들에게 좋은 환경을 제공해서 또 다른 코이가 생길 수 있음 좋겠습니다.
앞으로 열심히 해보겠습니다!
회사에서 Elastic Search(ES)를 사용하는데 ES에 대해 지식이 전무해서 공부하고 기록하려고 합니다.
Elastic 가이드 북 | Elastic 가이드북
이 가이드북은 출판을 위해 집필중이던 내용을 Elastic을 처음 시작하시는 분들께 도움이 되고 커뮤니티와 함께 완성 해 나가려는 목적으로 공개하게 되었습니다. 모든 문서에 대한 저작권은 저
esbook.kimjmin.net
이 가이드북을 보고 공부했습니다!
3. ES 시스템 구조
3.1 클러스터 구성
클러스터 및 노드
- ES는 대용량 데이터 증가에 따른 스케일 아웃과 데이터 무결성을 유지하기 위한 클러스터링을 지원한다.
- 항상 클러스터를 기본으로 동작하며 1개의 노드만 있어도 클러스터로 구성된다.
- 클라스터를 서버라 생각하고, 클라스터 안에 노드가 구성되어있다고 생각하면 된다.
- 노드 ↔ 클라이언트 통신을 위한 http 포트 (9200~9299)
- 노드 ↔ 노드 데이터 교환을 위한 tcp 포트 (9300~9399)
총 2개의 네트워크 통신을 열어둔다. 일반적으로 1개의 물리 서버마다 하나의 노드를 실행하는 것을 권장한다.
하지만 물리적인 서버 안에서 여러 개 노드 실행 또한 가능하다.
디스커버리
노드가 처음 실행 될 때 같은 서버, 또는 discovery.seed_hosts: [ ] 에 설정된 네트워크 상의 다른 노드들을 찾아 하나의 클러스터로 바인딩 하는 과정이다.

3.2 인덱스와 샤드
- 도큐먼트(document) : 단일 데이터 단위
- 인덱스(Index) : 도큐먼트를 모은 집합 # 혼동 주의 : 데이터 저장 단위인 인덱스는 인디시즈(indices)라 부른다.
- 색인 : 데이터를 ES에 저장하는 행위
인덱스는 기본적으로 샤드(shard)라는 단위로 분리 및 각 노드에 분산되어 저장된다.
- 샤드 : 루씬의 단일 검색 인스턴스

Document vs Shard
- Document는 ES에 저장되는 개별 데이터 항목으로써 Document를 인덱스에 저장한다.
- Shard는 ES 클러스터에서 데이터를 분산 저장하는 단위로써 인덱스를 하나 이상의 Shard로 분할시켜 확장성과 성능을 향상시킨다.
- 프라이머리 샤드와 복제본(Replica)
- 클라스터에 노드를 추가하게 되면 샤드들이 각 노드들로 분산되고 디폴트로 1개의 복제본을 생성한다.
- 프라이머리 샤드 : 처음 생성된 샤드
- 리플리카 : 복제본
- 당연한 말이지만 노드가 1개 있으면 리플리카는 존재하지 않는다.
- 프라이머리 샤드가 유실될 경우 리플리카가 프라이머리 샤드로 승격되며 다른 노드에 새로운 리플리카가 생성된다.
- 같은 "샤드와 리플리카는 동일한 데이터를 담고 있어 반드시 서로 다른 노드에 저장"된다.
- 데이터 가용성과 무결성을 보장한다.

3.3 마스터 노드와 데이터 노드
마스터 노드 (Master Node)
- ES 클러스터는 하나 이상의 노드로 구성되어 있다.
- 이 중 하나의 노드는 인덱스의 메타 데이터, 샤드의 위치와 같은 클러스터 상태 정보를 관리하는 마스터 노드의 역할을 수행한다.
데이터 노드 (Data Node)
- 실제로 색인된(저장된) 데이터를 저장하고 있는 노드
- 데이터 처리에만 집중한다.
Split Brain
- 마스터 후보 노드를 하나만 놓게 되면 유실 되었을 때 클러스터 전체가 작동을 정지할 위험이 생긴다.
- 그래서 최소한의 백업용 마스터 노드를 설정하게 되는데 이때 마스터 후보 노드들을 3개 이상의 홀수 개를 놓는 것을 권장한다.
- 왜 3개 이상 둬야 할까?
- 만약 짝수개일 경우, 마스터 후보 노드가 분리되면 각자가 서로 다른 클러스터에서 존재하며 동작하기 때문에 추후에 하나의 클러스터로 다시 합쳐지면 데이터 정합성에 문제가 생기고 데이터 무결성이 유지될 수 없다.
- 왜 3개 이상 둬야 할까?
- 결론 : Split Brain 문제를 피하고 싶으면
- 마스터 후보 노드 개수는 항상 홀수
- 가동을 위한 최소 마스터 후보 노드 설정은 (전체 마스터 후보 노드) / 2 + 1 로 설정
4. ES 데이터 처리
4.1 REST API
ES는 http 프로토콜로 접근이 가능한 REST API를 지원한다.
4.2 CRUD
구조
PUT/POST my_index/_doc
{
"name":"Koi",
"message":"안녕하세요 Koi"
}
GET/DELETE my_index/_doc/1
행위를 나타내는 메서드명으로 시작한다.
[PUT/POST] 접근할 인덱스를 지정한 후 Json을 통해 데이터를 입력한다.
[GET/DELETE] 접근할 도큐먼트 id를 지정해서 조회, 삭제한다.
입력 (PUT) ↔ 수정 (POST)
보통 삽입할 때 POST를 사용하지만 ES에선 입력이 PUT이고 수정이 POST이다.
4.3 벌크 연산
- 여러 명령을 배치로 수행하기 위해선 _bulk API를 사용한다.
- _bulk API로 index, create, update, delete의 동작을 할 수 있다.
- delete를 제외하고는 명령문과 데이터문을 한 줄씩 순서대로 입력하고 delete는 내용 입력이 필요 없기 때문에 명령문만 존재한다.
POST _bulk
{"index":{"_index":"test", "_id":"1"}}
{"field":"value one"}
{"index":{"_index":"test", "_id":"2"}}
{"field":"value two"}
{"delete":{"_index":"test", "_id":"2"}}
{"create":{"_index":"test", "_id":"3"}}
{"field":"value three"}
{"update":{"_index":"test", "_id":"1"}}
{"doc":{"field":"value two"}}
- 저장 과정
- test/_doc/1 -> field : value one 을 입력한다.
- test/_doc/2 -> field : value two 을 입력한다.
- test/_doc/2 -> delete 삭제한다.
- test/_doc/3 -> field : value three 을 입력한다.
- test/_doc/1 -> field : value two 으로 수정한다.
bulk 연산을 사용하는 것이 따로따로 저장하는 것보다 훨씬 빠르기때문에 대용량의 데이터를 저장할 때는 벌크 동작을 고려해보자!
4.4 검색 API - _search API
- 전체 도큐먼트 조회(match_all)
GET <인덱스명>/_search
- 쿼리를 통한 검색
GET <인덱스명>/_search?q=countryCode:KR
+ AND, OR, NOT 연산도 가능하다.
// AND
GET /<index명>/_search?q=id:KR AND id:US
// OR
GET /<index명>/_search?q=id:KR OR id:US
데이터 본문 (Data Body) 검색
- 데이터 본문 검색은 검색 쿼리를 데이터 본문으로 입력하는 방식이다.
- ES의 QueryDSL을 사용하며 쿼리 또한 json 형식으로 되어있다.
GET /test/_search
{
"query": {
"match": {
"id": "US"
}
}
}
이렇게 data body에 넣어서 쿼리 검색을 할 수 있다.
항상 “query” 지정자로 시작
멀티테넌시 (Multitenancy)
- ES는 여러 개의 인덱스를 한꺼번에 묶어서 검색할 수 있는 멀티테넌시를 지원한다.
- logs-2024-01, logs-2024-02 와 같이 날짜별로 저장된 인덱스들이 있다면 이 인덱스들을 모두 logs-*/_search 명령으로 한꺼번에 검색할 수 있다.
- 또는 logs-2024-01, logs-2024-02와 같이 쉼표로 나열할 수도 있다.
1. 쉼표로 구분
GET logs-2024-01,logs-2024-02/_search
2. 와일드카드 *로 구분
GET logs-2024-*/_search