celld
합의 프로토콜 없이 버킷만으로 조율하는 자체 호스팅 분산 Durable Objects
curl -fsSL https://celld.dev/install.sh | shCloudflare Workers 와 Durable Objects 를 내 장비에서 돌리는 오픈소스 데몬입니다. 객체 하나가 각자의 SQLite 데이터베이스이고, 내가 소유한 S3 호환 또는 GCS 버킷에 복제됩니다. 노드끼리는 그 버킷 하나로만 조율하며 컨트롤 플레인도 합의 서비스도 두지 않습니다. 오브젝트 스토리지의 compare-and-swap 이 한 시점에 한 노드만 소유하도록 보장합니다.
판단
이럴 때 씁니다
- Durable Objects 로 짠 애플리케이션을 Cloudflare 밖 내 인프라에서 돌려야 할 때
- 샤딩을 나중에 얹는 대신 객체 단위로 처음부터 갈라 두고 싶을 때
- 멤버십 프로토콜이나 합의 서비스를 운영 대상에서 빼고 싶을 때
- 대부분의 객체가 놀고 있고 활성 객체만 비용을 내는 형태가 맞을 때
이럴 땐 쓰지 마세요
- 노드 간 통신을 신뢰할 수 있는 사설망이나 암호화 오버레이에 올릴 수 없을 때
- 버킷 자격 증명을 함대 관리자 권한과 같은 급으로 다룰 준비가 안 됐을 때
- Wrangler 설정과 Worker 번들 구조를 쓰지 않는 애플리케이션일 때
- 패치를 이메일로 보내는 기여 방식을 감당할 수 없고 포크 유지가 필요한 경우
차별점
- 컨트롤 플레인도 합의 프로토콜도 없이 오브젝트 스토리지 compare-and-swap 만으로 소유권을 정합니다. 멤버십 프로토콜과 장애 감지기가 운영 대상에서 빠집니다.
- 객체마다 자기 SQLite 를 갖기 때문에 공유 데이터베이스 한 개에서 생기는 경합과 장애 전파가 설계 단계에서 사라집니다.
- 버킷이 진실의 원천이고 노드는 교체 가능한 부품입니다. 셀이 이동하거나 비활성 셀이 깨어나면 새 소유자가 데이터베이스를 복원해 이어 갑니다.
- 아무 노드도 들고 있지 않은 셀은 비활성이고 비용이 거의 들지 않습니다.
워크플로
- 01설치 스크립트로 celld 바이너리를 내립니다. gh attestation verify 로 출처를 검증할 수 있습니다.
- 02Worker 프로젝트를 배포하려면 esbuild 를 PATH 에 둡니다. 정적 자산만 있는 프로젝트는 필요 없습니다.
- 03celld deploy 로 S3 호환 또는 GCS 버킷에 배포합니다. 함대 전체가 이 버킷 하나를 공유합니다.
- 04각 노드를 공개 리스너와 내부 리스너를 나눠 띄웁니다. 내부 포트는 절대 공개하지 않습니다.
- 05celld diagnose 로 노드 리스를 훑고 살아 있는 피어마다 서명된 직접 프로브를 돌려 상태를 확인합니다.
주요 명령
| 명령 | 설명 |
|---|---|
curl -fsSL https://celld.dev/install.sh | sh | celld 바이너리를 설치합니다. 릴리스는 ~/.local/lib/celld/releases 아래에 쌓입니다. |
celld deploy . --bucket s3://my-cells-bucket | Wrangler 설정 하위 집합을 읽어 배포 객체를 버킷에 직접 씁니다. |
celld --bucket s3://my-cells-bucket --listen 0.0.0.0:8080 --internal-listen 10.0.0.12:8081 --advertise node-a.internal:8081 | 노드를 띄웁니다. 데이터 플레인과 컨트롤 플레인 리스너를 반드시 나눕니다. |
celld diagnose --bucket s3://my-cells-bucket | 만료된 레코드, 위험한 advertise 주소, 닿지 않는 피어, 호환되지 않는 프로토콜을 구분해 보고합니다. |
함정
설치 전에 확인하세요
- 내부 포트를 공개하면 안 됩니다. advertise 주소는 사설망이나 WireGuard, Tailscale 같은 암호화 오버레이 위에 두어야 하고, 공인 IP 를 그대로 쓰면 --unsafe-public-advertise 없이는 거부됩니다.
- 버킷과 그 자격 증명에 대한 접근은 함대 관리자 권한과 같습니다. 피어 요청은 버킷에 만들어지는 함대 비밀로 HMAC 인증됩니다.
- celld 는 호스트명이나 변환된 포트를 검증할 수 없습니다. advertise 주소가 내부 리스너로 라우팅되도록 직접 보장해야 합니다.
- Worker 코드를 배포하려면 esbuild 가 PATH 에 있어야 합니다.
- 풀 리퀘스트를 받지 않습니다. git format-patch 를 메일로 보내야 하고 기여 시 Deno Land 로의 권리 양도에 동의하게 됩니다.
- 공개 함대를 돌리기 전에 docs/limitations.md 와 docs/security.md 를 먼저 읽으라고 저장소가 지정합니다.
검토 메모
공식 문서·릴리스·공개 자료를 바탕으로 정리한 편집 메모입니다.
저는 이 프로젝트에서 가장 눈여겨볼 대목이 성능 수치가 아니라 빼기로 한 것들이라고 봅니다. 분산 시스템을 만들 때 보통 먼저 붙이는 멤버십 프로토콜, 장애 감지기, 합의 서비스가 여기에는 없습니다. 대신 오브젝트 스토리지의 compare-and-swap 하나로 소유권을 정합니다. 운영해야 할 부품이 줄어든다는 뜻이라 저는 이 교환을 좋게 봅니다.
다만 그 대가가 어디로 갔는지는 분명히 하고 싶습니다. 저장소가 내부 포트를 공개하지 말라고 하고 공인 IP 를 쓰면 별도 플래그 없이는 거부하는 이유가 있습니다. 피어 인증이 버킷에 놓인 함대 비밀에 기대고 있어서, 버킷 자격 증명을 쥔 사람은 사실상 함대 관리자입니다. 사설망이나 WireGuard 를 이미 운영하고 있지 않다면 그 준비부터가 도입 비용입니다.
권하는 순서는 이렇습니다. 공개 함대를 띄우기 전에 저장소가 지정한 limitations 와 security 문서를 먼저 읽고, celld diagnose 가 어떤 항목을 구분해서 보고하는지부터 확인하시기 바랍니다. 만료된 리스와 위험한 advertise 주소를 따로 잡아 준다는 것은 그 두 가지가 실제로 자주 어긋난다는 뜻으로 읽힙니다.
용량 산정 기준이 이번 릴리스에서 바뀐 점도 짚어 둘 만합니다. 상주 셀 하나가 약 3.4MB 에서 약 471KB 로 내려가면서 한 노드에 2,500 셀까지 선형으로 측정됐고, 저장소는 이제 메모리가 상주 셀 수를 제한하지 않으며 승인과 RSS 축출이 한계를 정한다고 적었습니다. v0.1.0 기준으로 노드 수를 잡아 두었다면 그 계산은 버리고 다시 하는 편이 맞습니다. 다만 이 수치는 저장소가 자체 측정한 값이므로 내 워크로드에서 한 번은 직접 확인하시기 바랍니다.
비교
Cloudflare 의 관리형 Durable Objects 가 운영을 통째로 맡기는 대신 플랫폼에 묶이는 선택이라면, celld 는 같은 프로그래밍 모델을 유지한 채 버킷과 장비만 내 것으로 가져오는 선택입니다. 대신 사설망 구성과 버킷 자격 증명 관리가 통째로 내 몫이 됩니다.
최근 변경
v0.4.0에서는 Workers KV·Queues·Workflows·R2 바인딩을 배포할 수 있게 하고, Docker나 클라우드 버킷 없이 로컬 개발이 가능한 celld dev 명령을 추가했습니다. 노드가 재시작 없이 새 배포로 전환하도록 하고 Durable Object 출력 게이트 순서 규칙을 하나로 통일했으며, peer tunnel 프로토콜이 바뀌어 v0.3.0 fleet는 완전히 정지한 뒤에만 업그레이드할 수 있습니다.