검색 프로세스 이해 (ES, Redis 등)

huni_·2022년 7월 6일
0

React

목록 보기
30/57

우리가 평소에 사용하는 웹서비스의 검색은 어떻게 이루어지는 것일까요?

Browser에서 검색을 요청하면 Back-end에서 DB 내부의 수 많은 Data 들 속에서 요청받은 keyword를 가지고 full-scan 하게 됩니다. Data가 많을 수록 속도가 느리겠죠? 이러한 방식을 변경할 수 있습니다.

Data를 특정 키워드들로 구분지어 해당하는 글들을 모아 역인덱스 방식(Inverted Index)으로 저장되게 된다면 특정 키워드에 대한 글들의 검색이 빠르겠죠?

이런 방식을 쉽게 만들어 주는 도구(DB)가 Elastic Search 입니다. 이 방식은 Disk에 저장되는 방식으로 컴퓨터가 꺼져도 저장이 유지됩니다. 분명 안전하지만 속도는 조금 떨어지게 됩니다.

반면, Memory에 저장되는 방식도 존재합니다. 이방식은 임시저장방식으로 Disk저장보다는 안정성이 떨어지지만 속도가 빠릅니다. 이러한 메모리저장기반 방식으로는 Redis가 있습니다.

서비스를 제공하고 시간이 흐르면, 사람들의 검색에 대한 어느정도 일정 패턴이 생기게 되는데, 그렇다면 사람들이 자주 검색하게 되는 것들은 검색마다 Disk에 가서 꺼내오는것보다는 Memory 기반 DB에 넣어두면 그때 그때 마다 더 빠르게 제공할 수 있겠죠? 이런 방식을 검색로그 캐싱 이라고 합니다.

즉, 검색이 진행될 때, 캐싱이 되어있다면 Redis , 캐싱되어 있지 않은 기록은 Elastic Search 방식이 사용되는 것입니다.

검색기능 구현

💡  우리가 map() 을 사용할 때 key값을 주어야 하는데 이럴때, 고유 값을 더욱 손쉽게 부여할 수 있는 라이브러리가 있습니다.

바로 uuid uuid_github 입니다.

사용하기 위해

yarn add uuid

이후,

uuidimport 시켜준뒤 필요한 key에 넣어주면 사용 가능합니다.

검색버튼 없이 검색 시, 발생하는 문제

검색버튼을 누르지 않고 검색기능이 활성화 될때, 생기는 문제가 있습니다.

바로, page를 변경하며 refetch될 때, state로 관리하는 검색 input키워드 값이 검색을 누르지 않아도 검색되는 문제입니다.

이러한 문제는 검색을 눌렀을 때 들어가있는 키워드 값을 따로 저장시켜주는 state를 분리시켜주어야 합니다.

refetch될때 mySearch로 검색되는 부분을 myKeyword로 바꿔 해결합니다.


디바운싱 & 쓰로틀링

디바운싱이란, 연이어 발생한 이벤트를 하나의 그룹으로 묶어 처리하는 방식으로 주로 그룹에서 마지막, 혹은 처음에 처리된 함수를 처리하는 방식으로 사용됩니다.

마지막 호출이 발생한 후 일정 시간이 지날 때까지 추가적 입력이 없을 때 실행이 됩니다.

디바운싱이 사용되는 대표적 예제로는 검색기능이 있습니다.

반면 쓰로틀링이란, 연이어 발생한 이벤트에 대해 일정한 delay를 포함 시켜, 연속적으로 발생하는 이벤트는 무시하는 방식으로 사용됩니다.

즉, 지정한 delay동안 호출된 함수는 무시합니다.

쓰로틀링이 사용되는 대표적 예제는 스크롤 기능이 있습니다


Lodash 디바운싱 구현

Lodash는 자바스크립트의 유틸리티 라이브러리입니다.

내장되어 있는 유용한 함수가 많기 때문에 자주사용 됩니다.

Lodash의 많은 기능 중 디바운싱 내용에 대해 알아보겠습니다.

먼저 Lodash를 사용하기 위해서는 설치를 해야 합니다.

yarn add lodash
yarn add -D @types/lodash

Debounce

Debounce는 반복적인 동작을 강제적으로 대기하는 것을 말합니다.

예를들어, 우리가 input에 onChange를 이용해 console.log()를 확인해 보면 우리가 하나하나 입력할 때마다 onChange가 실행됩니다.

아래 사진처럼 말이죠. 아마 여러번 보셨을겁니다.

export default function Test2() {

	const handleOnChange = debounce((e) => {
		console.log(e.target.value);
  	});
  
	return (
		<>
			<input onChange={handleOnChange}></input>
		</>
	);
}

그럴 경우 중간 과정을 없애고 결과만 한 번에 실행해주는 것이 Debounce입니다.

사용하고 싶은 컴포넌트 상단에 Debounce를 불러봅시다.

import { debounce } from 'lodash';

그리고 우리가 원하는 기능을 debounce로 감싸주시면 됩니다.

import { debounce } from 'lodash';
export default function Test2() {
  
	const handleOnChange = debounce((e) => {
		console.log(e.target.value);
	}, 500);

	return (
		<>
			<input onChange={handleOnChange}></input>
		</>
	);
}

위에서 굵게 표시된 부분이 Debounce 입니다.

DebouncesetTimeout과 사용방법이 똑같습니다. debounce(콜백함수, 시간)

첫 번째 인자로는 실행시키고 싶은 함수가 들어가고, 두 번째 인자로는 시간이 들어갑니다.

debounce는 우리가 두 번째 인자로 넣어준 시간 동안 아무 일도 하지 않았을 때 콜백함수를 실행시킵니다.

즉, 우리가 무언가를 계속 입력하고 있으면 함수를 실행시키지 않고, 우리가 입력을 끝내고 가만히 있으면 그때 함수 결과를 보여줍니다.

Debounce의 결과는 아래와 같습니다.

처음 결과와는 다르게 Debounce를 사용하니 console.log()에 한 번만 찍힌 것을 볼 수 있습니다.

Debounce 활용하는 곳

그럼 우리는 Debounce를 어떻게 활용할 수 있을까요?

주로 검색을 할 때 사용할 수 있습니다. 우리가 검색을 할 때 엔터를 치지 않더라도, 사용자가 입력을 멈추고 일정 시간이 지나면 자동으로 함수를 실행시켜 검색 결과를 보여주는 것입니다.

그러면 아주 편리하겠죠?

Debounce와 검색 Mutation을 함께 사용하는 코드는 여러분들이 직접 구현해보세요!

profile
FrontEnd Developer

0개의 댓글