서비스의 규모가 커지고 데이터가 수백만 건 이상 쌓이기 시작하면, 가장 먼저 성능 한계가 드러나는 곳 중 하나가 바로 검색 기능입니다.
우리가 흔히 사용하는 PostgreSQL이나 MySQL 같은 관계형 데이터베이스(RDBMS)에서 LIKE '%keyword%' 쿼리를 실행하면, DB 엔진은 테이블의 모든 행을 하나씩 훑어야 하는 Full Table Scan을 수행합니다. 데이터가 적을 때는 문제가 없지만, 수백만 개의 상품이나 게시글이 쌓인 상태에서 동시 접속자가 늘어나면 검색 쿼리 하나가 2초 이상 걸리게 되고, 이는 곧 전체 시스템의 병목 현상으로 이어집니다.
이러한 검색 성능 문제를 해결하기 위해 크게 세 가지 대안을 고려했습니다.
대규모 데이터에 대한 실시간 검색과 정교한 한글 분석(Nori 등)이 필수적이었기에, 우리는 Elasticsearch를 최종 솔루션으로 채택했습니다.
Elasticsearch가 RDBMS보다 수십 배 빠른 이유는 데이터를 저장하는 방식 자체가 다르기 때문입니다.
책의 맨 뒷부분에 있는 '찾아보기' 페이지를 생각하면 쉽습니다. 일반적인 DB가 "문서 번호 -> 내용" 순서로 저장한다면, Elasticsearch는 "단어 -> 그 단어가 포함된 문서 번호들"의 형태로 데이터를 저장합니다. 따라서 특정 단어를 검색할 때 모든 데이터를 훑을 필요 없이, 단어가 등록된 위치로 즉시 점프하여 결과를 찾아냅니다.
Elasticsearch는 여러 대의 서버(Node)를 하나의 클러스터로 묶어 데이터를 분산 저장(Sharding)합니다. 특정 서버에 장애가 발생해도 복제본(Replica)을 통해 서비스 중단 없이 작동하는 탄탄한 아키텍처를 가지고 있습니다.
NestJS 환경에서 Elasticsearch 클라이언트를 연동하고 상품을 검색하는 기본적인 흐름은 다음과 같습니다.
// elasticsearch.service.ts import { Injectable } from '@nestjs/common'; import { ElasticsearchService } from '@nestjs/elasticsearch'; @Injectable() export class ProductSearchService { constructor(private readonly esService: ElasticsearchService) {} async searchProducts(query: string) { // Elasticsearch의 match 쿼리를 사용한 전문 검색 const result = await this.esService.search({ index: 'products', body: { query: { multi_match: { query, fields: ['title', 'description', 'category'], fuzziness: 'AUTO' // 오타 교정 기능 포함 } } } }); return result.hits.hits.map(item => item._source); } }
Elasticsearch 도입 시 가장 까다로운 부분은 RDBMS와의 데이터 일관성 유지였습니다. DB에서 상품명이 수정되었는데 검색 엔진에는 옛날 이름이 남아있는 현상이 발생했죠.
이를 해결하기 위해 우리는 Logstash를 활용한 배치 동기화와, 데이터 변경 시점에 MQ(Message Queue)를 사용하여 실시간으로 인덱스를 갱신하는 방식을 병행하여 데이터 정합성 문제를 해결했습니다.
도입 전후의 지표 변화는 매우 극적이었습니다.
얻은 것과 잃은 것(Trade-off): 하지만 Elasticsearch는 메모리를 매우 많이 점유(JVM Heap)하며, 운영을 위한 인프라 비용이 추가로 발생합니다. 또한, 실시간성(Real-time)이 아닌 Near Real-time(약 1초의 지연) 구조이므로, 데이터 입력 즉시 검색 결과에 나오지 않을 수 있다는 점을 반드시 설계 시 고려해야 합니다.
검색은 사용자가 우리 서비스의 가치를 가장 먼저 경험하는 창구입니다. 단순한 기능 구현을 넘어 Elasticsearch와 같은 전문 도구를 도입하는 것은 사용자 경험을 한 단계 끌어올리는 아주 중요한 엔지니어링 결정입니다.
성능 병목으로 고민하고 계신다면, 지금 바로 여러분의 서비스에 검색 엔진이라는 날개를 달아보시는 건 어떨까요?