GDB 도입의 배경 및 신규 시스템 설계
오늘날 투미유 서비스의 백엔드는 여러 가지 형태의 데이터베이스를 함께 사용하고 있고, 각 데이터를 최선이라고 판단되는 데이터베이스 형태에 저장함으로써 시스템 효율성을 높이고 있습니다. 하지만 이 모든 세팅들이 처음부터 완벽했던 것은 아닌데요. 특히 투덥 소셜 시스템에 사용되는 그래프 데이터베이스의 경우, 투미유 팀이 사용하는 여러 형태의 데이터베이스 중 사전 정보가 가장 적었던 데이터베이스로써 신규 도입 과정에서 다양한 어려움을 발생시키기도 했습니다.
총 5편에 걸친 이번 에피소드에서는 투미유 팀의 그래프 데이터베이스 도입 당시의 상황과 도입 과정에서 겪은 각종 시행착오들, 그리고 문제 해결을 위해 다각도로 고민했던 투미유 팀의 노력기를 공유하고자 합니다. 투미유 팀은 어떤 부분을 특히 더 신경썼는지, 또 그때 시도했던 것들은 무엇이었는지 지금부터 확인해 보시죠 :D
당시 투덥은 소통을 중시하는 유저들의 니즈를 반영해 홈 화면의 피드 형식 개편을 앞두고 있었습니다. 홈 개편을 통해 자신의 팔로우들이 어떤 활동을 했는지, 또 팔로우 외 다른 유저들은 어떤 활동을 하고 있는지등을 서비스 진입 시 바로 볼 수 있도록 계획한 것이죠. 그런데 달라지는 것이 메인이 되는 홈 화면인 만큼, 개편을 위한 자체적인 기능적 요구사항 외에도 추가 요구사항들이 붙게 되었고, 이로 인해 기존 시스템만으로는 달라질 환경을 완전히 만족시키기 어렵다고 판단했습니다.
커뮤니티 기능 제공을 목적으로 했던 '피드 형식'의 홈 화면 개편 이후,
● 홈 화면은 서비스 진입 시 바로 보이는 곳이므로 여전히 빠른 응답 속도가 필요했음.
● 서비스를 사용하는 모든 유저는 홈부터 지나게 되므로 높은 트래픽이 발생할 것으로 예상됨.
투덥 시스템은 대부분의 데이터를 RDB에 저장하고 있었고, 알림 시스템은 새롭게 추가되거나 변형되는 기능들에 맞추어 부분적으로만 변경해 나가고 있었습니다. 물론 이때도 알림 시스템 자체의 동작과 구조 부분에서 약간의 비효율이 존재했고, 유저 수의 증가로 인해 성능 상에서의 하락 또한 조금씩 나타나기는 했지만 여전히 크게 문제 되는 부분은 없었습니다. 하지만 앞으로 더 많은 기능이 추가될 수 있는 상황에서 복잡도나 트래픽이 갈수록 높아진다면 지금처럼 정상 동작하기 어려울 것이라는 사실은 자명했습니다.
특히 문제로 예상되었던 부분은,
● RDB에 로그성 데이터를 저장/관리 함으로 인해 발생하는 성능 이슈 우려
● 유저 수 증가에 따라 유저 관계 데이터가 급격히 증가함으로 인한 성능 이슈 우려
● 수신자 중심으로 생성되는 메시지 데이터로 인한 공간 및 처리의 비효율성
일반적으로 유저 관계 데이터나 메시지 데이터는 유저 수에 따라 지수적 증가의 경향을 보입니다. 투덥 또한 유저가 늘어남에 따라 해당 테이블들의 크기가 급격히 증가하며 성능이 저하되는 모습을 보이기 시작한 상황에서, 개편에 따른 신규 기능 추가 이후 홈에서 관련 데이터를 사용하기 시작한다면 트래픽 역시 증가될 수밖에 없는 상황이었죠. 게다가 팔로우 관계는 수시로 변하는 데이터이자 유저들이 즉각적으로 체감할 수 있는 부분으로써 서비스 홈에서 바로 사용되었기 때문에 캐싱 처리 등을 통해 성능 이슈를 회피하는 방법을 사용하는 것도 쉽지 않았습니다.
그리고 수신자 중심의 메시지 생성 방법은 유저 간의 팔로우 관계가 많아질수록 생성되어야 하는 메시지도 함께 증가하게 되는데, 투덥은 팔로우 관계 수에 제한을 두고 있지 않기 때문에 수천 개 이상의 관계를 가진 유저들도 존재했습니다. 이로 인해 특정 유저들의 액션은 백엔드에 과한 부담을 주었고, 이러한 상황에서 메시지 삭제 기능까지 추가하게 된다면 백엔드가 받는 부담은 더욱 가중될 것이라 판단되었습니다. 또한, 몇 개월씩 접속하지 않은 휴면 상태의 유저를 대상으로도 모두 메시지 데이터가 생성되면서 공간적 측면에서도 비효율적이라는 사실을 확인할 수 있었습니다.
이에, 기존 알림 시스템을 대체하면서 팔로우 관계를 중심으로 메시지 및 활동 정보를 종합적으로 표현할 수 있는 새로운 소셜 시스템을 만드는 것을 계획하게 되었습니다. 신규 시스템이 만족해야 할 요구사항은 다음의 3가지로 정리될 수 있었습니다.
신규 시스템이 충족시켜야 할 3가지 조건
● 홈에서 사용할 수 있는 빠른 응답시간과 높은 트래픽에도 안정적인 성능을 내는 시스템
● 유저 수 및 데이터가 증가하더라도 성능 저하를 일으키지 않거나 영향이 적은 구조를 가진 시스템
● 같은 메시지를 여러 개로 복사하여 만들지 않고도 필요한 기능들을 구현할 수 있는 시스템
소셜 시스템이 가지게 될 데이터는 '팔로우 관계 데이터'와 '메시지 데이터' 총 2가지였습니다.
1) 팔로우 관계 데이터
팔로우 관계 데이터의 경우 기존처럼 RDB를 사용하는 형태로는 유저별 테이블이라도 구축하지 않는 이상 전체 테이블의 크기가 커지는 것은 피할 수 없었습니다. 그렇다고 Document 형태의 DB를 사용하게 될 경우, 유저별 목록으로 구성할 수는 있게 되지만 팔로우/팔로워 두 가지에 대해 따로따로 저장하지 않는 이상 하나의 방향에만 인덱스 접근이 허용되고 다른 한쪽은 모든 데이터를 탐색하거나 하나의 관계를 두 개의 데이터로 만들어야 하는 문제가 존재했습니다.
뿐만 아니라 따로 만들어진 두 개의 데이터가 서로 다를 경우를 대비하기 위해 하나의 데이터로 강제로 통일시키거나 별도의 장소에 확실하게 기준이 되는 데이터를 저장하는 형태가 되어야 한다고 생각했는데, 이 경우 하나의 데이터가 세 개의 데이터로 늘어나게 되면서 앞서 정리한 신규 시스템 요구 조건 중 두 번째 조건에 어긋날 수밖에 없었습니다.
2) 메시지 데이터
메시지 데이터는 기존 시스템에서 수신자만을 중심으로 생성했기 때문에 생겨난 문제라고 생각했습니다. 이에 송신자/수신자 두 가지 모두를 중심으로 메시지를 생성할 수 있는 형태로 만들고자 시도했으나, 이는 개별 읽음 처리를 위해 별도의 관계 테이블을 두어야 하는 구조였고 이로 인해 해당 테이블의 크기가 커지는 것에 따른 성능 저하를 피할 수 없음을 알게 되었습니다.
고민을 이어가던 중 그래프 데이터베이스의 존재를 알게 되었고 이에 대한 추가 리서치를 진행했습니다. 그 결과 이미 많은 소셜 네트워크 서비스에서 사용되고 있던 그래프 데이터베이스는 기준 노드로부터 너비 우선 탐색을 한다는 점에서 유저 수 증가나 데이터량 증가에 따른 성능 저하가 적을 것이라 생각되었고, 노드에 여러 개의 관계를 설정할 수 있다는 특징 덕분에 하나의 메시지 노드만 생성하고도 개별 읽음 처리까지 수행 가능할 것이라고 기대되었습니다. 이에 투미유 팀은 그래프 데이터베이스를 바탕으로 SEND 관계의 방향성을 활용해 메시지가 송신자 중심인지 수신자 중심인지를 표시하고, 개별 읽음 처리는 별도의 관계를 설정하는 형태로 다음과 같은 시스템 구조를 설계했습니다.
User는 다른 User와 FOLLOW 관계를 가지며 User와 Message는 SEND 관계를 가집니다. 간단한 예시로 위 그림에서 User A에게 보여질 메시지 목록은 A에게 들어오는 방향의 SEND 관계로 연결된 Message #A001과 User A가 FOLLOW 하고 있는 User B와 D의 나가는 방향의 SEND 관계로 연결된 Message #B003, #D002가 보여지게 됩니다. 그리고 확인한 User와 Message 간에 READ 관계로 연결하여 읽었음을 표시할 수 있습니다.
최초 테스트는 Neo4j로 진행했습니다. 가능 여부 테스트를 목적으로 투덥 유저 수 보다 많은 User 노드와 FOLLOW 관계를 생성하고, Message 노드와 SEND 관계를 랜덤하게 만들어 테스트 환경을 조성한 뒤에 아래와 같은 테스트를 설계했습니다.
● 팔로우 유저 목록 가져오기
(기준 노드 중심 단일 깊이 관계, (:User)-[:FOLLOW]→(:User))
● 내가 받을 메시지 목록 가져오기
(기준 노드 중심 다중 깊이 관계, (:User)-[:FOLLOW]→(:User)-[:SEND]→(:Message))
첫 테스트 수행 당시 기준 노드를 중심으로 너비 우선 탐색을 하는 그래프 데이터베이스의 기본적 특성에 따라 빠른 응답 속도가 나올 것이라 기대했습니다. 하지만 결과는 좋지 않았습니다. 유저 수에 관계없을 것이라 생각해 많은 유저 노드를 만들었는데, 타겟 유저 노드를 찾는 과정에서 전체 유저 노드를 대상으로 검색하는 까닭에 생각보다 많은 시간이 걸린 것입니다. 이 부분은 유저 속성 중 식별 키에 해당하는 속성에 인덱스 설정을 하여 전체를 조회하지 않고 바로 타겟 유저 노드에 바로 접근하도록 함으로써 해결할 수 있었습니다.
첫 테스트를 거치며 인덱스가 설정된 덕분에 두 번째 테스트에서도 준수한 성능을 확인할 수 있었습니다. 오히려 응답시간에 더 큰 영향을 끼치는 부분은 마지막에 반환하는 노드의 수였습니다. 이는 반환하는 노드의 수만 많지 않도록 조정해 주면 되었는데, 실제 클라이언트에서 한 번에 가져가는 단위가 크지 않았기 때문에 문제가 없을 것이라 판단했습니다.
이러한 테스트 결과를 바탕으로 본격적으로 그래프 데이터베이스를 기반으로 한 투덥 소셜 시스템의 개발이 시작되었습니다.
(2편에서 계속됩니다.)