검색 기능 개발이 어려운 이유

Posted on September 11, 2023
검색 기능 개발이 어려운 이유

들어가며

쿠팡, 배달의민족, 야놀자 등 우리 일상생활에서 쓰는 앱들의 공통적인 필수 기능은 무엇일까요? 바로 검색입니다. 쿠팡에서는 상품을, 배달의 민족에서는 음식을, 야놀자에서는 여행을 검색합니다. 그리고 맛집을 찾기 위해, 쇼핑을 하기 위해 구글과 네이버에서도 검색을 합니다. 검색은 우리 일상생활에서 뗄레야 뗄 수 없는 행위이며, 모든 현대 애플리케이션에서 검색은 필수 기능이 되었죠.

그런데 검색 기능을 개발하는 것은 결코 쉽지 않은 과제입니다. 백엔드 개발자, 프로덕트 기획자 분들은 잘 아실 겁니다. 제대로 된 검색 기능을 개발하기 위해서는 엄청난 고통이 뒤따른다는 것을요. 사용자들은 구글과 같은 수준의 검색 품질을 애플리케이션 레벨에서도 기대하지만, 그럴수록 기술적 요구사항은 복잡해집니다.

도대체 어떤 기술적 요구사항들이 있길래 검색 기능 개발이 어려울까요?

검색 기능 개발하기 위한 두 가지 방법이 있습니다. 하나는 데이터베이스에서 제공하는 검색 기능(정확히는 쿼리 기능)을 사용하는 것이고, 다른 하나는 데이터베이스에 별도의 검색 엔진을 추가하여 두 시스템을 동기화하는 것입니다.

데이터베이스의 쿼리 기능을 사용

첫 번째 방법의 장점은 서비스 초기에 비교적 간단하게 만들 수 있다는 것입니다. 데이터베이스에서 제공하는 쿼리와 인덱싱을 사용할 수 있기 때문에 추가 솔루션이 필요 없고, 개발자는 데이터베이스의 쿼리 언어만 사용하면 되므로 러닝 커브가 발생하지 않습니다.

예를 들어 호텔 예약 앱에서 판교에 있는 호텔을 검색할 경우 간단한 SQL 쿼리문을 사용하여 해당 지역에 있는 호텔을 찾아 사용자에게 제공할 수 있습니다. 이렇게 사용자의 요구사항이 복잡하지 않은 서비스 초기 단계에서는 대부분 데이터베이스의 검색 기능을 사용합니다.

하지만 검색 요구 사항이 조금만 높아지면 상당한 기능 제한과 사용자 경험에 부정적인 영향을 미치는 성능 문제에 직면하게 됩니다.

우선 오타 수정, 동의어 처리, 점수 계산과 같은 기능 제한이 있습니다. 예를 들어 주식 앱에서 동의어 처리가 되지 않았다면 "네이버"를 검색하기 위해서 반드시 "NAVER"로 입력해야 합니다. 혹여 오타를 하나라도 입력하면 검색 결과 없음이 나타나지요.

그리고 검색 조건이 많아질수록 복잡성이 증가합니다. "판교"에 있는 호텔이 아니라, "판교"에 위치하고 조식이 제공되며 유아 동반, 반려동물 동반이 가능한, 앤티크한 분위기의 5성급 호텔을 검색한다면 어떻게 될까요?

사용자가 원하는 검색 결과를 찾기 위해 쿼리문 조합이 많아질수록 쿼리문 길이가 늘어나게 되고, 무엇보다 많은 조건을 검색하기 위한 인덱스를 생성해야 합니다. 인덱스를 만들기 위해서는 많은 리소스가 소요되고, 반대로 인덱싱을 하지 않으면 조건을 만족하는 결과를 찾기 위해 데이터베이스의 모든 레코드를 스캔해야 하는 성능 부하가 발생하죠.

결론적으로 테스트, 디버그 등 개발 시간이 급격히 증가하고, 설령 기능이 완성되었다 하더라도 서비스 속도 등에 부정적인 영향을 미치게 됩니다.

서비스가 확장함에 따라 결국은 별도의 검색 엔진을 필요로 하게 됩니다.

데이터베이스에 검색 엔진 연결

검색 엔진과 데이터베이스는 근본적으로 다르게 설계된 소프트웨어입니다.

데이터베이스의 주 목적은 데이터 처리에 대한 무결성, 일관성, 내구성이므로 읽기/쓰기의 균형 잡힌 성능 유지, 동시성, 가용성, 재해 시 복구 가능성과 같은 요소가 중요시 됩니다.

데이터베이스에서 필요한 데이터를 추출하는 쿼리 기능은 상대적으로 중요성이 떨어집니다. (물론 대량의 데이터를 추출하는 것에 특화된 OLAP 데이터베이스가 있습니다.)

데이터베이스와 달리 검색 엔진의 설계 목표는 저장된 데이터에서 사용자 의도에 가장 적합한 결과를 찾는 것입니다. 오타 수정, 동의어 처리, 일치하지 않지만 관련성이 높은 결과 탐색, 검색 결과의 순위 산정과 같은 기능을 전제합니다. 따라서 데이터베이스 기능은 제한적일 수 밖에 없습니다.

두 소프트웨어가 가지는 트레이드오프 관계 때문에 데이터를 저장하고 처리하는 기능은 데이터베이스에서, 검색 기능은 검색 엔진에서 처리하는 방법을 선택합니다. 말은 쉬워 보이지만 이제부터 어마어마한 개발 고통의 늪에 빠지게 됩니다. 검색 기능을 개발하고 이를 운영할 수 있는 역량 있는 백엔드 개발자를 채용하는 것이 대표님의 주요 과제가 되는 시점이지요.

먼저 검색 엔진을 추가하는 순간 개발팀이 다루어야 할 시스템이 두 개가 됩니다. 검색 엔진 언어를 추가로 사용해야 하므로 러닝 커브가 발생하고, 서비스를 배포할 때마다 두 시스템을 동시에 테스트해야 합니다. 그리고 API도 달라지겠죠? 애플리케이션의 백엔드 종속성이 심화되고 제품화 속도는 점점 느려집니다. 개발 생산성의 급격한 저하가 발생합니다.

무엇보다 가장 어려운 문제는 데이터베이스와 검색 엔진의 동기화입니다. 데이터베이스에 저장된 데이터를 검색 엔진에서 검색하기 위해서는 두 시스템이 저장하고 있는 데이터가 일치해야 합니다. 일단 동일한 데이터를 중복 저장하는 것에서부터 비효율성이 발생합니다.

그리고 회원 가입, 상품 추가와 같은 새로운 이벤트가 발생하여 데이터베이스가 처리한 순간, 그 즉시 검색 엔진에 동기화가 돼야 하는 메커니즘을 만들어야 겠죠? 보통 Apache Kafka와 같은 메시징 시스템을 기반으로 데이터 파이프라인을 만들거나, 별도의 패키지 커넥터를 사용합니다. 만드는데 시간도 소요되고 솔루션을 위한 솔루션 구입 비용도 추가되죠.

동기화 프로세스가 배포되었으니 이제는 모니터링하고 관리해야 합니다. 데이터베이스에 발생한 트랜잭션과 같은 속도로 동기화가 되는지, 보안 이슈는 없는지 등을 실시간으로 트래킹해야 합니다. 장애가 발생했다면 이것이 데이터베이스 문제인지, 검색 엔진 문제인지 구분부터 해야 하구요. 당연히 Datadog과 같은 솔루션을 또 구매해야겠죠? 혹여나 검색 엔진의 인덱싱 속도가 데이터베이스보다 크게 뒤처지면 처음부터 재동기화해야 합니다.

이런 복잡성은 애플리케이션 성능에 영향을 미치며 사용자 경험을 저하시킵니다. 리텐션을 떨어뜨리고, 구매 전환율을 낮추고, 궁극적으로는 고객이 이탈합니다.

검색 기능을 쉽게 개발할 수는 없을까요?

데이터베이스의 쿼리 기능만으로는 제대로 된 검색 기능을 구현할 수 없고, 데이터베이스에 검색 엔진을 연동하기 위해서는 검색 전문 개발자가 필요하고, 개발의 복잡도를 증가시킵니다. 그렇다면 서비스 초기 단계에서 수준 높은 검색을 통한 사용자 경험 향상은 정말로 불가능한 것일까요? Aeca로 해결하는 방법을 알아보세요.

Aeca가 검색 개발을 쉽게 하는 방법

Tags:

Copyright © 2024 Aeca, Inc.

Made with ☕️ and 😽 in San Francisco, CA.