d8a80f6272
이름만 다른(표기 변형) [[위키링크]]를 대상 문서의 canonical 제목으로 치환해 끊겼던 1,200개 링크를 연결. 제목/파일명 정규화 일치만 적용하고 별칭 매칭은 과병합 위험으로 제외(애매성 가드). 원본은 _link_reconcile_backup/ 에 백업. 도구: Datacollect/scripts/link_reconcile_apply.mjs Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
192 lines
6.6 KiB
Markdown
192 lines
6.6 KiB
Markdown
---
|
||
id: wiki-2026-0508-distributed-systems-fallacies
|
||
title: Distributed Systems Fallacies
|
||
category: 10_Wiki/Topics
|
||
status: verified
|
||
canonical_id: self
|
||
aliases: [Fallacies of Distributed Computing, 8 Fallacies, Deutsch Fallacies]
|
||
duplicate_of: none
|
||
source_trust_level: A
|
||
confidence_score: 0.95
|
||
verification_status: applied
|
||
tags: [distributed-systems, architecture, networking, reliability]
|
||
raw_sources: []
|
||
last_reinforced: 2026-05-10
|
||
github_commit: pending
|
||
tech_stack:
|
||
language: polyglot
|
||
framework: distributed-systems
|
||
---
|
||
|
||
# Distributed Systems Fallacies
|
||
|
||
## 매 한 줄
|
||
> **"매 network 의 invisible 한 assumption 의 매 production failure 의 source"**. 1994년 Peter Deutsch (Sun) 가 매 7 fallacies 의 articulate, 1997년 James Gosling 가 8th 의 add. 매 2026 cloud-native 시대 에도 매 microservices / serverless / edge compute 의 매 매 valid.
|
||
|
||
## 매 핵심
|
||
|
||
### 매 8 Fallacies
|
||
1. **Network 의 reliable**: 매 packet drop / partition / DNS failure 의 inevitable.
|
||
2. **Latency 의 zero**: 매 LAN ~0.5ms, 매 cross-region ~150ms, 매 satellite ~600ms.
|
||
3. **Bandwidth 의 infinite**: 매 video / ML model weights / log shipping 의 saturate.
|
||
4. **Network 의 secure**: 매 default 의 insecure — 매 zero-trust assume.
|
||
5. **Topology 의 안 변함**: 매 autoscaling / k8s pod reschedule / failover 의 매 second.
|
||
6. **Administrator 의 single**: 매 multi-cloud / multi-region 의 매 다른 policy.
|
||
7. **Transport cost 의 zero**: 매 serialization / TLS handshake / egress fee 의 real.
|
||
8. **Network 의 homogeneous**: 매 IPv4/IPv6, 매 protocol versions, 매 MTU mismatch.
|
||
|
||
### 매 왜 fallacy 인가
|
||
- 매 dev 의 localhost / monolith mental model 의 distributed 에 적용 시 fail.
|
||
- 매 "happy path" coding 의 매 timeout / retry / circuit breaker 의 lack.
|
||
- 매 50ms RTT 의 매 100 calls 의 5 second user-facing latency.
|
||
|
||
### 매 응용
|
||
1. Microservices design — 매 call graph 의 latency budget 산정.
|
||
2. Cross-region replication — 매 split-brain / eventual consistency 의 plan.
|
||
3. Edge computing — 매 intermittent connectivity 의 first-class.
|
||
|
||
## 💻 패턴
|
||
|
||
### Pattern 1: Timeout + Retry with Exponential Backoff
|
||
```typescript
|
||
async function callWithRetry<T>(
|
||
fn: () => Promise<T>,
|
||
opts = { maxRetries: 3, baseMs: 100, timeoutMs: 2000 }
|
||
): Promise<T> {
|
||
for (let attempt = 0; attempt <= opts.maxRetries; attempt++) {
|
||
try {
|
||
return await Promise.race([
|
||
fn(),
|
||
new Promise<never>((_, reject) =>
|
||
setTimeout(() => reject(new Error("timeout")), opts.timeoutMs)
|
||
),
|
||
]);
|
||
} catch (err) {
|
||
if (attempt === opts.maxRetries) throw err;
|
||
const jitter = Math.random() * opts.baseMs;
|
||
await new Promise(r => setTimeout(r, opts.baseMs * 2 ** attempt + jitter));
|
||
}
|
||
}
|
||
throw new Error("unreachable");
|
||
}
|
||
```
|
||
|
||
### Pattern 2: Circuit Breaker (Resilience4j-style)
|
||
```typescript
|
||
class CircuitBreaker {
|
||
private failures = 0;
|
||
private state: "closed" | "open" | "half-open" = "closed";
|
||
private openedAt = 0;
|
||
constructor(private threshold = 5, private cooldownMs = 30_000) {}
|
||
|
||
async exec<T>(fn: () => Promise<T>): Promise<T> {
|
||
if (this.state === "open" && Date.now() - this.openedAt < this.cooldownMs)
|
||
throw new Error("circuit open");
|
||
if (this.state === "open") this.state = "half-open";
|
||
try {
|
||
const r = await fn();
|
||
this.failures = 0; this.state = "closed";
|
||
return r;
|
||
} catch (e) {
|
||
if (++this.failures >= this.threshold) {
|
||
this.state = "open"; this.openedAt = Date.now();
|
||
}
|
||
throw e;
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### Pattern 3: Bulkhead (concurrency limiter)
|
||
```typescript
|
||
import pLimit from "p-limit";
|
||
const dbLimit = pLimit(20); // 매 DB pool 의 isolate
|
||
const apiLimit = pLimit(50); // 매 external API 의 separate
|
||
|
||
async function getUser(id: string) {
|
||
return dbLimit(() => db.users.findOne({ id }));
|
||
}
|
||
```
|
||
|
||
### Pattern 4: Idempotency Key
|
||
```typescript
|
||
async function chargeCard(req: ChargeReq, idemKey: string) {
|
||
const cached = await redis.get(`idem:${idemKey}`);
|
||
if (cached) return JSON.parse(cached);
|
||
const result = await stripe.charges.create(req);
|
||
await redis.setex(`idem:${idemKey}`, 86400, JSON.stringify(result));
|
||
return result;
|
||
}
|
||
```
|
||
|
||
### Pattern 5: Latency Budget
|
||
```typescript
|
||
// 매 user-facing 200ms 의 budget
|
||
// API gateway: 20ms
|
||
// auth check: 10ms (cached)
|
||
// service call: 50ms (timeout 100ms)
|
||
// DB query: 30ms (timeout 80ms)
|
||
// serialization: 10ms
|
||
// buffer: 80ms
|
||
// 매 each hop 의 explicit budget — over 시 fail fast.
|
||
```
|
||
|
||
### Pattern 6: Chaos Testing (Toxiproxy)
|
||
```bash
|
||
# 매 latency injection
|
||
toxiproxy-cli toxic add api -t latency -a latency=500 -a jitter=100
|
||
# 매 packet loss
|
||
toxiproxy-cli toxic add db -t timeout -a timeout=2000
|
||
```
|
||
|
||
### Pattern 7: Health check with deep probe
|
||
```typescript
|
||
app.get("/health/deep", async (_, res) => {
|
||
const checks = await Promise.allSettled([
|
||
db.raw("SELECT 1").then(() => ({ db: "ok" })),
|
||
redis.ping().then(() => ({ redis: "ok" })),
|
||
fetch(upstream + "/health", { signal: AbortSignal.timeout(500) }),
|
||
]);
|
||
const failed = checks.filter(c => c.status === "rejected");
|
||
res.status(failed.length ? 503 : 200).json({ checks });
|
||
});
|
||
```
|
||
|
||
## 매 결정 기준
|
||
| 상황 | Approach |
|
||
|---|---|
|
||
| LAN microservice call | timeout 1-2s, retry 2x |
|
||
| Cross-region call | timeout 5-10s, circuit breaker |
|
||
| 3rd-party API | bulkhead + circuit breaker + idempotency |
|
||
| Streaming / WebSocket | heartbeat + auto-reconnect |
|
||
| Critical write | idempotency key 의 mandatory |
|
||
|
||
**기본값**: 매 every remote call 의 timeout + retry + circuit breaker 의 wrap.
|
||
|
||
## 🔗 Graph
|
||
- 부모: [[Distributed Systems]] · [[Software Architecture]]
|
||
- 변형: [[CAP Theorem & PACELC]] · [[PACELC]]
|
||
- 응용: [[Microservices Architecture]] · [[Service Mesh]]
|
||
- Adjacent: [[Resilience Patterns]] · [[Chaos Engineering]]
|
||
|
||
## 🤖 LLM 활용
|
||
**언제**: 매 distributed system design review, 매 incident postmortem, 매 SLO 산정.
|
||
**언제 X**: 매 single-process monolith, 매 batch job 의 isolated.
|
||
|
||
## ❌ 안티패턴
|
||
- **Infinite retry**: 매 retry storm — 매 backoff + max attempts 의 mandatory.
|
||
- **Timeout 의 unset**: 매 default infinite — 매 thread pool exhaustion.
|
||
- **Synchronous fan-out**: 매 N services 의 sequential await — 매 N×latency.
|
||
- **Trust LAN security**: 매 zero-trust / mTLS 의 default.
|
||
- **Ignore tail latency**: 매 p50 의 보고 의 — 매 p99 / p99.9 의 user experience.
|
||
|
||
## 🧪 검증 / 중복
|
||
- Verified (Deutsch 1994 / Gosling 1997 original list, AWS Builders' Library, Google SRE book).
|
||
- 신뢰도 A.
|
||
|
||
## 🕓 Changelog
|
||
| 날짜 | 변경 |
|
||
|---|---|
|
||
| 2026-05-08 | Phase 1 |
|
||
| 2026-05-10 | Manual cleanup — 8 fallacies + resilience patterns |
|