Computer >> 컴퓨터 >  >> 프로그래밍 >> Redis

Cloudflare KV vs Upstash Redis: 실측 성능 벤치마크로 확인한 차이

배포 플랫폼을 선택할 때 두 플랫폼 간의 실질적인 성능을 공정하게 비교하는 일은 생각보다 쉽지 않습니다. 특히 글로벌 엣지 배포를 통해 초저지연(low latency)을 내세우는 서버리스 플랫폼의 경우 더욱 그렇습니다. 하지만 정작 데이터를 가져오는 속도가 느리다면 낮은 지연 시간이 무슨 소용일까요? API가 사용자 바로 옆에서 실행되더라도, 데이터를 가져오기 위해 지구 반대편까지 네트워크 왕복을 해야 한다면 좋은 사용자 경험을 기대하기 어렵습니다.

전통적으로 컴퓨팅과 스토리지는 단일 서버, 혹은 적어도 동일한 데이터센터 안에 함께 위치했습니다. 그러나 서버리스와 엣지 함수의 부상과 함께 컴퓨팅과 스토리지가 분리되는 흐름이 나타났습니다. 이는 확장성과 가용성 측면에서 큰 장점이지만, 새로운 문제를 낳습니다. 바로 지연 시간(latency)입니다. 요즘은 API를 글로벌 엣지 네트워크에 배포하는 것이 매우 쉬워졌지만, 정작 데이터는 어떨까요? 데이터는 아직 뒤처져 있지만 분명 따라잡고 있는 중입니다.

이 글에서는 두 가지 서버리스 데이터스토어인 Cloudflare KVUpstash Redis의 성능을 비교해 보겠습니다. 두 서비스 모두 서버리스 방식이며 글로벌하게 분산되어 있지만, 접근 방식은 매우 다릅니다. Cloudflare KV는 풀 기반(pull-based) 키-값 저장소이고, Upstash는 액티브 복제(active replication)를 지원하는 Redis 호환 서비스입니다.

풀 기반(Pull-based): 데이터는 일반적으로 중앙 위치에 저장되고, 사용자의 요청이 있을 때에만 엣지 노드로 이동합니다. Cloudflare KV가 채택한 방식입니다.

액티브 복제(Active replication): 데이터가 모든 엣지 로케이션에 저장되며, 데이터스토어 자체가 동기화를 유지합니다. 데이터 변경 사항은 즉시 모든 리전에 복제됩니다. Upstash, 그리고 이를 채택한 Vercel의 방식입니다.

캐싱은 결국 키와 값의 묶음을 저장하는 것에 불과합니다. 개념은 단순하지만 매우 보편적으로 쓰이며, 두 데이터스토어의 성능을 비교하기에도 좋은 시나리오입니다. 간단한 캐싱 상황을 통해 Cloudflare KV와 Upstash Redis의 성능을 직접 측정해 보겠습니다.

벤치마크 환경

그렇다면 무엇을 테스트하는 걸까요?

Cloudflare Worker가 Cloudflare KV와 Upstash Redis에서 단일 값을 읽을 때 발생하는 지연 시간을 측정합니다.

  • Cloudflare Worker 1개
  • 1,000개의 키
  • 4KB ~ 64KB 데이터 크기(무작위)
  • 모든 키에 60초 TTL 적용
  • Worker를 호출하는 20개 리전
  • 초당 약 10건의 요청(RPS)

의도적으로 작은 키스페이스를 선택한 이유는 RPS를 과도하게 높이지 않고도 캐시 히트가 발생하도록 하기 위해서입니다.

Worker 코드

Worker 코드 자체는 매우 간단합니다. Redis에서 값을 읽고, KV에서 값을 읽은 뒤, 나중에 분석할 수 있도록 두 지연 시간을 반환합니다.

worker.ts

app.get("/test", async (c) => {
 const redis = Redis.fromEnv(c.env);
 
 const key = Math.floor(Math.random() * 1_000).toString();
 const minValueSize = 4 * 1024;
 const maxValueSize = 64 * 1024;
 const ttlSeconds = 60;
 const randomValue = new TextDecoder().decode(
 crypto.getRandomValues(
 new Uint8Array(
 Math.floor(Math.random() * (maxValueSize - minValueSize)) +
 minValueSize,
 ),
 ),
 );
 
 const beforeRedis = performance.now();
 const redisResponse = await redis.get(key);
 const redisLatency = performance.now() - beforeRedis;
 
 if (!redisResponse) {
 await redis.set(key, randomValue, {
 ex: ttlSeconds,
 });
 }
 
 const beforeKV = performance.now();
 const kvResponse = await c.env.ANDREAS_KV_BENCHMARK.get(key);
 const kvLatency = performance.now() - beforeKV;
 
 if (!kvResponse) {
 await c.env.ANDREAS_KV_BENCHMARK.put(key, randomValue, {
 expirationTtl: ttlSeconds,
 });
 }
 
 return c.json({
 kvLatency,
 redisLatency,
 });
});

결과 – 글로벌 지연 시간

약 30분간 벤치마크를 실행한 결과, 두 데이터스토어 간에 이미 상당한 차이가 관찰됩니다.

Cloudflare KV vs Upstash Redis: 실측 성능 벤치마크로 확인한 차이

이미지를 클릭하면 전체 크기로 확인할 수 있습니다.

보시다시피 Cloudflare KV는 Upstash Redis보다 꾸준히 느립니다. 이는 예상 밖의 결과였습니다. Cloudflare는 KV를 저지연 제품으로 홍보하고 있으며, Worker 자체와 동일한 플랫폼 위에서 구동되기 때문입니다. 기본적으로 모든 리전에 데이터를 보관하지는 않지만, 몇 분이 지나면 Worker가 실행되는 리전에 데이터가 캐시될 것이라 기대했었습니다.

혹시 시스템이 데이터를 함께 배치할 만큼 충분한 부하가 걸리지 않은 것일까요? 특정 리전만 격리한 뒤 부하를 대폭 늘려서 변화가 있는지 확인해 보겠습니다.

단일 리전 테스트

이번에는 훨씬 높은 RPS 조건에서 단일 리전의 결과를 살펴보겠습니다. 이론상 Cloudflare는 해당 리전의 모든 캐시를 워밍업하여 광고하는 것과 같은 초저지연을 달성할 수 있어야 합니다.

이 테스트는 첫 번째 테스트와 동일하지만, 단일 리전에서 약 400 RPS로 Worker를 호출한다는 점만 다릅니다.

Cloudflare KV vs Upstash Redis: 실측 성능 벤치마크로 확인한 차이

이미지를 클릭하면 전체 크기로 확인할 수 있습니다.

KV의 지연 시간이 크게 개선되었습니다:

  • P90: 742ms → 115ms
  • P99: 1,336ms → 560ms

Cloudflare가 실제로 실행 중인 Worker 근처에 데이터를 복제하기 위해서는 상당히 높은 부하가 필요한 것으로 보입니다. 그럼에도 여전히 Upstash Redis의 지연 시간에는 한참 미치지 못합니다. P90 지연 시간 115ms는 나쁘지 않지만, 0.5초를 넘는 P99 지연 시간은 분명히 체감됩니다. 참고로 데이터가 실제로 복제되도록 하기 위해 초당 약 400건의 요청을 보냈는데, 이는 이미 대부분의 중소규모 API가 받는 트래픽보다 많은 부하입니다.

흥미롭게도 Cloudflare가 데이터를 Worker에서 더 가깝게 혹은 더 멀리 이동한 시점을 아래 이미지에서 확인할 수 있습니다:

Cloudflare KV vs Upstash Redis: 실측 성능 벤치마크로 확인한 차이

이미지를 클릭하면 전체 크기로 확인할 수 있습니다.

가격 비교

비용 이야기 없이는 공정한 비교라고 할 수 없겠죠.

여기서 핵심 변수는 각 데이터스토어에 접근할 때의 건당 요청 비용입니다.

Cloudflare는 KV 읽기 100만 건당 $0.50를 청구하고, Upstash는 Redis 명령 100만 건당 $1를 청구합니다. 그 외에도 몇 가지 차이가 있는데, Cloudflare는 스토리지 비용이 더 비싼 반면 Upstash는 대역폭 비용이 더 비쌉니다. 다만 이 시나리오에서는 주요 비용 변수가 아닙니다.

  • Cloudflare 가격 정책
  • Upstash 가격 정책

Upstash가 당신에게 맞을까?

이 질문은 오직 스스로만 답할 수 있습니다.

물론 우리는 자사 제품과 그 가치를 진심으로 믿고 있기에 어느 정도 편향되어 있으니, 이 부분은 걸러 들어주시기 바랍니다.

중소규모 API를 운영하고 있다면 비용은 무시할 수 있는 수준이므로 지연 시간을 우선 고려해야 합니다. 반면 트래픽이 많은 API라면 Upstash의 고정 가격제가 Cloudflare KV보다 저렴합니다.

앞으로 필요한 기능이 set, get, list 수준으로 단순하고, 계속 Workers 플랫폼에 머물 예정이며, 높은 지연 시간이 애플리케이션에 허용된다면 Cloudflare KV가 적합한 선택일 수 있습니다. 모든 것이 한곳에서 처리되므로 별도로 신경 쓸 것이 없습니다.

위 질문 중 하나라도 '아니오'라고 답했다면 Upstash를 사용해 보시길 권합니다. Redis에는 pub/sub, 정렬된 집합(sorted sets), 해시(hash) 등 Cloudflare KV에 없는 다양한 기능이 있으며, Upstash는 이 모든 것을 지원합니다. 이미 Redis를 사용 중이라면 애플리케이션의 연결 대상을 Upstash로 변경하기만 하면 됩니다. 코드 수정 없이 바로 동작합니다.

결론

Cloudflare KV는 훌륭한 제품이지만, Redis와 같은 완전한 기능의 데이터베이스를 대체할 수는 없습니다. 지연 시간이 중요하지 않은 단순한 사용 사례에 적합한 도구입니다.

이 내용에 대해 궁금한 점이 있다면 Discord나 X(X 트위터)로 언제든 문의해 주세요.