S2, 내구성 있는 스트림 API
요약
S2는 실시간 스트리밍 데이터 처리에 특화된 서버리스(serverless) 데이터스토어입니다. 이 저장소에는 S2를 사용하기 위한 CLI, 자체 호스팅 가능한 오픈 소스 구현체인 s2-lite, 그리고 Rust SDK가 제공됩니다. 개발자들은 다양한 설치 방법과 함께 안정적인 스트리밍 API를 활용할 수 있습니다.
핵심 포인트
- 실시간 데이터 처리에 최적화된 서버리스 데이터스토어 S2 소개
- s2-cli, s2-lite(오픈 소스), Rust SDK 등 개발 도구 제공
- Homebrew, Cargo, Docker 등 다양한 환경에서 설치 및 사용 가능
s2.dev는 실시간 스트리밍 데이터용 서버리스(serverless) 데이터스토어입니다.
이 저장소에는 다음 내용이 포함되어 있습니다:
- s2-cli - S2를 위한 커맨드라인 인터페이스(Command-line interface)
- s2-lite - S2 API의 오픈 소스, 자체 호스팅 가능한 서버 구현체
- s2-sdk - S2를 위한 Rust SDK
개발(Development)
저장소 게시 쿨다운이 적용되도록 nightly Cargo 의존성 명령을 사용하세요:
cargo +nightly add <crate>
cargo +nightly update
cargo +nightly update -p <crate>
...
일반 빌드, 확인(check), 테스트(test), 실행(run), 문서화(document), 가져오기(fetch), 메타데이터 명령에는 --locked를 사용하세요. 시뮬레이터는 별도의 잠금 파일이 재생성될 때까지 일시적으로 면제됩니다. 풀 리퀘스트 의존성 확인은 Rust 빌드 작업이 시작되기 전에 제안된 모든 잠금 파일 변경 사항을 검증합니다.
Homebrew bottles에서 저장소 Cargo 도구를 설치하세요:
brew install cargo-deny cargo-nextest
설치(Installation)
Homebrew (macOS/Linux)
brew install s2-streamstore/s2/s2
Cargo
cargo install --locked s2-cli
릴리스 바이너리 (macOS/Linux)
curl -fsSL https://raw.githubusercontent.com/s2-streamstore/s2/main/install.sh | bash
또는 명령어 실행 전에 VERSION=x.y.z로 버전을 지정할 수 있습니다. 모든 릴리스를 확인하세요.
Docker
docker pull ghcr.io/s2-streamstore/s2
인증 (Authentication)
OS 자격 증명 저장소에 액세스 토큰을 저장하세요:
s2 auth access-token set
스크립트나 비밀 관리자에서 파이프하여 입력할 수도 있습니다:
op read 'op://S2/CLI/access-token' | s2 auth access-token set --stdin
CI 및 기타 임시 환경에서는 S2_ACCESS_TOKEN을 환경 변수로 설정하세요. 자격 증명 저장소가 없는 헤드리스 호스트의 경우, 대신 개인 평문 파일(Unix에서 모드 0600)로 옵트인하세요:
printf '%s' "$S2_ACCESS_TOKEN" |
s2 auth access-token set --stdin --insecure-storage
unset S2_ACCESS_TOKEN
config.toml에 있는 평문 access_token 값은 더 이상 사용되지 않습니다(deprecated). s2 auth access-token migrate로 마이그레이션하거나, 자격 증명 저장소가 없는 헤드리스 호스트에서 --insecure-storage를 사용하여 다시 저장하세요.
s2-lite
s2-lite는 CLI의 s2 lite 하위 명령어로 임베딩되어 있습니다. 이는 S2 API의 자체 호스팅 가능한 서버 구현체입니다.
이는 지속성(durability)을 위해 객체 스토리지에 전적으로 의존하는 SlateDB를 저장 엔진으로 사용합니다.
AWS S3 및 Tigris와 같은 객체 스토리지에서 s2 lite를 실행하기 쉽습니다. 다른 외부 종속성이 없는 단일 노드 바이너리입니다.
또한 --bucket을 지정하지 않기만 하면 되므로, 완전히 인메모리(in-memory)로 작동하게 하거나 (대신 로컬 디스크에 영구 저장하려면 --local-root를 사용하세요).
[!TIP]
lite가--bucket을 가리키도록 설정하면, 읽기자에게 확인되거나 반환되기 전에 데이터는 항상 객체 스토리지에 지속적으로 보존됩니다 — 이는 s2.dev와 같습니다.선택적인 인메모리 모드(
--bucket이나--local-root지정 안 함)는 통합 테스트를 위한 효과적인 S2 에뮬레이터 역할을 할 뿐입니다.
빠른 시작 (Quickstart)
외부 종속성 없이 인메모리(in-memory)로 실행하는 방법은 다음과 같습니다:
# Docker 사용
docker run -p 8080:80 ghcr.io/s2-streamstore/s2 lite
...
docker run -p 8080:80 \
-e AWS_PROFILE=${AWS_PROFILE} \
-v ~/.aws:/home/nonroot/.aws:ro \
...
docker run -p 8080:80 \
-e AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} \
-e AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} \
...
[!NOTE]
S2 CLI 또는 SDK를 다음과 같이 lite 인스턴스에 지정하세요:export S2_ACCOUNT_ENDPOINT="http://localhost:8080" export S2_BASIN_ENDPOINT="http://localhost:8080" export S2_ACCESS_TOKEN="ignored"
서버가 준비되었는지 확인해 봅시다:
while ! curl -sf ${S2_ACCOUNT_ENDPOINT}/health -o /dev/null; do echo Waiting...; sleep 2; done && echo Up!
CLI를 설치하거나 (위의 설치 참고) s2 --version이 0.26보다 오래되었다면 업그레이드하세요.
스트림 자동 생성을 활성화하여 basin을 생성해 봅시다:
s2 create-basin liteness --create-stream-on-append --create-stream-on-read
성능 테스트를 해보세요:
s2 bench liteness --target-mibps 10 --duration 5s --catchup-delay 0s

이제 스트리밍 세션을 시도해 봅시다. 새 터미널(하나 이상)에서 (위에서 언급된 환경 변수를 다시 내보냈는지 확인하세요):
s2 read s2://liteness/starwars 2> /dev/null
이제 원래 터미널로 돌아와 스트림에 쓰기 해 봅시다:
nc starwars.s2.dev 23 | s2 append s2://liteness/starwars

Kubernetes 배포
Helm을 사용하여 s2-lite를 Kubernetes에 배포하세요. 설치 지침 및 구성 옵션은 Helm 차트 문서를 참고하세요.
스토리지
Lite는 S3와 호환되는 버킷 또는 로컬 디렉터리에 영구 저장되거나, 둘 중 어느 곳도 지정되지 않은 경우 메모리 내에서 실행됩니다.
쓰기 전 로그(WAL)는 기본적으로 메인 스토어를 공유합니다. WAL 지연 시간을 플러시 및 압축 작업으로부터 격리하려면 별도의 버킷이나 디렉터리에 배치할 수 있습니다. --path는 두 저장소 모두에 적용됩니다.
| 설정 | 메인 스토어 | WAL 스토어 |
|---|---|---|
| S3 버킷 | --bucket | --wal-bucket / S2LITE_WAL_BUCKET |
| ... | ||
| Without static credentials, the standard AWS credential chain (profile, instance role 등)이 사용됩니다. | ||
WAL 버킷은 메인 스토어의 S3 설정을 상속받습니다. 각 S2LITE_WAL_AWS_* 변수는 해당 설정만 덮어쓰며, WAL 키 쌍이 메인 자격 증명(및 세션 토큰)을 대체하는 방식으로 작동합니다. | ||
| WAL 스토어를 사용하려면 영구적인 메인 스토어가 필요합니다. |
# S3에 LSM 저장소, 로컬 디스크에 WAL 저장소
s2 lite --bucket my-bucket --wal-local-root /data/wal
...
모니터링 (Monitoring)
/health는 준비 상태(readiness) 및 활성 상태(liveness) 검사 성공 시 200을 반환합니다.
/metrics는 Prometheus 텍스트 형식을 반환합니다.
내부 구조 (Internals)
SlateDB 설정 (SlateDB settings)
설정 참조를 사용하세요.
SL8_ 접두사가 붙은 환경 변수(예: SL8_FLUSH_INTERVAL)를 사용합니다:
# S3의 경우 50ms 기본값, 그 외는 5ms; 설정된 WAL 스토어를 따름
SL8_FLUSH_INTERVAL=10ms
설계 (Design)
개념(Concepts)을 참고하세요.
- HTTP 서비스는 axum을 사용하여 구현되었습니다.
- 각 스트림은
streamer라는 Tokio 태스크에 해당하며(lite/src/backend/streamer.rs), 현재의tail위치를 소유하고, 추가된 내용을 직렬화하며, 승인된 레코드를 팔로워들에게 브로드캐스트합니다. - 높은 지연 시간을 가진 객체 스토어에 대비하여 추가 작업(Appends)은 파이프라인 처리됩니다.
lite::backend::kv::Key에서 SlateDB의 데이터 모델링을 문서화하고 있습니다.
호환성 (Compatibility)
- CLI ✅ v0.26+
- TypeScript SDK ✅ v0.22+
- Go SDK ✅ v0.11+
- Rust SDK ✅ v0.22+
- Python SDK ✅ v0.1+
API 지원 범위 (API Coverage)
완벽한 사양서(specs)를 이용할 수 있습니다:
[!중요]
클라우드 서비스의 경우 베이신(basin)이 서브도메인으로 암묵적이지만,/streams/*요청에서는S2-Basin헤더를 사용하여 반드시 베이신을 지정해야 합니다. SDK가 이 작업을 자동으로 처리합니다.
| 엔드포인트 (Endpoint) | 지원 여부 (Support) |
|---|---|
/basins | 지원됨 (Supported) |
| ... |
AI 자동 생성 콘텐츠
본 콘텐츠는 HN AI Engineering의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기