콘텐츠로 이동

Blog

액션베이스(Actionbase) 오픈소스 공개

처음엔 단순하지만, 규모가 커질수록 복잡해지는 기능

피드나 상품 페이지에 좋아요 기능을 추가한다고 생각해 봅시다.

기본적인 구현은 단순합니다. 누가(사용자 ID)가 무엇을(대상 ID) 좋아했는지를 기록하면 됩니다. 좋아요 수는 동일한 대상 ID를 가진 레코드를 세는 것(COUNT)으로 계산할 수 있습니다. 그래서 대부분의 시스템은 사용자 ID와 대상 ID를 담은 단일 테이블로 시작합니다. 조회 패턴에 맞춰 인덱스를 추가하고, COUNT 비용이 커지면 캐시를 도입합니다. 그리고 이 방식은 대부분의 규모에서는 잘 동작합니다.

하지만 서비스가 일정 수준 이상으로 성장하면, 상황이 달라지기 시작합니다.

샤딩을 고민하게 하고, 캐시 정합성을 맞추기 위한 보정 로직이 반복해서 추가됩니다. 처음에는 단순했던 모델은 점점 복잡해집니다. “좋아요”처럼 단순해 보이는 기능을 유지하기 위한 비용은 계속 증가합니다. 대규모 트래픽을 경험한 팀이라면, 언젠가는 같은 질문에 도달하게 됩니다.

“이게 정말 계속 가져가야 할 방식일까?”

이 질문 앞에서, 우리는 하나의 결론에 도달했습니다.

“다른 접근이 필요하다.”

같은 문제에 대한 다른 해답 — 사용자 상호작용을 다루는 데이터베이스

액션베이스는 대규모 트래픽 환경에서도 사용자 상호작용을 안정적으로 처리하기 위해 설계된 데이터베이스입니다. 여기서 말하는 상호작용이란 좋아요, 반응, 팔로우처럼 사용자와 대상 사이에서 발생하는 모든 행동을 의미합니다. 액션베이스는 이를 다음과 같이 모델링합니다.

누가(actor)가 어떤 행동(action)을 어떤 대상(target)에 했는가.

예: “User1”(actor)이 Product A”(target)에 좋아요(action)를 눌렀다.

읽기를 먼저 정의하고, 쓰기를 설계하다

섹션 제목: “읽기를 먼저 정의하고, 쓰기를 설계하다”

“다른 접근”이 실제로 의미하는 것

액션베이스의 핵심 아이디어는 단순합니다.

쓰기 시점에, 읽기에 필요한 모든 결과를 미리 만들어 둔다.

사용자가 좋아요를 누르는 순간, 사용자의 좋아요 목록이 갱신되고, 대상의 좋아요 수가 증가하며, 정렬과 조회에 필요한 순서 정보까지 하나의 쓰기 흐름 안에서 함께 업데이트됩니다. 그 결과, 읽기 시점에는 어떠한 집계나 추가 연산도 필요하지 않습니다. 이미 준비된 결과를 그대로 읽기만 하면 됩니다.

이것이 액션베이스가 기반으로 삼은 “다른 접근”입니다.

“어떻게 읽기를 빠르게 만들 것인가”를 나중에 고민하는 대신, 빠른 읽기를 먼저 정의하고, 그에 맞춰 쓰기를 설계하는 방식입니다.

이 접근은 이미 실서비스 환경에서 검증되었습니다. 액션베이스는 선물하기와 같은 카카오 주요 서비스의 대규모 트래픽 환경에서 안정적으로 운영되고 있습니다.

개별 기능에서 공통 구조로

이 글에서는 좋아요를 예로 들었지만, 액션베이스가 다루는 범위는 특정 기능에 국한되지 않습니다.

좋아요 👍, 최근 본 👀, 팔로우 👥, 그리고 주고받은 선물까지 🎁— 사용자 상호작용으로 표현할 수 있다면 액션베이스로 풀어낼 수 있습니다. 겉보기에는 서로 다른 기능처럼 보이지만, 데이터 모델의 관점에서 보면 이들은 결국 하나의 공통된 구조로 수렴합니다.

이 구조가 쌓이기 시작하면, 개별 기능을 넘어 더 큰 관계 그래프로 확장됩니다. 사용자를 중심으로 콘텐츠와 상품이 연결되고, 사람과 사람이 이어지며, 서비스 전반의 흐름이 하나의 일관된 구조 안에서 저장되고, 조회되고, 따라갈 수 있게 됩니다.

이 문제를 각자 다른 방식으로 반복해서 해결하기보다는, 여러 환경에서 함께 검증하고 다듬을 수 있는 공통된 구조가 필요하다고 믿습니다. 액션베이스는 사용자 상호작용을 개별 기능이 아니라 연결 가능한 관계로 다루려는 접근이며, 오픈소스는 그 구조를 함께 만들어 가는 우리의 방식입니다.

데이터가 액션베이스로 모이면, 이전에는 보이지 않던 가능성이 열릴지도 모릅니다.

액션베이스를 살펴보고, 미래를 함께 만들어 주세요.