RecoPick



안녕하세요. RecoPick engineering팀입니다.

RecoPick 추천의 결과는 http://docs.recopick.com 에 설명되어 있는 대로, API 서버를 통해 json 형태로 결과를 가져가실 수 있습니다.

아래는 기존 시스템을 간략히 나타낸 그림입니다.

 

복잡한 로직을 거쳐 계산된 추천의 결과는 우선 MySQL master 서버에 저장되고, 다시 slave 서버로 replication 됩니다. API 서버가 특정 서비스의 특정 아이템에 대한 추천 결과 리스트 요청을 받으면, 우선 local에 있는 redis에 결과가 있는지 확인하고, 없으면 MySQL slave 서버에 요청하는 식이었습니다.

기본적으로 MySQL slave서버에는 크게 부하가 걸리는 작업이 없으며, 자주 요청되는 아이템의 추천 결과는 대부분 API 서버의 local redis에 cache 되어 있기 때문에, (cache hit ratio는 60 % 정도였습니다) 크게 무리 없이 서비스를 제공할 수 있었습니다.

현재 (2013년 8월 15일 기준) RecoPick API 서버들이 하루에 처리하는 추천 요청 수는 약 550만 건 정도이고, 대부분의 요청들은 수 ms 안에 처리됩니다. 하지만, 현재 API 서버들이 사용하는 Amazon EC2 인스턴스들은 m1.small 로 사용 가능한 메모리가 1.7 GB 밖에 되지 않는 저사양 서버이며, local redis에 큰 메모리를 할당할 수 없는 상황입니다. (현재는 약 100 MB 정도를 redis에 할당하여 cache로 활용합니다) 그러므로 local redis cache에 존재하지 않고, MySQL 메모리에도 올라와 있지 않는 변방의 아이템들에 대한 추천 리스트 요청의 경우, 처리하는데 종종 1초 이상 걸리는 경우도 있었습니다.

이러한 문제를 해결하기 위해 RecoPick에서는 아래와 같이 별도의 Redis 서버를 두고 추천의 결과를 cache하는 구조로 변경하였습니다.

메모리에 여유가 있는 서버(m2.xlarge)에 Redis를 설치하여 전체 추천의 결과를 함께 저장합니다. 그리고 API 서버에 추천 결과 요청이 들어오면, 우선 local redis를 찾고, 저장되어 있는 결과가 없다면, MySQL과 Cache 서버의 redis에 동시에 요청을 보낸 다음, 먼저 돌아 오는 응답을 사용자에게 제공합니다.

효과는 어땠을까요? :)

아래는 결과입니다.

보시는 것과 같이 처리하는데 1초 이상 걸리는 요청들이 평균 약 1,000건에서 100건 정도로 90 % 감소하였습니다.

이제 API 서버에서 추천의 결과를 더 빠르게 가져가서 사용자에게 서비스를 제공하시면 됩니다. :)

Posted by recopick