서론
기존 프로젝트에서 검색 엔진을 ELK 스택(Elasticsearch, Logstash, Kibana )으로 전환하고
프로젝트의 요구사항 중 하나였던 실시간 검색어 기능 구현을 완료하면서,
이전에 작성했던 글에서 다룬 초기 설계 및 설정 과정을 기반으로 아키텍처가 어떻게 개선되었는지 정리하고자 한다.
초기 설계 단계에서 검색 기록 관리와 실시간 인기 검색어 제공을 목표로 설정했고,
이에 따라 기존 MySQL 기반의 스택은
검색 시스템을 ELK(Elasticsearch, Logstash, Kibana) 스택으로 전환하며 얻을 수 있는 성능 향상 및 확장성을 확인했다.
이번 구현에서는 Spring Boot와 Nginx, Docker, 그리고 Filebeat 및 Logstash를 연동하여
실시간 검색어를 10위까지 노출하는 기능을 완성해 보게 되었다.
시스템 아키텍처
- Spring Boot: 클라이언트 요청 처리 및 API 설계
- Nginx: Spring Boot와 ELK 스택 간의 안정적 통신을 위한 리버스 프록시 설정
- Docker: 각 서비스의 컨테이너화를 통해 효율적인 배포 및 관리
- Filebeat: 로그 데이터를 Logstash로 전달하기 위한 경량 데이터 전송 도구
- Logstash: Filebeat로부터 전달받은 데이터를 필터(filter) 를 활용하여 Elasticsearch에 적합한 형태로 변환
- Elasticsearch: 데이터 색인 및 검색 성능 향상
- Kibana: 데이터 시각화 및 실시간 검색어 조회 결과 확인
아키텍처는 데이터 검색에 대한 api 처리 (검색에 대한 데이터 수집) 및 분석 환경 ( 실시간 검색어 구현)을 목적으로,
Spring Boot로 클라이언트 요청을 처리하고, Nginx를 통해 로그 데이터를 효과적으로 수집하여
ELK 스택(Elasticsearch, Logstash, Kibana, filebeat)으로 이어져 검색 트렌드의 전체적인 파이프라인이 완성했다.
Elasticsearch의 역색인(Inverted Index) 방식과 분산 처리 기능은 대규모 데이터를 빠르고 효율적으로 색인하고 검색할 수 있기 때문인데, 여기서 Filebeat와 Logstash는 로그 데이터를 실시간으로 수집하고 전처리하여 Elasticsearch에 전달하는 과정은 대규모 트래픽 환경에서도 로그 유실 없이 안정적으로 동작하며, 데이터의 통합과 관리가 용이할 것이라고 생각했다.
이를 통해 데이터 수집으로 인한 처리와 실시간 검색어 구현 추가적으로
로그 데이터 수집으로 인한 시스템 성능 모니터링도 가능해질것이라고 판단된다.
구현 과정 및 세부 내용
1. Nginx -> Filebeat -> Logstash
Nginx 설정 파일에서 Spring Boot로 API 요청을 전달하도록 리버스 프록시를 설정하고,
Filebeat를 통해 Nginx 엑세스로그를 Logstash로 전달할 수 있었다.
Logstash의 grok 필터는 로그 데이터를 패턴 기반으로 분석하고, 필요한 정보를 구조화된 필드로 추출할 수 있다.
이미지와 같이 Nginx 액세스 로그의 특정 패턴(예: IP 주소, HTTP 메서드, URL 경로)을 분리하여 각각의 필드로 저장하여
구조화된 데이터로 추출할 수 있고 이것은 Elasticsearch에서 효율적인 검색과 집계 작업을 가능하게 한다.
또한 데이터 디코딩 및 타임스탬프, 다양한 필터 지원으로 데이터를 가공하고 분석 가능한 형태로 변환하는데 도움을 줬다.
2. Logstash -> Elasticsearch -> Kibana
Logstash에서 전달받은 데이터를 Elasticsearch는 색인(Indexing)하여 저장하게 되면,
실시간으로 데이터 수집을 확인할 수 있다.
나의 경우 특정 색인인 nginx-logs-*(timestamp) 날짜를 활용해서
특정 시간대의 API 경로(2025-01-19)에 해당하는 상위 검색어를 추출해 보았다.
위 결과에서 /bar/titles/술이 가장 많이 요청된 API 경로가 될 것이고 "술"이라는 검색어가 1위로 검색량이 측정이다.
그렇게 된다면 사용자 요청 데이터를 한눈에 파악할 수 있으며,
대시보드(Kibana)에서 다양한 분석 작업을 수행 인기검색어에 대한 데이터를 불러올 수 있을 것이다.
3. Spring Boot Swagger를 통한 API 테스트 및 확인
RestHighLevelClient를 사용하여 Elasticsearch로 전송할 요청을 구성하기 위해 Request 객체를 활용한다.
이때 객체 생성 양식은 POST 방식, 특정 색인, _search으로 구성되고,
...
Request request = new Request("POST", "/nginx-logs-*/_search");
...
request 본문에는 검색요청의 쿼리 요청 본문을 JSON 문자열로 설정한다.
이후 API 호출 시, 내부적으로 Request 객체를 생성하고 Elasticsearch로 검색 요청을 전달하여
실시간 데이터를 최종적인 집계를 확인할 수 있었다.
@DisplayName("kibana_devtool_getTopSearchTerms_log()")
@Test
void testGetTopSearchTerms() {
String startTime = "2025-01-19T00:00:00";
String endTime = "2025-01-19T21:00:00";
given(this.spec)
.filter(document(DEFAULT_RESTDOC_PATH)) // Spring Rest Docs 설정
.queryParam("startTime", startTime) // 쿼리 파라미터 추가
.queryParam("endTime", endTime) // 쿼리 파라미터 추가
.accept(ContentType.JSON) // JSON 응답 기대
.log().all() // 요청/응답 로그 출력
.when()
.get("/bar/top-terms") // 엔드포인트 호출
.then()
.statusCode(HttpStatus.OK.value()) // HTTP 상태 코드 200 확인
.contentType("application/json"); // 응답 타입 확인
}
// 응답 예시
{ "key": "/bar/titles/술", "doc_count": 2 },
{ "key": "/bar/titles/111", "doc_count": 1 },
{ "key": "/bar/titles/희", "doc_count": 1 }
성과 및 개선점
1) 성과
- MySQL 대비 검색 성능이 약 88.7% 개선되었으며, 실시간 데이터 처리의 효율성을 입증.
- 비정형 데이터를 효과적으로 처리할 수 있는 유연한 시스템 구축.
2) 개선점
- Filebeat와 Logstash의 로깅 효율성 개선:
- 현재 Filebeat와 Logstash는 대규모 로그 데이터를 처리할 때, 데이터 필터링 및 전처리 과정에서 병목이 발생할 가능성
- Redis를 도입하여 임시 데이터 저장소 및 큐(Queue) 역할을 추가하면, 처리 효율성을 개선
- 데이터 동기화 문제:
- 실시간으로 집계된 데이터와 실제 Elasticsearch 색인 데이터 간에 데이터 지연? (10~20초간의 간격)
- Redis를 캐시로 활용하면, Elasticsearch에서 직접 데이터를 조회하기 전 Redis에서 우선적으로 결과를 제공하여 사용자의 응답 대기 시간 개선
향후 계획
- Redis 기반 실시간 캐시 최적화:
- 실시간 검색어 집계를 Redis에 일정 주기로 갱신하여 최신 데이터를 유지..
- Redis 클러스터링을 활용하여 데이터의 안정성과 확장성을 확보.
- Redis와 Logstash 통합 최적화:
- Logstash의 Redis input 플러그인을 활용하여 Redis에 적재된 로그 데이터를 효율적으로 수집.
- Redis 큐의 모니터링 도구를 추가하여 데이터 처리 상태를 실시간으로 확인.
이번 실시간 검색어 구현은 프로젝트의 주요 요구사항을 충족하는 데 성공했으며, ELK 스택의 강점을 활용해 보았다.
특히, MySQL 기반 시스템 대비 약 88.7% 향상된 검색 성능을 확인하고,
대규모 로그 데이터와 비정형 데이터를 효과적으로 처리할 수 있는 유연한 시스템을 구축해보았으니
이를 입증할 테스트 또한 진행을 해보아야 할 것 같다.
다음 포스팅에서는 실시간 데이터 처리 효율성을 높이기 위해 수행한 최적화 작업과 추가 기능 구현에 대해 다룰 예정이다.
Reference
https://spring.io/projects/spring-data-elasticsearch
https://tecoble.techcourse.co.kr/post/2021-10-19-elasticsearch/
'회고' 카테고리의 다른 글
[우테코] 프리코스 4주차 - 다리 건너기 회고록 (2) | 2023.01.01 |
---|---|
[우테코] 프리코스 3주차 - 로또 회고록 (0) | 2023.01.01 |
[우테코] 프리코스 2주차 - 숫자 야구 게임 회고록 (0) | 2023.01.01 |