--- 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]]