Cloudflare Workers, Fastly Compute, Akamai Edge의 Wasm 실행 환경을 비교하고, 엣지에서의 AI 추론, 콜드 스타트 성능 분석, 엣지 배포 전략을 다룹니다.
**엣지 컴퓨팅(Edge Computing)**은 사용자와 물리적으로 가장 가까운 위치에서 코드를 실행하는 패러다임입니다. 전통적인 중앙 집중식 서버 구조에서는 서울의 사용자가 미국 동부의 서버에 요청을 보내면, 네트워크 왕복 시간만 200ms 이상이 소요됩니다. 엣지 컴퓨팅은 서울의 PoP에서 요청을 직접 처리하여 이 지연을 10ms 이내로 줄입니다.
WebAssembly가 엣지에 적합한 이유는 다음과 같습니다.
Cloudflare Workers는 330개 이상의 글로벌 로케이션에서 코드를 실행하는 엣지 컴퓨팅 플랫폼입니다. V8 엔진 기반으로, JavaScript와 WebAssembly를 모두 지원합니다.
Cloudflare Workers는 V8 Isolate 기반의 실행 모델을 사용합니다. 전통적인 컨테이너나 VM 대신, V8 Isolate가 가벼운 격리 경계를 제공합니다. 하나의 프로세스 내에서 수천 개의 Isolate가 동시에 실행되므로, 프로세스 생성 오버헤드가 없습니다.
// Cloudflare Workers에서 Wasm 사용
import wasmModule from './processor.wasm';
export default {
async fetch(request, env) {
// Wasm 인스턴스 생성
const instance = await WebAssembly.instantiate(wasmModule);
// URL에서 파라미터 추출
const url = new URL(request.url);
const input = url.searchParams.get('input') || '';
// Wasm 함수로 처리
const encoder = new TextEncoder();
const inputBytes = encoder.encode(input);
// 메모리에 쓰기
const memory = new Uint8Array(instance.exports.memory.buffer);
memory.set(inputBytes, 0);
// 처리 함수 호출
const resultLen = instance.exports.process(0, inputBytes.length);
// 결과 읽기
const resultBytes = memory.slice(0, resultLen);
const result = new TextDecoder().decode(resultBytes);
return new Response(JSON.stringify({ result }), {
headers: { 'Content-Type': 'application/json' }
});
}
};workers-rs SDK를 사용하면 Rust로 Workers를 직접 작성할 수 있습니다.
use worker::*;
#[event(fetch)]
async fn fetch(req: Request, env: Env, _ctx: Context) -> Result<Response> {
let router = Router::new();
router
.get_async("/api/process/:input", |_req, ctx| async move {
let input = ctx.param("input").unwrap();
// 연산 집약적 처리를 Rust/Wasm에서 수행
let result = heavy_computation(input);
Response::from_json(&serde_json::json!({
"input": input,
"result": result,
"edge_location": "auto"
}))
})
.run(req, env)
.await
}
fn heavy_computation(input: &str) -> String {
// SHA-256 해시 등 연산 집약적 작업
let hash = sha256(input.as_bytes());
hex::encode(hash)
}Cloudflare Workers의 무료 플랜은 요청당 10ms CPU 시간, 유료 플랜은 요청당 30초 CPU 시간을 제공합니다. 엣지에서의 처리는 가볍고 빠른 작업에 최적화되어 있으므로, 장시간 실행이 필요한 작업은 별도의 서버에서 처리하는 것이 적합합니다.
Fastly Compute는 Wasm을 네이티브 실행 엔진으로 사용하는 엣지 플랫폼입니다. Cloudflare Workers가 V8 기반인 반면, Fastly는 자체 개발한 Lucet(현재는 Wasmtime으로 전환) 런타임을 사용합니다.
Fastly의 가장 큰 기술적 차별점은 마이크로초 단위의 Wasm 인스턴스화입니다. AOT 컴파일과 메모리 스냅샷 기술을 활용하여, 새 요청이 들어올 때 거의 즉시 Wasm 모듈을 실행할 수 있습니다.
use fastly::http::{header, Method, StatusCode};
use fastly::{Error, Request, Response};
#[fastly::main]
fn main(req: Request) -> Result<Response, Error> {
// 요청 라우팅
match (req.get_method(), req.get_path()) {
(&Method::GET, "/api/geo") => {
// Fastly의 지리 정보 활용
let geo = req.get_client_geo()
.unwrap_or_default();
let body = serde_json::json!({
"country": geo.country_code(),
"city": geo.city(),
"latitude": geo.latitude(),
"longitude": geo.longitude(),
});
Ok(Response::from_status(StatusCode::OK)
.with_header(header::CONTENT_TYPE, "application/json")
.with_body_json(&body)?)
}
(&Method::GET, path) if path.starts_with("/api/transform/") => {
// 이미지 변환 등 연산 처리
let image_url = &path["/api/transform/".len()..];
// 오리진에서 이미지 가져오기
let mut origin_resp = Request::get(image_url)
.with_header("Host", "images.example.com")
.send("origin_backend")?;
let image_data = origin_resp.take_body_bytes();
// Wasm에서 이미지 처리 (리사이즈, 포맷 변환 등)
let processed = process_image(&image_data, 800, 600);
Ok(Response::from_status(StatusCode::OK)
.with_header(header::CONTENT_TYPE, "image/webp")
.with_header(header::CACHE_CONTROL, "public, max-age=86400")
.with_body(processed))
}
_ => Ok(Response::from_status(StatusCode::NOT_FOUND)
.with_body_text_plain("Not Found"))
}
}8장에서 다룬 Akamai의 Fermyon 인수는 엣지 컴퓨팅 관점에서 가장 의미있는 사건입니다. 4,000개 이상의 PoP이라는 비교 불가능한 규모의 인프라에 Spin 기반 Wasm 실행 환경이 통합되었습니다.
| 항목 | Cloudflare | Fastly | Akamai |
|---|---|---|---|
| PoP 수 | 330+ | 90+ | 4,000+ |
| Wasm 런타임 | V8 | Wasmtime | Wasmtime (Spin) |
| 실행 모델 | V8 Isolate | Per-Request | Per-Request |
| 컴포넌트 모델 | 미지원 | 미지원 | 지원 (Spin 2.x) |
| 최대 실행 시간 | 30초 (유료) | 120초 | 가변 (플랜별) |
| 프레임워크 | Workers API | Compute API | Spin |
# Spin 앱을 Akamai Edge에 배포
spin deploy --provider akamai
# 배포 상태 확인
spin cloud status
# 로그 확인
spin cloud logs --follow엣지 플랫폼을 선택할 때는 PoP의 지리적 분포가 중요합니다. 주요 사용자 기반이 한국과 일본이라면, 해당 지역의 PoP이 충분한 플랫폼을 선택해야 합니다. Akamai는 아시아 태평양 지역에서 가장 많은 PoP을 보유하고 있습니다.
Vercel Edge Functions는 Next.js 개발자에게 친숙한 엣지 런타임입니다. V8 기반으로 Cloudflare Workers와 유사한 실행 환경을 제공하며, Wasm 모듈을 직접 임포트하여 사용할 수 있습니다.
import { NextRequest, NextResponse } from 'next/server';
// Edge Runtime 지정
export const runtime = 'edge';
// Wasm 모듈 임포트
import wasmModule from '../../../wasm/processor.wasm?module';
let wasmInstance: WebAssembly.Instance | null = null;
async function getWasmInstance() {
if (!wasmInstance) {
wasmInstance = await WebAssembly.instantiate(wasmModule);
}
return wasmInstance;
}
export async function GET(request: NextRequest) {
const instance = await getWasmInstance();
const searchParams = request.nextUrl.searchParams;
const n = parseInt(searchParams.get('n') || '10');
// Wasm 함수 호출
const result = (instance.exports.fibonacci as Function)(n);
return NextResponse.json({
input: n,
result: result,
computed_at: 'edge',
});
}엣지 컴퓨팅의 새로운 프론티어는 AI 추론입니다. 작은 모델을 엣지에 배포하여 지연 시간을 최소화하고, 데이터가 사용자의 지역을 벗어나지 않도록 합니다.
use spin_sdk::http::{IntoResponse, Request, Response};
use spin_sdk::http_component;
// 경량 AI 모델을 Wasm에 임베딩
mod model;
#[http_component]
fn classify(req: Request) -> anyhow::Result<impl IntoResponse> {
let body: serde_json::Value = serde_json::from_slice(req.body())?;
let text = body["text"].as_str().unwrap_or("");
// 엣지에서 텍스트 분류 수행
let classification = model::classify_text(text);
let response = serde_json::json!({
"text": text,
"classification": classification.label,
"confidence": classification.confidence,
"processed_at": "edge",
"latency_benefit": "~195ms saved vs origin"
});
Ok(Response::builder()
.status(200)
.header("content-type", "application/json")
.body(serde_json::to_string(&response)?)
.build())
}엣지에서의 AI 추론은 모델 크기에 제약이 있습니다. 대부분의 엣지 플랫폼은 Wasm 모듈 크기에 제한을 두고 있으며(Cloudflare Workers 무료 플랜: 1MB, 유료: 10MB), 대형 모델은 포함할 수 없습니다. 양자화된 소형 모델(수 MB)이나 임베딩 모델이 엣지 AI에 적합합니다.
엣지 컴퓨팅에서 콜드 스타트는 가장 중요한 성능 지표입니다.
| 플랫폼 | 콜드 스타트 | 비고 |
|---|---|---|
| Wasm (Spin/Wasmtime) | 약 0.5ms | AOT 컴파일 기준 |
| Cloudflare Workers | 약 5ms | V8 Isolate 생성 |
| Fastly Compute | 마이크로초 단위 | 메모리 스냅샷 기술 |
| AWS Lambda | 100~500ms | 런타임에 따라 다름 |
| AWS Lambda (컨테이너) | 1~10초 | 이미지 크기에 따라 다름 |
| Docker 컨테이너 | 1~30초 | 이미지 크기, 초기화에 따라 다름 |
엣지에 배포하기 적합한 워크로드는 다음과 같습니다.
반면 다음 워크로드는 엣지보다 오리진 서버가 적합합니다.
"모든 것을 엣지에서"라는 접근은 바람직하지 않습니다. 엣지는 가볍고 빠른 처리에 최적화되어 있으며, 복잡한 비즈니스 로직이나 상태 관리는 여전히 오리진 서버의 영역입니다. 엣지와 오리진을 적절히 조합하는 하이브리드 아키텍처가 현실적인 최선입니다.
이번 장에서는 엣지 컴퓨팅에서의 WebAssembly 활용을 살펴보았습니다.
마지막 10장에서는 실전 프로젝트를 통해 시리즈 전체 내용을 종합합니다. Rust+Spin으로 서버리스 API를 구축하고, 브라우저 Wasm 모듈을 통합하며, 엣지에 배포하는 전체 과정을 실습합니다. 그리고 Wasm 도입 의사결정 가이드와 미래 전망으로 시리즈를 마무리합니다.
이 글이 도움이 되셨나요?
관련 주제 더 보기
Spin 프레임워크의 아키텍처, Fermyon Cloud와 Akamai 통합, SpinKube를 활용한 Kubernetes 배포, Docker와 Wasm의 비교를 통해 서버사이드 WebAssembly의 현재를 분석합니다.
Rust+Spin 서버리스 API 구축, 브라우저 Wasm 모듈 통합, 엣지 배포, 성능 벤치마킹, Wasm 도입 의사결정 가이드, 그리고 WebAssembly의 미래 전망을 다룹니다.
JavaScript와 Wasm의 상호 호출, Web API 연동, 이미지/비디오 처리, AI 추론, 게임 엔진 등 브라우저에서 WebAssembly로 고성능 애플리케이션을 구축하는 방법을 다룹니다.