-
[FastAPI] ElasticSearch프로젝트/뉴스타 2024. 6. 27. 09:38
ElasticSearch 왜 궁금했을까❓
뉴스타는 1시간마다 크롤링한 뉴스 데이터를 요약해서 사용자 맞춤형으로 뉴스를 추천하는 서비스이다. 뉴스 검색 기능도 지원하여 MySQL의 like 함수를 이용하여 구현했다. 하지만, 추후 데이터가 늘어나면 사용자 응답 속도가 늦어질 것이라 판단했고 이에 대안으로 ElasticSearch를 도입하기로 했다. 이번 포스팅에서는 ElasticSearch의 개념과 동작원리 등에 대해서 알아보려고 한다.
1. ElasticSearch란?
- Apache Lucene기반의 Java 오픈 소스 분산 검색 엔진
- 빅데이터를 신속하게 저장, 검색, 분석
- 단독으로 검색엔진으로 사용되기도 하며 ELK(ElasticSearch, Logstash, Kibana)로 사용하기도 함
- ElasticSearch - Logstash로 받은 데이터를 검색 및 집계하여 관심 있는 정보를 획득
- Logstash - 다양한 로그 또는 데이터를 수집, 집계, 파싱하여 ElasticSearch에 제공
- Kibana - ElasticSearch를 통해 데이터를 시각화 및 모니터링
1.1. ElasticSearch 아키텍처
클러스터 (Cluster)
- 네트워크를 통해 여러 개의 노드가 연결된 것을 클러스터라고 한다.
- 노드의 집합으로 하나 이상의 노드로 구성되며 동일한 서버나 네트워크 망에 있어도 클러스터명이 다르면 서로 다른 시스템이다.
노드 (Node)
- 기본 작동 단위로 ElasticSearch가 설치되어 실행되는 각 서버를 의미한다.
- 데이터를 저장하고 클러스터의 일부로 동작하여 검색 및 인덱싱 작업 등을 수행한다.
- Master Node - 클러스터 관리 / 노드 관리
- Data Node - 실질적인 데이터 저장 / 검색과 통계 등 데이터 관련 작업 수행
- Coordinating Node - 사용자의 요청만 받아서 처리하는 노드로 클러스터는 마스터로 데이터는 데이터 노드로 전달
- Ingest Node - 문서의 전처리를 담당하여 인덱스 생성 전 문서의 형식을 다양하게 변경
인덱스 (Index)
- RDB의 Row를 ElasticSearch에서는 도큐먼트(Document)라고 부른다.
- 도큐먼트(Document)를 모아놓은 집합을 인덱스(Index)라고 하며 하나 이상의 샤드로 분할될 수 있다.
샤드 (Shard)
- ElasticSearch에서 데이터를 분산 저장하는 방법으로 각 샤드는 독립적인 인덱스라고 할 수 있으며 자체적인 검색이 가능하다.
- 샤딩(Sharding)은 빅데이터를 여러 노드에 분산시켜 저장하고 처리하는데 필요하며, 성능 향상과 확장성 등을 얻을 수 있다.
- 단일 ElasticSearch 클러스터 내에서 샤딩된 각 부분은 서로 다른 노드에 위치할 수 있어서 한 노드가 실패하더라도 다른 노드에서 해당 샤드와 관련된 작업을 계속을 진행할 수 있다.
- 샤드의 개수만큼 CPU의 Thread를 사용하기 때문에 샤드의 개수가 많아질수록 자원을 많이 잡아먹게 되어 적절히 설정해야 한다.
복제본 (Replica)
- 데이터 손실 방지와 검색 성능 향상을 위해 샤드는 복사될 수 있으며 기존의 샤드가 장애가 발생할 경우 대체할 수 있다.
2. RDB / ElasticSearch
2.1. 데이터 저장 방법
- RDB의 경우 정규화된 스키마에 따라 데이터를 구조화하지만 ElasticSearch는 JSON 문서 형태로 비정형 데이터도 저장하고 인덱싱할 수 있다.
- RDB의 경우 Row를 기반으로 데이터를 저장하지만 ElasticSearch는 word를 기반으로 데이터를 저장한다.
- ElasticSearch는 NoSQL의 Key-Value DB처럼 저장돼서 수정과 삭제가 많은 경우에는 자원이 많이 소비될 수 있지만 검색 속도가 빠르다.
2.2. 용어
RDB ElasticSearch Database Index Table Type Row Document Column Field Index Analyze Primary Key _id Physical partition Shard Logical partition Route Relational Parent / Child, Nested SQL Query DSL 2.3. 데이터 조작
ES HTTP Method RDB SQL GET SELECT PUT INSERT POST UPDATE, SELECT DELETE DELETE HEAD (인덱스 정보 확인) X 2.4. 검색 원리
RDB의 텍스트 검색
RDB는 인덱스(Index)라는 테이블 내의 데이터를 더욱 빠르게 찾아주기 위한 데이터 구조가 존재
SELECT * FROM NEWS WHERE title LIKE '%삼성%'
- 뉴스 테이블에서 제목에 "삼성"이라는 단어가 들어간 뉴스를 찾기 위해서는 위와 같은 SQL문을 작성해야 한다.
- 인덱스 설계와 튜닝을 잘해놨다 하더라도 %(Wildcard) 모든 패턴 매칭으로 인해 인덱스를 사용하지 못하고 전체 데이터를 스캔하게 될 것이다.
- 위와 같은 데이터가 주어졌을 때, 아래 그림처럼 모든 데이터에 순차적으로 접근하여 DATA에 문자열이 있는지 확인할 것이다.
ElasticSearch의 텍스트 검색
ElasticSearch는 역인덱스 기술인 검색에 최적화된 인덱스 기술을 활용
- 위 데이터가 주어졌을 때, 단어를 기준으로 분류되어 아래와 같이 저장된다.
- 삼성전자라는 단어가 포함된 데이터를 찾고 싶다면 아래 그림처럼 빠르게 찾을 수 있다.
- 실제 검색엔진의 구조는 훨씬 더 복잡한데 특정 데이터가 들어오면 필터링과 토큰화를 통해서 검색 품질을 높이는 작업을 수행한다.
아래 포스팅에서 뉴스타 서비스에 적용하는 과정과 성능 비교를 작성해 놨다.
'프로젝트 > 뉴스타' 카테고리의 다른 글
[React] Axios API 모듈화 (0) 2024.07.02 [Spring Boot / FastAPI] 프로젝트 환경 분리 (0) 2024.06.30 [Spring boot] Java 테스트 코드 (0) 2024.06.17 [Spring Boot] Redis를 활용한 성능 향상 (0) 2024.06.16 [Infra] 무중단 서비스를 위한 Health Check (0) 2024.06.14