[Redis] Module - RediSearch
Redis Core는 Redis의 핵심 기능을 담당하는 부분으로 메모리 기반의 키-값 저장소를 의미한다.
Redis Modules는 Redis Core의 기본 기능을 확장하기 위해 개발된 모듈 시스템으로, Redis Core가 제공하는 기본 데이터 타입 이외에 다른 특화된 기능을 제공한다.
모듈은 독립적인 C/C++ 기반 프로그램으로 Redis 서버가 시작할 때 해당 모듈을 가져와서 Redis 내부에 포함시키는 방식으로 사용한다.
RediSearch : Redis에 검색 기능을 추가해 전체 텍스트 검색, 자동완성, 필터링, 정렬 등을 제공한다.
RediSQL : Redis에서 SQL을 사용할 수 있게 해 주는 모듈이다.
RedisJson : JSON 데이터를 Redis에서 다룰 수 있게 해 준다. Redis Core의 Hash를 다룰 때 보다 더 복잡한 데이터를 다룰 때 유용하다.
...
모듈을 Redis Core에 포함시킬 때는 보통 Redis Stack 을 사용한다.
Redis Stack은 Redis Core와 여러 앞서 설명한 여러 모듈을 함께 제공하는 배포판으로, 여러 모듈을 쉽게 설정하도록 도와준다.
물론 Redis Stack을 사용하지 않고도 모듈을 설정할 수 있지만, 개별 모듈을 수동으로 로드하는 작업을 직접 해 줘야 해 매우 번거롭다.
AWS, GCP, Azure 같은 클라우드 플랫폼을 사용할 경우 보통 Redis 관련 서비스를 추상화해서 제공해 주지만, 서비스가 내가 원하는 모듈을 포함하지 않는 경우 EC2 인스턴스 등 가상 머신 인스턴스에 직접 모듈을 설치하는 방식으로 설정해야 한다.
Redis Core도 여러 데이터 구조에 대한 빠른 조회와 저장을 지원하지만.. Full Text 검색, 필터링, 정렬 등 고급 검색 기능을 제공하지는 않는다.
RediSearch는 이런 한계를 극복하기 위해 도입되었고, 메모리에 로드된 데이터들에 대해 빠르게 검색할 수 있는 기능을 제공한다.
RediSearch를 사용하기 위해, 먼저 인덱스를 정의해야 한다.
여기서의 인덱스는 RDB의 인덱스처럼 기존 데이터를 기반으로 빠르게 검색하기 위해 만들어진 추가적인 데이터 구조이고, Inverted Index구조로 구성돼 문서 내의 해당 단어가 나타나는 위치를 저장한다.
RDB의 인덱스는 B-Tree 기반으로 동작해 범위 검색과 정렬된 데이터 조회에 유리하지만 텍스트 검색에는 적합하지 않다.
Inverted Index는 특정 단어가 포함된 문서를 미리 인덱스하기에 검색 시 역색인에서 바로 관련 문서를 찾을 수 있어 빠르게 검색할 수 있다.
인덱스를 생성할 때는 FT.CREATE 명령어를 사용한다.
idx:cars : 생성하려는 인덱스의 이름을 의미한다. 보통 idx:... 형식으로 이름을 지어준다.
ON HASH : 인덱스를 생성할 데이터 구조를 지정한다. HASH 와 JSON 을 사용할 수 있다. (RedisJSON)
PREFIX 1 cars# : 지정한 단어로 시작하는 키 값을 찾고 색인한다. 여러 단어를 지정할 수 있다.
SCHEMA : 인덱스에서 사용할 필드와 자료형을 정의한다. 필요한 부분만 선택해서 정의할 수 있다.
인덱스가 만들어졌으면 이후 데이터가 추가되거나 수정될 때 마다 자동으로 인덱스를 업데이트해 수동으로 인덱스를 다시 생성하지 않아도 괜찮다.
FT.CREATE 명령어로 인덱스를 만들고, 만들어 둔 인덱스를 활용해서 데이터를 검색 할 때는 FT.SEARCH 명령어를 사용한다.
FT.SEARCH {index_name} {query} [options]
기본적으로 위 구조대로 명령어를 작성한다.
쿼리 작성 시 @ 기호로 특정 필드를 대상으로 검색할 수 있고, 괄호를 통해 검색 옵션을 지정할 수 있다.
options과 query부분은 다루기에 양이 너무 많으니.. 공식문서를 참고하자.
(https://redis.io/docs/latest/develop/interact/search-and-query/advanced-concepts/query_syntax/)
인덱스 생성 시 동일한 이름의 인덱스가 이미 존재하는 경우 예외를 뱉으니 애플리케이션이 시작할 때 FT._LIST 명령어로 이미 만들어져 있는 인덱스를 쭉 조회해 인덱스가 존재하지 않는 경우에만 인덱스를 새로 생성하도록 설정해 줘야 한다.
또, 인덱스를 업데이트 하는 기능을 지원하지 않으니 필드를 새로 추가했을 때 변경사항을 반영하려면 기존 인덱스를 삭제한 후 다시 생성해 줘야 한다.
RediSearch는 내부적으로 TF-IDF 알고리즘과 유사한 방법을 사용해 검색 결과의 관련성을 평가해 단순히 일치하는 결과를 반환하는 역할 뿐 아니라 관련성을 기준으로 정렬된 결과를 제공한다.
(TF-IDF : https://wikidocs.net/31698)
FT.CREATE reviewIndex SCHEMA summary TEXT WEIGHT 2.0 review TEXT WEIGHT 1.0
기본적으로 관련성을 사용해 정렬하고, SORTBY 명령어로 특정 정렬 기준을 직접 지정할 수 있고,
WEIGHT 명령어를 사용해 특정 속성과 내용에 대해 우선순위를 설정할 수 있다.
RDB에서는 EXPLAIN 명령어를 사용해 통계 쿼리 등 무거운 쿼리 실행 시 쿼리가 어떤 인덱스를 사용하고, 어떤 전략을 사용해 데이터를 가져오는지 확인할 수 있다.
이 정보를 사용해 쿼리 튜닝을 진행하고 성능을 끌어올리는데..
RediSearch는 RDB의 EXPLAIN과 유사한 역할을 수행하는 명령어인 EXPLAINCLI와 PROFILE 명령어를 제공한다.
이 명령어로 쿼리 수행 시간, 실행 전략 등을 확인할 수 있고, 이 정보를 사용해 특정 필드에 SORTABLE 옵션을 추가하거나 인덱스에서 특정 필드를 제거해 인덱스를 최적화한다.
회사에서는 RediSearch를 도입해도 간단한 데이터만 캐시 데이터로 다루고 사용해 실행 계획을 조회할 필요까지는 없었는데.. 검색어 자동완성 기능을 활용할 때는 몇 ns 단위로도 UX가 극명하게 갈리니 이런 경우 실행 계획을 조회하고 인덱스를 최적화하는것도 필요할 것 같다
RDB는 원본 테이블이 있고, 원본 테이블에서 쿼리 할 때 인덱스를 활용해서 빠르게 데이터를 가져오는 방식이지만
RediSearch는 문서 기반 인덱스를 사용해 쿼리 자체를 인덱스 위에서 실행시킨다.
'Database > Redis' 카테고리의 다른 글
[Redis] Stream (0) | 2024.10.10 |
---|---|
[Redis] 동시성 제어 (4) | 2024.05.25 |
[Redis] 파이프라인과 자료구조 (0) | 2024.05.15 |
[Redis] 캐시 서버와 명령어 (0) | 2024.04.27 |
댓글
이 글 공유하기
다른 글
-
[Redis] Stream
[Redis] Stream
2024.10.10 -
[Redis] 동시성 제어
[Redis] 동시성 제어
2024.05.25 -
[Redis] 파이프라인과 자료구조
[Redis] 파이프라인과 자료구조
2024.05.15 -
[Redis] 캐시 서버와 명령어
[Redis] 캐시 서버와 명령어
2024.04.27