
Ludo의 실시간 크로스체인 평판 플랫폼 구축기
요약
Ludo의 실시간 크로스체인 평판 플랫폼 구축 과정을 다룹니다. 15개 이상의 블록체인 네트워크에서 발생하는 대규모 데이터를 실시간으로 처리하여 지갑의 신뢰 점수를 생성하는 아키텍처와 엔지니어링 과제를 설명합니다.
핵심 포인트
- 15개 이상의 블록체인 네트워크 지원 및 200만 개 이상의 지갑 주소 처리
- 초당 10,000개 이상의 이벤트 처리 및 200ms 미만의 API 응답 시간 달성
- 배치 작업이 아닌 실시간 스트리밍 데이터 처리 방식의 중요성 강조
- 확장 가능한 파이프라인 설계를 통한 신규 네트워크 추가 용이성 확보
퍼블릭 블록체인 (Public blockchains)은 트랜잭션을 투명하게 공개합니다.
하지만 이들은 훨씬 더 유용한 제품적 질문에는 자동으로 답해주지 않습니다:
해당 트랜잭션 뒤에 있는 지갑을 신뢰할 수 있는가?
저는 Pharos Production - 소프트웨어 개발 회사의 설립자이자 CTO입니다. 2021년부터 저희 팀은 Ludo와 협력하여 플랫폼의 블록체인 인덱싱 (blockchain indexing), 실시간 데이터 처리 (real-time data processing), 스마트 컨트랙트 (smart contracts), 백엔드 인프라 (backend infrastructure) 및 외부 API (external APIs)를 구축하고 확장해 왔습니다.
하나의 지갑은 여러 네트워크에 걸쳐 수년간의 활동 내역을 가질 수 있습니다. 그 이력에는 전송, 스마트 컨트랙트 호출, 그리고 수백 개의 프로토콜과의 상호작용이 포함될 수 있습니다. 데이터는 공개되어 있지만, 이를 최신의 사용 가능한 신뢰 신호 (trust signal)로 전환하는 것은 별개의 엔지니어링 문제입니다.
그리고 그것이 바로 Ludo - Web3 평판 플랫폼 이면에 있는 문제입니다.
Ludo는 온체인 (onchain) 행동을 사용자 및 기타 Web3 제품이 소비할 수 있는 평판 데이터로 변환하는 라이브 크로스체인 (cross-chain) 평판 플랫폼입니다.
이 글에서는 저희가 공개적으로 논의할 수 있는 아키텍처 (architecture), 이를 형성한 제약 조건들, 그리고 이 프로젝트를 통해 얻은 엔지니어링 교훈을 다룹니다.
프로덕션 요구사항
이것은 소수의 지갑 샘플을 기반으로 구축된 프로토타입 (prototype)이 아니었습니다.
플랫폼은 증가하는 사용자 수와 외부 통합을 지원하면서 15개 이상의 블록체인 네트워크에서 작동해야 했습니다.
프로덕션 목표에는 다음이 포함되었습니다:
- 200만 개 이상의 점수가 매겨진 지갑 주소
- 초당 10,000개 이상의 블록체인 이벤트 처리
- 200밀리초 (milliseconds) 미만의 API 응답 시간
- 99.9%의 플랫폼 가동 시간 (uptime)
- 50개 이상의 파트너 통합
- 실시간 평판 업데이트
또한 시스템은 전체 처리 파이프라인 (processing pipeline)을 재설계하지 않고도 추가적인 네트워크를 지원할 수 있어야 했습니다.
그러한 요구사항은 예약된 배치 작업 (scheduled batch jobs)이나 API 요청 경로 (API request path) 내부의 무거운 계산에만 의존하는 아키텍처를 즉시 배제하게 만들었습니다.
평판은 스트리밍 데이터 문제 (streaming data problem)입니다
평판 점수 (reputation score)는 지갑의 현재 상태를 반영할 때만 유용합니다.
만약 점수가 24시간마다 한 번씩 재계산된다고 가정해 봅시다. 지갑은 계산 직후에 행동을 바꿀 수 있으며, 연결된 제품들은 오래된 정보 (stale information)를 바탕으로 계속해서 의사결정을 내리게 됩니다.
API 소비자 (API consumer)가 요청할 때마다 전체 점수를 계산하는 것은 또 다른 문제를 야기합니다. 요청 경로가 방대한 양의 과거 데이터를 읽고 집계하는 책임을 떠맡게 되기 때문입니다. 지갑과 관련된 활동량이 많아질수록 지연 시간 (latency)이 증가합니다.
Ludo의 경우, 우리는 평판을 지속적으로 업데이트되는 데이터 제품 (data product)으로 취급했습니다.
블록체인 활동은 스트림 (stream) 형태로 시스템에 유입됩니다. 새로운 이벤트는 도착하는 즉시 처리되며, 외부 제품이 요청하기 전에 관련 평판 상태가 업데이트됩니다.
이를 통해 비용이 많이 드는 이벤트 처리 과정을 지연 시간에 민감한 API 경로 외부로 분리할 수 있습니다.
단순화된 수준에서 아키텍처는 다음과 같습니다:
Blockchain networks
|
v
...
이는 공개된 단순화된 뷰입니다. 독점적인 점수 산정 규칙 (scoring rules)과 내부 데이터 모델 (internal data models)은 의도적으로 제외되었습니다.
블록체인 인제스션 (ingestion)과 평판 로직의 분리
15개 이상의 네트워크를 지원하는 것은 점수 산정 공식 자체와는 거의 관련이 없는 문제를 발생시킵니다.
각 체인은 서로 다른 데이터 구조 (data structures), 완결성 모델 (finality models), 인덱싱 동작 (indexing behavior)을 노출합니다. 심지어 유사한 동작이라도 네트워크마다 다르게 표현될 수 있습니다.
만약 모든 다운스트림 서비스 (downstream service)가 모든 블록체인의 네이티브 포맷을 이해해야 한다면, 새로운 네트워크를 추가하는 비용이 점진적으로 증가하게 됩니다. 또한 점수 산정 계층 (scoring layer)이 체인별 구현 세부 사항에 강하게 결합 (tightly coupled)됩니다.
따라서 아키텍처는 블록체인 인제스션 (blockchain ingestion)과 평판 처리 (reputation processing) 사이에 명확한 경계가 필요합니다.
체인별 인덱싱 (Chain-specific indexing)은 네트워크를 읽고 관련 활동을 일관된 내부 표현 (internal representation)으로 변환하는 역할을 담당합니다. 이를 통해 다운스트림 프로세싱 (downstream processing)은 원시 체인 데이터를 반복적으로 해석하는 대신 정규화된 이벤트 (normalized events)를 기반으로 동작할 수 있습니다.
이러한 분리는 우리 팀이 플랫폼의 나머지 부분을 매번 다시 구축하지 않고도 추가적인 블록체인 네트워크에 대해 프로덕션급 (production-grade) 인덱싱을 제공할 수 있도록 도왔습니다.
더 넓은 관점에서의 교훈은 명확합니다:
시스템 경계에서 체인별 동작을 정규화(Normalize)하십시오. 네이티브 블록체인 형식이 전체 백엔드(backend)로 퍼져나가게 두지 마십시오.

이벤트 백본 (event backbone)으로서의 Kafka
Apache Kafka는 블록체인 활동의 연속적인 스트림을 처리합니다.
Kafka의 역할은 단순히 두 서비스 간에 데이터를 이동시키는 것보다 더 큽니다. Kafka는 인제스션 (ingestion)과 프로세싱 (processing) 사이에 내구성이 있는 경계를 제공합니다.
블록체인 인덱서 (indexers)는 모든 컨슈머 (consumer)와 직접적으로 결합되지 않고도 이벤트를 발행할 수 있습니다. 프로세싱 서비스는 독립적으로 발전할 수 있으며, 인덱싱 레이어 (indexing layer)를 수정하지 않고도 추가적인 컨슈머를 도입할 수 있습니다.
이는 평판 플랫폼에서 매우 중요한데, 동일한 소스 활동이 결국 여러 워크플로우 (workflows)를 지원할 수 있기 때문입니다:
- 평판 상태 업데이트 (Reputation state updates)
- 이력 분석 (Historical analysis)
- 제품 대시보드 (Product dashboards)
- 감사 및 추적 가능성 (Audit and traceability)
- 새로운 스코어링 모델 (New scoring models)
또한 Kafka를 사용하면 이벤트가 도착하는 속도와 다운스트림 서비스가 이를 처리하는 속도 사이의 단기적인 차이를 흡수할 수 있습니다.
이러한 유형의 시스템에서는 파티셔닝 (partitioning)에 특별한 주의가 필요합니다. 동일한 논리적 엔티티 (logical entity)를 업데이트하는 이벤트는 예측 가능한 처리 순서를 보장해야 하는 동시에, 워크로드 (workload)는 클러스터 (cluster) 전체에 분산되어야 합니다.
정확한 파티셔닝 (partitioning) 모델은 제품의 점수 산정 규칙에 따라 달라지지만, 일반적인 요구 사항은 일관됩니다. 즉, 순서 보장 (ordering guarantees)과 수평적 확장성 (horizontal scalability)을 반드시 함께 고려해야 합니다.
증분 처리 (incremental processing)를 위한 Flink
Apache Flink는 시스템을 통과하는 블록체인 이벤트를 처리합니다.
중요한 아키텍처 결정은 지갑의 전체 이력을 반복적으로 재구축하는 대신, 평판 상태 (reputation state)를 증분적으로 업데이트하는 것이었습니다.
관련 이벤트가 도착하면, 처리 계층 (processing layer)은 해당 이벤트가 기존 평판 상태에 어떤 영향을 미치는지 결정합니다. 업데이트된 결과는 이후 빠른 조회를 위해 저장될 수 있습니다.
이러한 접근 방식은 두 가지 장점을 제공합니다.
첫째, 새로운 이벤트에 필요한 처리량이 지갑의 전체 연령 (age)에 따라 증가할 필요가 없습니다.
둘째, API 소비자 (consumers)가 과거 데이터의 집계 (aggregation)를 기다리게 만들지 않고도 점수를 최신 상태로 유지할 수 있습니다.
실시간 처리 (real-time processing)는 또한 다음과 같은 운영상의 질문을 던집니다.
- 중복 이벤트는 어떻게 처리해야 하는가?
- 이벤트가 늦게 도착하면 어떻게 되는가?
- 체인 재구성 (chain reorganization)이 파생된 상태에 어떤 영향을 미치는가?
- 점수 산정 로직이 변경된 후 계산을 어떻게 다시 실행 (replay)할 수 있는가?
- 어떤 상태가 감사 가능 (auditable)하게 유지되어야 하는가?
이러한 질문들은 스트림 처리 (stream-processing) 프레임워크를 선택하는 것만으로는 해결할 수 없습니다. 이들은 처음부터 데이터 모델 및 운영 절차의 일부가 되어야 합니다.
서로 다른 워크로드 (workloads)를 위한 다양한 저장 시스템 사용
Ludo와 같은 플랫폼은 하나의 보편적인 데이터베이스 워크로드를 가지고 있지 않습니다.
운영 평판 상태 (operational reputation state), 과거 데이터, 그리고 실시간 분석 쿼리 (analytical queries)는 서로 다른 액세스 패턴 (access patterns)을 가집니다. 이 모든 것을 하나의 데이터베이스에 강제로 밀어 넣는 것은 기술 목록을 단순화할 수는 있겠지만, 시스템의 확장성을 어렵게 만들 것입니다.
공개된 아키텍처는 여러 전문화된 구성 요소들을 사용합니다.
| 구성 요소 (Component) | 주요 역할 (Primary role) |
|---|---|
| Apache Cassandra | 사용자 및 평판 데이터를 위한 확장 가능한 저장소 (Scalable storage) |
| ... |
Cassandra는 액세스 패턴 (access patterns)이 알려져 있고 수평적 확장 (horizontal scale)이 중요한 분산 운영 저장소 (distributed operational storage)를 지원합니다.
Pinot은 신선한 데이터와 낮은 쿼리 지연 시간 (low query latency)이 필요한 분석 워크로드 (analytical workloads)를 처리합니다. 이는 평판 정보를 필터링하거나 분석해야 하는 대시보드, 큐레이션 도구 및 API 소비자 (API consumers)에게 유용합니다.
Delta Lake는 더 깊은 분석과 장기적인 처리를 위해 정리된 이력 데이터 (historical data)를 보관합니다.
이는 폴리글랏 퍼시스턴스 (polyglot persistence)를 의도적으로 활용한 사례입니다. 각 시스템은 스택의 또 다른 항목이 되는 대신 명확한 책임을 가집니다.
API 경로를 빠르게 유지하기
플랫폼은 API 응답 시간을 200밀리초 (milliseconds) 미만으로 유지해야 했습니다.
이 목표 뒤에 있는 주요 아키텍처 원칙은 외부 요청 중에 전체 평판 계산을 수행하는 것을 피하는 것이었습니다.
API 호출이 도착할 때쯤이면, 스트림 처리 (stream-processing) 레이어가 이미 관련 블록체인 활동을 처리하고 구체화된 평판 상태 (materialized reputation state)를 업데이트한 상태가 됩니다.
API 레이어는 제어된 검색 (retrieval), 권한 부여 (authorization) 및 응답 구성에 집중할 수 있습니다.
Spring Boot는 이러한 서비스들을 위한 백엔드 기반을 제공합니다. 또한 플랫폼이 다양한 소비자들에게 평판 데이터를 노출할 수 있는 일관된 방법을 제공합니다.
해당 소비자들은 다음과 같습니다:
- Ludo 웹 플랫폼
- 브라우저 확장 프로그램 (browser extension)
- Telegram 미니 앱 (Telegram Mini App)
- 큐레이터 도구 (Curator tools)
- 외부 Web3 제품
- 모바일 통합 (Mobile integrations)
플랫폼은 또한 소울바운드 NFT (soulbound NFTs)를 통해 평판을 나타냅니다. 이러한 자산은 전송하거나 판매할 수 없으므로, 그 표현은 이를 생성한 지갑 활동과 연결된 상태로 유지됩니다.
NFT는 검증 가능한 제품 표면 (verifiable product surface)입니다. 그 뒤에 있는 스트리밍 및 스코어링 인프라가 해당 표현을 최신 상태로 유지합니다.
통합은 제품의 일부입니다
API와 문서를 메인 플랫폼이 완성된 후에 이루어지는 작업으로 취급하기는 쉽습니다.
그러한 접근 방식은 Ludo의 가치를 제한했을 것입니다.
크로스체인 평판 시스템 (cross-chain reputation system)은 다른 제품들이 자신의 워크플로 (workflows) 내에 해당 신뢰 신호 (trust signal)를 배치할 수 있을 때 더욱 유용해집니다. 이는 개발자 경험 (developer experience)을 별도의 문서화 작업이 아닌 아키텍처 (architecture)의 일부로 만듭니다.
Pharos Production은 외부 플랫폼을 위한 API를 개발하고 문서화했습니다. 또한 각 파트너가 요구되는 커스텀 작업량을 줄일 수 있도록 SDK와 통합 자료 (integration materials)를 제작했습니다.
그 결과, 파트너 온보딩 (onboarding) 시간이 60% 이상 단축되었습니다.
현재 50개 이상의 파트너가 DeFi, 게이밍, 소셜 제품을 포함한 Web3 유스케이스 (use cases) 전반에서 이 플랫폼을 사용하고 있습니다.
이 교훈은 블록체인 너머에도 적용됩니다:
인프라 제품은 내부 서비스가 작동한다고 해서 완성되는 것이 아닙니다. 다른 팀이 원래 개발자에게 의존하지 않고도 안전하게 이를 통합할 수 있을 때 비로소 완성됩니다.
인프라 및 신뢰성
플랫폼은 Kubernetes와 Istio를 사용하여 AWS 위에서 실행됩니다.
Kubernetes는 독립적으로 진화하는 서비스들을 배포하고 확장하는 데 필요한 오케스트레이션 계층 (orchestration layer)을 제공합니다. Istio는 클러스터 전반의 서비스 트래픽 관리 (traffic management)를 담당합니다.
Terraform은 반복 가능한 인프라 관리를 지원하며, 지속적인 부하 테스트 (continuous load testing)를 통해 플랫폼이 변경됨에 따라 성능이 요구 범위 내에 유지되는지 검증합니다.
이 운영 모델은 두 가지 실질적인 요구 사항을 중심으로 설계되었습니다.
첫 번째는 트래픽 변동성 (traffic variability)입니다. 블록체인 활동과 파트너의 수요는 항상 예측 가능한 속도로 성장하지 않습니다.
두 번째는 지속적인 확장 (continuous expansion)입니다. 네트워크와 통합을 추가하면 새로운 서비스, 데이터 흐름 (data flows), 배포 요구 사항이 도입됩니다.
따라서 인프라는 평판 API (reputation API)에 의존하는 제품들을 중단시키지 않으면서 트래픽 급증 시에도 확장할 수 있어야 했습니다.
그 결과, 구축된 플랫폼은 긴 대기 지연 (queuing delays)이나 데이터 손실 없이 초당 10,000개 이상의 블록체인 이벤트를 처리하면서 99.9%의 업타임 (uptime)을 유지하고 있습니다.
이러한 규모에서는 업타임 (uptime)과 지연 시간 (latency)이 단순한 인프라 지표에 그치지 않습니다. 이는 신뢰 모델 (trust model)의 일부입니다.
활동이 증가하는 바로 그 시점에 API를 사용할 수 없게 된다면, 평판 신호 (reputation signal)를 신뢰하기 어려워집니다.
Pharos Production이 제공한 결과물
Ludo를 위한 우리의 작업은 단일 격리 서비스 그 이상을 다루었습니다.
Pharos Production은 다음 항목에 기여했습니다:
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기