728x90
구성
- 수집기
- 데이터 수집
- 스토리지
- 분리된 데이터를 저장
- 색인기
- 검색이 용이하게 수집된 데이터를 분리
- 검색기
- 사용자의 질의를 통해 데이터를 검색
인덱스
- 하나의 인덱스에는 하나의 타입만 존재
- HTTP의 RESTful api 사용하여 CRUD 처리
- RDBMS의 데이터베이스
- 엘라스틱서치를 분산 환경으로 구성하면 하나의 인덱스는 여러 노드에 분산 저장 됨
- GET
- 데이터 조회
- POST
- 인덱스 업데이트, 데이터 조회
- PUT
- 데이터 생성
- DELETE
- 데이터 삭제
- HEAD
- 인덱스 정보 조회
- 인덱스의 샤드 수를 조절하여 대용량 데이터 분산 처리
elasticsearch.yml
- cluster.name
- 클러스터 이름 설정
- node.name
- 노드명 설정
- path.data
- 인덱스 저장 경로
- path.log
- 노드와 클러스터에서 생성되는 log 저장
- path.repo
- 인덱스 백업 경로
- network.host
- 특정 IP만 엘라스틱 서치에 접근
- http.port
- 엘라스틱서치 서버에 접근 할 수 있는 API 호출을 위한 포트 지정(디폴트 : 9200)
- transport.tcp.port
- 클라이언트가 접속할 수 있는 TCP 포트 (디폴트 : 9300)
- discovery.zen.ping.unicats.hosts
- 노드가 여러개인 경우 유니캐스트로 활성화된 다른 서버 찾음(같은 클러스터내 다른 노드 host 설정)
- discovery.zen.minimum_master_nodes
- 마스터 노드의 선출 기준이 되는 노드 수 지정
- node.master
- 마스터 노드로 동작 여부 지정
- node.data
- 데이터 노드로 동작 여부 지정
샤드
- RDBMS의 파티션
- 색인된 데이터는 여러 개의 파티션으로 나뉘어지는데 이 파티션이 샤드임
타입
- RDBMS의 테이블
- 하나의 인덱스당 하나의 타입만 존재
문서
- RDBMS의 행
- 데이터의 최소 저장 단위로써 JSON 형태
필드
- RDBMS의 열
- 다수의 데이터 타입을 가질 수 있음
노드의 종류
- 클러스터는 물리적인 노드 인스턴스들의 모임
- 마스터노드
- 클러스터를 관리
- 노드 추가와 제거 같은 클러스터 전반적인 관리 담당
- 다수의 마스터 노드를 지정해도 하나만 선출되어 동작
- 데이터 노드
- 실제 데이터 저장
- 검색과 통계 같은 데이터 관련 작업 수행
- 샤드가 배치되는 노드
- 리소스 모니터링 필요
- 마스터 노드와 구분해서 구성
- 코디네이팅 노드
- 사용자의 요청만 받아서 처리
- 클러스터 관련 요청은 마스터 노드에 데이터 관련 요청은 데이터 노드에 전달
- 인제스트 노드
- 문서의 전처리 작업 담당
- 데이터 조회를 할때 마스터 노드를 통해 각 데이터 노드를 모두 조회해서 데이터를 취합한 후 결과를 하나로 합쳐 제고
인덱스 옵션
- number_of_shards : 샤드의 개수로 각 노드에 균일하게 분배
- nubmer_of_replicas : 샤드의 개수를 세트로 구분하여 복사본을 만듬
- 장애가 발생하면 마스터 노드는 데이터를 재분배 하거나 레플리카 샤드를 프라이머리 샤드로 승격시켜 장애를 복구
- 스키마리스 기능은 지양
노드설정
- action.auto_create_index : false
인덱스설정
- index.mapper.dynamic : false
- 인덱스 생성시 한번 생성된 매핑 정보는 변경할 수 없음
- 형태소 분석이 필요할 시 text 일반적인 문자는 keyword 사용
- 필드의 속성
- 데이터 타입
- 메타 데이터
- 매핑 정보 정의시 고려사항
- 문자열을 분석할 것인가?
- _source에 어떤 필드를 정의할 것인가 ?
- 날짜 필드를 가지는 필드는 무엇인가?
- 매핑에 정의되지 않고 유입되는 필드는 어떻게 처리할 것인가?
- 매핑 파라미터
- dynamic : 매핑에 필들르 추가할 때 동적으로 생성할지 말지 결정(true, false, strict)
- enabled: 검색 결과에는 포함하지만 색인은 하지 않을 경우 사용
- fields : 다중 필드를 설정할 수 있는 옵션, 필드안에 또 다른 필드의 정보를 추가
- null_value : 필드가 없거나 필드 값이 null 일때 해당 옵션을 지정하면 해당 값을 저장 함
- properties : 오브젝트 타입이나 중첩 타입을 정의할 때 사용되는 옵션
필드 데이터 타입
- keyword 타입
- 키워드 형태로 사용할 데이터에 적합한 데이터 타입
- 원문 그대로 색인하기 때문에 정형화된 콘텐츠에 사용
- 정렬이 필요한 항목
- 집계 해야하는 항목
- 검색시 필터링 되는 항목
- text 타입
- 전문 검색이 가능
- 색인되어 전체 텍스트가 토큰화되어 생성되며 특정 단어를 검색하는 것이 가능
- 정렬이나 집계가 필요할 경우 keword 타입과 같이 멀티 필드로 설정 하여 사용
- 역색인 구조
- 모든 문서가 가지는 단어의 고유 단어 목록
- 해당 단어가 어떤 문서에 속해 있는지에 대한 정보
- 전체 문서에 각 단어가 몇 개 들어있는지에 대한 정보
- 하나의 문서에 단어가 몇 번씩 출현 했는지에 대한 빈도
- 토큰화를 한 후 텍스트 전체를 소문자로 변환 한 다음 색인하면 소문자를 검색해도 대문자의 결과도 같이 나옴
- => 원문자체를 변경하는 것이 아님
- 문서 파라미터
- op_type : 이미 문서가 존재할 경우 매번 update 하지 않고 errer 를 표출함
- Delete By Query는 해당 인덱스의 스냅숏을 불러와 스냅숏이 있는 문서의 버전 기반으로 삭제
- Update는 스크립트를 수행 후 문서를 재색인(재생성) 함
- Bulk API
- 다수의 문서를 상대로 업데이트
- 색인 작업의 경우 다수의 문서를 한번에 처리함으로써 속도를 크게 향상 시킬 수 있음
- 중도 실패 시 롤백되지 않음(주의)
데이터 검색
- 쿼리 컨텍스트
- 일반적으로 전문 검색에 많이 사용
- 루씬을 이용해 게산 수행하며 캐싱이 되지 않음
- 디스크 연산이라 상대적으로 느림
- 필터 컨텍스트
- 단순 매칭 여부 검사
- 조건 매칭 여부로 구분
- 내부적으로 캐싱
- 메모리 연산이라 상대적으로 빠름
- 검색 전 필터링 과정을 먼저 거침
- 쿼리 결과 페이징
- from과 size 옵션을 이용해 구현
- 5개의 2페이지라 하더라도 10개를 조회 하므로 페이지 번호가 높아질 수록 비용이 높아짐
- Term Query는 keyword 타입 검색
- Match Query는 text 타입 검색
검색 성능 튜닝
- 검색시 샤드의 선택은 라운드로빈이지만 동적 분배 방식으로 선택하여 요청의 응답시간, 스레드 풀 크기 등을 고려해 최적의 샤드를 동적으로 결정하여 성능을 향상 시킬 수 있음
- 적절한 타임아웃을 설정하여 서버 부하를 줄 일 수 있음
- 여러 쿼리는 multi search 사용
- profile api 를 사용해 샤드별 얼마나 많은 시간이 소요되어지는지 확인 가능
데이터 집계
- 캐시의 종류
- Node query Cache : 노드의 모든 샤드가 공유하는 캐시로써 가득차면 사용량이 가장 적은 데이터를 삭제함
- Shard request Cache : 샤드에서 수행된 쿼리의 결과를 캐싱
- Field data Cache : 필드에서 집계 연산을 수행할 때 모든 필드 값을 메모리에 로드하므로 계산되는 동안 필드의 값을 메모리에 보관하는 역할을 함
샤드와 인덱스
- 레플리카 샤드는 검색 시에만 필요하기 때문에 검색 성능은 늘어났을지 몰라도 색인 성능은 그대로임
- 프라이머리 샤드를 늘리면 색인 성능 늘어남 (각 노드들이 병행적으로 수행 하기 때문)
- => 많을 수록 리소스 사용 줄어듬
- 샤드는 힙메모리 비례함
- 30GB 기준 600개
- 세그먼트
- 루씬 내부에 존재하는 자료구조
- 역색인 구조로 생성
- 하나의 루씬 내부에만 존재하고 확장이 불가능
- 루씬 인덱스
- 검색과 색인 기능을 가진 최소한의 검색엔진
- IndexWriter로 색인 과정을 통해 세그먼트 생성
- IndexSearcher를 이용해 세그먼트 검색
- 자신이 가진 세그먼트 내에서만 검색 가능
- 엘라스틱서치 샤드
- 가장 작은 단위의 검색엔지
- 내부적으로 루씬을 확장해서 검색엔진 역할을 수행
- 다수의 샤드가 협력해서 존재하는 모든 세그먼트 검색
- 세그먼트 단위 검색이 기본이면 각 세그먼트들이 검색 결과를 만들고 이를 통합해서 하나의 결과로 합쳐 응답하도록 되어짐
- IndexSearcher는 커밋포인트를 이용해 가장 오래된 세그먼트부터 차례대로 검색한 후 결과를 하나로 합쳐서 제공
- 커밋포인트
- 여러 세그먼트의 목록 정보를 가지고 있음
- 시간의 흐름에 따라 루씬은 세그먼트를 merge함
- 최초에는 IndexWriter가 세그먼트를 생성하고 IndexSearcher가 세그먼트를 읽어 검색을 제공
- 추가 색인이 되면 IndexWriter가 추가로 생성하고 추가되는동안 IndexSearcher가 기존 세그먼트만 읽어 검색을 제공하다 추가가 완료되면 모든 세그먼트를 읽어 검색을 제공
- merge가 일어날 경우 IndexWriter가 대상이 되는 세그먼트를 복제하고 복제된 세그먼트를 하나로 합침, 이때 합쳐지는 동안 IndexSearcher는 원본 세그먼트를 읽어 검색을 제공하다가 복제 작업이 완료되면 원본과 교체하고 기존 원복 세그먼트를 삭제함 그러면 IndexSearcher가 새로운 세그먼트를 읽어 검색결과를 제공
- => 준실시간을 위해 기존 세그먼트를 두고 이용하면서 추가로 생성하는 방법을 선택
- 세그먼트는 불변성의 특징을 가짐
- 동시성 문제 회피
- 캐시 이용
- 높은 캐시 적중률 유지
- 리소스 절감
- 데이터 추가시에는 원본 세그먼트를 두고 새로 추가가 되면 원본 세그먼트 삭제
- 데이터 삭제시에는 실제데이터는 물리적으로 남아있지만 비트 배열만 찾아 삭제 되었기 때문에 검색 대상에서 제외
- => 물리적으로 삭제 될 때는 merge 작업일때 삭제됨
- 내부적으로 버퍼가 있어 해당 버퍼를 큐처럼 사용
- => 버퍼가 모두 차면 작업 수행
- translog
- 샤드 장애 복구를 위한 파일로써 모든 변경사항을 기록하며 루씬에서 commit 하면 commit까지의 내용을 삭제 함
- replica의 샤드 수는 최소로 시작해서 변경이 가능하기 때문에 늘려가는 것이 좋음
- 읽기 중요 -> replica 수 증가
- 색인 중요 -> replica 수 감소
- 인덱스 생성시 샤드 수 1024개로 제한
- 마스터 노드에서 샤드를 관리하기 때문에 너무 많은 샤드는 서버에 부하를 줄 수 있음
- 샤드의 크기 최대 50G 권장
- jvm 옵션
- 힙메모리 크기는 최대 32G
- 128G = 32G 힙메모리 노드 2개(64G) + 운영체제(64G)
- 자바에서 모든 객체는 힙영역에 생성되며 객체는 모두 포인터를 가짐
- jvm은 힙영역에 생성된 객체에 접근하기 위해 포인터의 주소를 OOP(Ordinary Object Pointer)라고 하는 특수한 자료구조를 만들어서 관리
- 32비트의 시스템은 하나의 포인터를 표현하기 위해 32비트 필요 -> 최대 4G
- 64비트를 이용하면 메모리 공간 낭비가 발생하고 32비트에 비해 큰 대역폭을 소모(공간낭비, 연산속도 저하)
- =>Compressed OOP 도입
- Compressed OOP는 공간낭비를 줄이고 좀 더 빠른 연사을 위해 포인터를 압축해서 표현하는 트릭ex) 8비트의 경우 256 바이트의 물리적인 주소 공간을 표현하는 것이 아닌 256개의 객체를 가리킬 수 있게 됨=> 힙크기가 32G 넘어가면 64비트 OOP로 자동 변화하므로 사용할 이유가 사라짐
- => 32비트의 경우 32G까지 가리키는 것이 가능
- => 객체의 정확한 주소를 가리키는 것이 아닌 상대적인 Object Offset을 가리키도록 동작시키는 것
- 힙크기가 커질수록 FullGC를 수행한느 시간이 늘어나고 그에 비례해서 시트메이 처리불능 빠지는 시간이 늘어남
- 하나의 서버에 여러 인스턴스보단 여러 서버에 각 노드를 두고 각 클러스터를 구성해 고가용성 보장하는 것이 좋음
- 만약 하나의 서버에 다수의 인스턴스를 실행하여 클러스터를 구성하면 해당 옵션 지정
- cluster.routing.allocation.same_shard.host: true
- 엘라스틱서치는 스와핑을 하면 노드 안정성에 치명적이기 때문에 스와핑을 하지 않는 것이 좋음
- sudo swapoff -a : 일시적
- vi /etc/fstab : 영구적
- sudo sysctl vm.swappiness=1 : 최소화
- max open file 최대값 늘리기
'BackEnd 학습 > ELK' 카테고리의 다른 글
| Logstash(로그스테이시) - 카프카에서 consumer,producer (0) | 2023.04.09 |
|---|