성능 분석 결과
Last updated
Last updated
SOOJLE의 추천 뉴스피드의 성능 분석 지표는 아래와 같다.
DB의 전체 POST에서 날짜로 정렬된 데이터의 상위 15000개를 호출한다.
DB에 캐싱 된 Max 좋아요/조회 수를 호출한다.
POST 한 개와 한 명의 사용자 간의 유사도 측정 (TOS, TAS, FAS, IS, RANDOM)
호출한 15000개의 POST와 한 명의 사용자 간의 유사도 측정
분석이 완료된 15000개의 POST의 similarity 값 정렬
SOOJLE의 MongoDB는 읽기가 빈번하게 일어나는 모든 컬럼에는 Index를 적용시켜 놓았기 때문에, pure로 호출했을 때 보다 훨씬 빠르게 불러오는 효과를 가진다.
위 결과는 현재 30만 개의 POST들이 저장되어 있는 SOOJLE의 test_post에서 날짜로 최신화 정렬을 수행한 후에 상위 15000개의 게시글들을 불러왔을 때의 시간이다. (DB에 저장되어 있는 데이터는 측정 용이 아닌 실제 서비스할 때 사용될 데이터들이다.)
개인 작업 PC에서 Single thread로 Server를 열어서 원격으로 상용 서버에 올라와 있는 DB에서 호출했을 때에는 평균 1~1.5초의 시간 소요가 확인되었다. 하지만 상용 서버의 하드웨어적인 우세와 DB의 local 호출을 통한 우세점을 통해서 현재는 0.17초로 약 10배 정도 빨라진 모습을 확인할 수 있다.
추천 뉴스피드의 핵심 알고리즘인 사용자와 문서 간의 유사도 측정 알고리즘은 크게 5가지로 나누어진다.
TOS = LDA Topic Vector 값의 유사도 측정
TAS = Tag 의 유사도 측정
FAS = FastText Vector 값의 유사도 측정
IS = Interest Score (최신 트렌드 게시글)
RANDOM = 사용자에게 골고루 보여주기 위한 랜덤 변수
자세한 내용은 아래의 링크된 부분을 통해서 유사도 측정 알고리즘을 확인할 수 있다.
사용자-문서 유사도(Recommendation Score)SOOJLE은 추천 뉴스피드를 모든 사용자 각각의 관심도와 맞춰서 추천해주기 때문에, 한 명의 사용자와 불러온 POST간의 유사도를 모두 측정해야 한다. 따라서 최대한 효율적이고 매우 빠른 연산을 요구한다.
이를 위하여 사용된 주된 방법은 아래와 같다.
MongoDB Indexing 작업
DB의 빈한 호출 지양
연산에 필요한 모든 지표들은 DB의 Cashing 처리
부동 소수점 연산 지양
Numpy를 통한 모든 산술 연
또한 알고리즘 적으로 반복적인 연산을 지양하기 위하여 최대한 효율적인 알고리즘을 계속 고안하여 구현하여 현재의 SOOJLE의 Recommendation newsfeed가 완성됐다.
위의 방식으로 TOS, TAS, FAS, IS, RANDOM을 통하여 하나하나의 POST와 사용자 간의 유사도를 측정하여 이에 대한 Total 시간은 약 0.8초로 측정되었다.
유사도 측정을 통하여 나오게 된 유사도 값 similarity는 각각의 POST에 Key로 저장 되어있다. 이를 통하여 내림차순 정렬을 해준 시간은 0.0096초로 정렬에는 크게 많은 시간이 소요되지는 않는다.
최종적으로 한 명의 유저가 최신 트렌드의 맞춤형 추천 뉴스피드를 호출하여 받아볼 수 있는 시간을 약 1초로 측정되어 매우 준수한 성능을 보여주고 있다.
검색 엔진의 성능 분석은 상당히 유동적이다. 검색어의 질, 검색 결과의 개수에 따라서 시간이 많이 차이나기 때문에 SOOJLE은 세종대학교의 정보 통합 솔루션인 만큼 '세종대학교'의 키워드를 중점으로 테스트를 진행한다.
SOOJLE의 검색 엔진의 성능 분석 지표는 아래와 같다.
검색어를 기준으로 Title Regex 호출
검색어 공백 제거
검색어 토크나이저 처리
FastText를 통하여 유사 단어 추출
Aggregate를 통하여 IDS를 생성 후 상위 X개를 정렬 후 반환
추출된 데이터와 검색어 간의 유사도 측정
측정된 유사도를 기준으로 내림차순 정렬
테스트를 위한 검색어는 다음과 같다.
1차 검색 엔진은 최근 트렌드에 중점을 둔 검색 엔진이며, 측정 결과는 다음과 같다.
SOOJLE의 검색엔진은 항상 1차로 정규 표현식(Regex)를 이용하여 Title Regex 호출한다. 즉, 사용자가 원하는 검색 결과 '제목일치'를 구해주기 위한 목적이다.
Title Regex는 DB에 있는 모든 데이터를 대상(테스트 데이터는 30만개)으로 검색어와 POST title과 일치하는 것을 먼처 찾는다. 시간 측정은 약 0.3초가 소모되었다.
Title 컬럼에도 Index 처리는 당연히 되어있으므로 pure 상태의 regex보다는 준수한 성능을 보여주었다.
이후 측정하는 지표들은 조금더 세부적이고 유사한 검색 결과물을 보여주기 위한 토큰화 작업이 필요하다. 토큰화 작업은 다음과 같다.
공백 제거
Tokenizer 처리
Fasttext 유사 단어 추출
Priority 검색엔진은 최신 트렌드 검색의 목적으로 IDS(Interest Date Score) 순으로 최대 상위 10000개 만 호출한다. 검색 결과가 10000개 이상 있을 시에는 다 가져 오겠지만 검색어의 결과가 소량일 때에는 적게 가져올 수 있다. 토큰화 + DB호출 작업에서 소요된 시간은 총 합쳐서 약 0.9초의 시간이 확인되었다.
추출된 문서와 검색어를 추천 뉴스피드와 같이, 서로 간의 유사도를 측정한다. 유사도의 측정의 자세한 알고리즘은 아래의 문서를 참고하길 바란다.
검색 알고리즘 설계현재 '세종대학교', '공모전'의 토큰을 통하여 추출된 10000개의 데이터와 검색어 간의 유사도 측정 시간은 약 0.2초로 확인할 수 있다.
2차 검색엔진은 각 카테고리 별로 검색을 수행한다. 카테고리는 다음과 같다.
진로&구인
공모전&행사 + 동아리&모임
위 카테고리를 제외한 모든 카테고리
커뮤니티
카테고리 분류에 대한 자세한 내용은 아래의 문서를 참고하길 바란다.
토픽 뉴스피드 목록검색 키워드는 1차 검색 엔진 때와 동일하다.
성능 분석 결과를 확인해보면, IDS 정렬 순 최대 상위 10000개 반환에서 개수에 따른 시간이 비례하는 것을 확인할 수 있다.
1차 검색엔진 설계 당시에는 카테고리 검색 엔진이 세부적인 분류 없이 통합하여 진행되었다. 하지만 30만 개의 데이터에서 정확한 결과값을 도출하는 부분에서도 아쉬움이 많이 나왔고, 속도 또한 배로 걸리는 현상이 나타났다.
이를 해결하기 위해서, 고안한 아이디어는 바로 병렬적인 검색 API 호출이다.
위 4개의 카테고리 API를 각각 따로 호출함으로써, 서버에서 병렬적인 연산처리가 가능해졌고 이를 통하여 많은 시간 단축의 효과를 볼 수 있었다.
검색엔진은 검색어의 결과에 따른 유동적인 시간으로 인해 정확한 성능 분석에는 어려움이 있지만 평균적으로 모든 API가 도착할 때까지의 시간은 약 1초로 매우 준수한 성능을 보여준다.