Files
2nd/10_Wiki/Topics/Coding/Arch_Cell_Based.md
T
2026-05-09 22:47:42 +09:00

331 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: arch-cell-based
title: Cell-based Architecture — blast radius 격리
category: Coding
status: draft
source_trust_level: B
verification_status: conceptual
created_at: 2026-05-09
updated_at: 2026-05-09
tags: [architecture, resilience, vibe-coding]
tech_stack: { language: "any", applicable_to: ["Architecture"] }
applied_in: []
aliases: [cell-based, cell architecture, bulkhead, blast radius, shuffle sharding, AWS cells]
---
# Cell-based Architecture
> 큰 system 가 1 cell. cell 가 다 죽으면 모두 down. **여러 cell + 사용자 가 1 cell 만 — blast radius 작아**. AWS, Slack, GitHub 의 모던 architecture.
## 📖 핵심 개념
- Cell = 작은 self-contained system (web + DB + cache).
- 사용자 별 1 cell 배정.
- Cell 간 isolation.
- Cell 가 죽으면 그 cell 의 사용자만 영향.
## 💻 코드 패턴
### 일반 system
```
모든 user → LB → app fleet → 1 DB
→ DB 죽으면 100% down.
App fleet bug 가 100% 영향.
```
### Cell-based
```
User → Router →
Cell A (10% user) → app A + DB A
Cell B (10% user) → app B + DB B
...
Cell J (10% user) → app J + DB J
→ Cell A 죽음 = 10% 만 down.
```
### Cell routing
```ts
function getCell(userId: string): string {
const hash = murmur32(userId);
const cellIndex = hash % NUM_CELLS;
return `cell-${cellIndex}`;
}
app.use((req, res, next) => {
const cell = getCell(req.user.id);
res.set('X-Cell', cell);
// Forward to cell
req.cell = cell;
next();
});
```
### Sticky routing
```
사용자 가 항상 같은 cell.
- Hash(user_id) % N
- Cookie 저장
- Geo (region)
→ Cache hit, locality.
```
### Cell size
```
큰 cell: 운영 적음, 큰 blast radius
작은 cell: 운영 많음, 작은 blast
Sweet spot: 1-10% user / cell.
- 100k user = 10-100 cell.
- 큰 system = N+ cells.
```
### Shuffle sharding (AWS)
```
N cell 중 매 user 가 K (e.g. 2-3) cell.
- User1 → Cell A, B
- User2 → Cell A, C
- User3 → Cell B, D
→ Cell A 죽음 = User1 가 B 로 fallback. 100% available.
```
```ts
function getShards(userId: string): string[] {
const seed = hash(userId);
return [`cell-${seed % N}`, `cell-${(seed + 7) % N}`];
}
```
### Bulkhead 비유
```
배 의 격실 (수밀 격벽).
1 곳 침수 = 그 격실 만.
Software:
- 1 thread pool 다 = 거기서만 hang
- 1 DB conn pool 다 = 그 service 만
```
### Cell 의 데이터
```
Option A: Cell 별 DB
Cell A — DB A
Cell B — DB B
Option B: Shared DB + tenant 분리
All cells → 1 DB (tenant ID)
→ A 가 isolation 강함. B 가 simple.
```
### Cross-cell read
```
"User A 가 User B 의 data 본다"
- A 와 B 가 다른 cell?
→ Cell B 에 query (cross-cell)
→ Network + 2x complexity
→ 큰 system 만. 같은 cell 친화 / global table.
```
### Global metadata
```
일부 data 가 cell 무관.
- Pricing
- Catalog
- Feature flag
→ Global DB + cell 가 read replica.
```
### Migration (cell 변경)
```
사용자 가 cell 변경 가능 — rare.
1. Source cell 에 read-only mark
2. Data copy → target cell
3. Verify
4. Routing 변경
5. Source cell 에서 삭제
→ Rebalance 시 발생.
```
### Cell autonomy
```
한 cell 가 down 해도:
- 다른 cell 가 영향 X
- 다른 cell 가 down 한 거 모름 (의존 X)
→ Shared dependencies = single point of failure.
Auth, payment 가 외부 service?
```
### Auth shared
```
Auth 가 cell 별 = scaling 어려움 (token 어느 cell?).
Auth 가 외부 (Auth0, Keycloak) → cell 가 verify.
→ Stateless cell.
```
### Deploy
```
N cell × deploy frequency.
1 cell deploy → verify → 다음 cell.
Canary:
1 cell 가 v2 → 10% user 가 v2.
→ Blast radius 작음 + 검증.
```
### 모니터링
```
Per-cell metric:
- cell-A: latency, error rate, ...
- cell-B: ...
Aggregated dashboard.
1 cell anomaly = visible.
```
### Failure injection
```
Chaos:
- Cell A 의 service kill
- Cell B 의 DB connection drop
→ 다른 cell 영향 X 검증.
```
### AWS 의 cell-based
```
S3, DynamoDB, IAM, CloudFront 가 cell.
1 cell ~10% user.
1 cell incident = 10% 영향 + 다른 cell 가 cover (failover).
```
### GitHub 의 cell-based (since 2022)
```
1 cell = 1 region of repos.
새 repo = 1 cell 배정.
→ Cell A incident = 그 cell 의 repo 만.
```
### Slack 의 cell-based
```
1 workspace = 1 cell.
Cell-based scaling + isolation.
```
### When 도입
```
- 큰 system (>1k user, > $$$ revenue)
- High availability 중요
- 1 incident = 큰 손해
- Independent scale 가능
→ 작은 system = overkill.
```
### Multi-region (다른 layer)
```
Region: 다른 지리.
Cell: region 안 / 사이.
→ N region × M cell/region.
Region disaster (data center 화재) ≠ cell incident (bug).
```
### Cost
```
- 운영 복잡 ↑
- Tooling (cell-aware deploy, monitoring)
- Cross-cell scenario 처리
→ Investment.
큰 system 가치 큰.
```
### Tenant model 비교
```
Single-tenant 1 DB / customer:
- 작은 cell (1 customer)
- 가장 isolated
- 비싼 운영
Multi-tenant 1 DB:
- 모두 1 곳
- 가장 cheap
- 가장 큰 blast
Cell:
- 중간 (10-1000 customer / cell)
- Sweet spot
```
→ [[Backend_Multi_Tenant_Architecture]].
### Implementation 어려움
```
1. Cell routing (가장 큰 결정)
2. Cell-aware tooling (deploy, monitoring)
3. Migration story (cell 변경)
4. Shared service (auth, billing)
5. Cross-cell data 의 flow
→ 시작 = 1 cell. 성장 = 분리.
```
### Strangler 식 도입
```
1. Modular monolith
2. 1 module 가 cell 후보 (e.g. tenant 별)
3. 분리 테스트
4. 점진 cell 화
```
### 작은 개념 — Bulkhead
```ts
// 작은 system 도 thread pool 별.
const dbPool = new Pool({ max: 20 });
const externalApiPool = new Pool({ max: 5 });
// External API 가 hang → external pool 다 → DB pool 영향 X.
```
→ Cell 의 작은 version.
## 🤔 의사결정 기준
| 상황 | 추천 |
|---|---|
| 작은 system | Modular monolith |
| 큰 + HA | Cell-based |
| 1k+ tenant | Cell |
| 매우 critical (banking) | Shuffle sharding |
| 1 region | Cell within region |
| Multi-region | Region + cells |
| Tenant 별 isolation 강 | Single-tenant DB |
## ❌ 안티패턴
- **1 monolith + 1 DB**: 큰 blast radius.
- **Cell 도입 + shared DB**: isolation 무효.
- **Cross-cell scenario 흔함**: cost 폭발.
- **Cell migration 없음**: rebalance 어려움.
- **Per-cell deploy 없음**: 1 deploy 가 모두 영향.
- **Per-cell monitoring 없음**: incident locate 어려움.
- **Shared auth 가 cell A 의 일부**: SPOF.
## 🤖 LLM 활용 힌트
- Cell-based = blast radius 격리 의 답.
- Shuffle sharding = 작은 cell + redundancy.
- Sticky routing (hash, cookie) 가 cell 의 중심.
- 작은 system = bulkhead 만 (thread pool, conn pool).
## 🔗 관련 문서
- [[Arch_Modular_Monolith]]
- [[Backend_Multi_Tenant_Architecture]]
- [[Backend_Geo_Replication]]