caffeine-library / system-design-interview

🌱 가상 면접 사례로 배우는 대규모 시스템 설계 기초를 읽는 스터디
4 stars 0 forks source link

[keyword] 13장 - 검색어 자동완성 시스템 #41

Closed ngwoon closed 2 years ago

ngwoon commented 2 years ago

주제

'13장 - 검색어 자동완성 시스템'을 읽고 내용을 요약하거나,
중요✨ 하다고 생각하는 키워드 및 관련 설명을 코멘트로 달아주세요

연관 챕터

40

@caffeine-library/readers-system-design-interview

ngwoon commented 2 years ago

13. 검색어 자동완성 시스템

1. 문제 이해 및 설계 범위 확정

요구사항

개략적 규모 추정

2. 개략적 설계안 제시 및 동의 구하기

검색어 자동완성 시스템은 크게 두 파트로 나눌 수 있다.

3. 상세 설계

RDB 대신 Trie

검색어 자동완성 서비스에는 RDB에 검색어를 저장하는 것보다 더 잘 어울리는 Trie 자료구조가 있다.

Trie 자료구조의 핵심은 아래와 같다.

검색어 - 빈도 쌍은 Trie 자료구조의 leaf노드에 저장된다.

이 기본적인 Trie를 사용하면, 최악의 경우 전체 Trie를 전부 조회해야할 수도 있다.

이를 보완하기 위해 책에서 두 가지 방법을 제시한다.

접두어의 최대 길이 제한

사용자가 긴 검색어를 입력하는 경우는 거의 없다.

따라서 접두어의 최대 길이를 제한해두면, 접두어 노드를 찾는 과정이 O(1)에 가까워진다.

각 노드에 검색어-빈도 쌍 캐시

접두어 노드를 찾은 뒤, 그와 연관된 검색어들을 찾는 과정 또한 시간이 오래 걸릴 수 있다.

접두어 노드에 검색어 - 빈도 쌍을 k개 캐시해둔다면, 따로 검색어 노드를 찾을 필요가 없게된다.

(단, 저장공간이 더 많이 필요하다.)

데이터 수집 서비스

사용자가 질의를 던질 때마다 Trie를 업데이트한다면 서버 부하가 엄청날 것이다.

따라서 사용자의 질의를 수집해서, 적절하게 조합한 다음, 적절한 주기로 Trie를 갱신할 수 있는 “데이터 수집 서비스” 가 필요하다.

KakaoTalk_20220305_025722441.jpg

질의 서비스

질의 서비스는 아래와 같은 흐름으로 사용자에게 검색어 k개를 제공한다.

KakaoTalk_20220305_032200370.jpg

검색어 제공은 굉장히 빠르게 제공되어야 한다. 서버 latency를 줄이기 위한 몇 가지 방법이 있다.

hyunrrr commented 2 years ago

13장 검색어 자동완성 시스템

요구사항

개략적 규모추정

개략적 설계안

상세 설계(개략적 설계 개선안)

트라이 자료구조(관계형 데이터베이스 대신 사용)

접두어 길이: p, 트라이 안에 있는 노드 개수: n, 주어진 노드의 자식 노드 개수: c일때 접두어를 표현하는 노드를 찾음: O(p) 접두어표현 노드부터 하위의 모든 유효 노드를 찾음: O(c) 유효 노드를 정렬: O(clogc) 한 번의 질의 시간복잡도: O(p) + O(c) + O(clogc)

두 가지 방법으로 시간복잡도를 최적화 할 수 있음

  1. 접두어의 최대 길이를 제한 -> p에 제한을 두면 p=최대 길이 상수, O(p) -> O(상수) -> O(1)이 된다.
  2. 각 노드에 인기 검색어를 캐시 -> 캐시에 저장된 내용을 사용하면 됨, O(1) 최적화된 시간복잡도: O(1)

데이터 수집 서비스

실시간으로 데이터를 갱신하면 두 가지 문제가 있다.

  1. 매일 수천만 건 발생하는 질의로 트라이를 실시간 갱신하면 서비스는 심각하게 느려짐
  2. 인기 검색어는 자주 바뀌지 않음, 굳이 트라이를 자주 갱신할 필요가 없음

질의 서비스

  1. 검색 질의가 로드밸런서로 전송
  2. 로드밸런서는 해당 질의를 api서버로 전송
  3. api서버는 트라이 캐시에서 데이터를 가져와 해당 요청에 대한 자동완성 검색어 제안 응답을 구성해야 함
  4. 데이터가 캐시에 없으면 데이터베이스에서 가져와 캐시를 채움

트라이 연산

저장소 규모 확장

binchoo commented 2 years ago

이번 시스템에서 성능 향상을 도모하는 기법 중, 두 가지가 반복적으로 사용됨을 느꼈습니다.

첫째는, 탐색 공간의 일부를 배제하는 것입니다. 모집단을 모두 살피지 않고, 통계적으로 유효한 샘플 집단만 가지고도 기능 요구사항을 적당히 만족할 수 있으며, 품질도 확보할 수 있습니다.

둘째는, 캐싱을 이용하는 것입니다. 사용자의 요청을 받아서 부랴부랴 작업을 수행하는 방식을 지양합니다. 대신, 과거 작업이 도출하고 메모리로 저장했던 값을 읽어 반환합니다.

탐색 공간을 제한하기

캐싱하기


성능 향상에 대한 품질 요구사항에 대응할 때는, 탐색 공간의 배제 & 캐싱 두 기법을 기억해둔다면 좋을 것 같습니다 . 동일한 접근 방식이 알고리즘 문제를 구현할 때도 필요하다고 느꼈습니다.