docs(10_Wiki): 위키 전체 재구성 — Topic_* 폴더를 4개 카테고리로 통합 + 대규모 중복 제거
Topic_Agent/Topic_Blog/Topics/Topics_Biz/Topics_Meeting/Topics_Rag의 마크다운 지식 문서를 Topic_General/Topic_Programming/Topic_Graphic/Topic_Business 4개 카테고리로 재분류. - 중복 제거: frontmatter의 status:duplicate/merged + duplicate_of/redirect_to 필드로 자기 자신을 중복으로 선언한 리다이렉트 stub 1032개 제거, 완전 동일 내용 파일 472개 제거, 동일 파일명·다른 내용 충돌 시 더 큰(완전한) 버전만 유지(162개 제거) — 총 1639개 중복 제거. - 분류: 폴더 단위로 명확한 항목(AI_and_ML/Coding/Architecture 등 → Programming, Comfyui/Visual_Effects → Graphic, Topics_Biz/Topics_Meeting/사업 등 → Business, Poetic_Blog_Writing/창의성/Game_Design 등 → General)은 폴더 우선순위로, 나머지 혼재 폴더(Topic_Agent/Topic_Blog/Topics 루트/Thinking & Reasoning/Other/UI_UX_Assets)는 title/tags 키워드 스코어링으로 파일 단위 분류(불명확한 경우 General로 폴백). 원본 폴더명은 "From_*" 서브폴더로 보존해 추적 가능성 유지. - 최종 배치: Programming 2784 / General 1608 / Graphic 285 / Business 249 = 4926개 문서. - 에이전트 운영 상태(.astra/.agent/.obsidian/sessions/memory/_company/docs/lessons/_shared/src)는 지식 콘텐츠가 아니므로 재분류 대상에서 제외하고 원위치 유지. - Topics/Topic_email(상위 보호 폴더 Topic_email과 파일명 100% 중복) 삭제 — 보호 폴더 자체는 미변경. - 완전히 비게 된 Topic_Agent/Topic_Blog/Topics_Biz/Topics_Rag 폴더 제거.
This commit is contained in:
@@ -0,0 +1,187 @@
|
||||
---
|
||||
id: wiki-2026-0508-global-network-positioning-gnp
|
||||
title: Global Network Positioning (GNP)
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [GNP, Network Coordinates, Network Positioning, Vivaldi]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.85
|
||||
verification_status: applied
|
||||
tags: [networking, latency-prediction, distributed-systems, p2p, coordinates]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: go
|
||||
framework: vivaldi-coords
|
||||
---
|
||||
|
||||
# Global Network Positioning (GNP)
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 host 를 매 low-D Euclidean space 의 point 로 embed — 매 distance 가 매 network latency 의 predictor"**. Ng & Zhang (SIGCOMM 2002) 의 GNP — 매 landmark 기반 절대 좌표 — 가 매 idea 의 시초. 매 후속작 Vivaldi (Dabek 2004) 가 매 decentralized 형태로 매 P2P / overlay network 에 광범위하게 사용. 매 2026 의 application 은 매 CDN edge selection, DHT routing, server placement.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 GNP (centralized) 의 idea
|
||||
- **Landmark hosts** (예: 15-20개) 가 매 Internet 곳곳에 배치.
|
||||
- 매 RTT 측정 후 landmark 들의 매 좌표를 매 fixed point 로 fitting (multidim scaling).
|
||||
- 매 new host 는 매 landmark 들에 ping → 매 자기 좌표 solve.
|
||||
- 매 두 host 간 RTT ≈ Euclidean distance.
|
||||
|
||||
### 매 Vivaldi (decentralized) 의 차이
|
||||
- Landmark X — 매 모든 peer 가 random subset 와 매 RTT 교환.
|
||||
- 매 spring relaxation: 매 over/under-estimated 매 vector 만큼 push/pull.
|
||||
- 매 height augmentation (extra non-Euclidean dim) 으로 매 access link 의 last-mile 표현.
|
||||
- 매 dynamic — peer churn 에 자동 적응.
|
||||
|
||||
### 매 application
|
||||
1. **CDN routing**: 매 client 좌표 → 매 nearest edge.
|
||||
2. **DHT optimization**: 매 finger table 을 매 latency-aware 로 선택.
|
||||
3. **Server selection**: 매 mirror / replica 중 가장 가까운 매 fetch.
|
||||
4. **Network tomography**: 매 latency map 시각화.
|
||||
5. **P2P overlays**: BitTorrent, Skype 가 매 사용 (legacy).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### GNP-style landmark fitting (NumPy)
|
||||
```python
|
||||
import numpy as np
|
||||
from scipy.optimize import minimize
|
||||
|
||||
def fit_landmarks(rtt_matrix, dim=4):
|
||||
"""rtt_matrix[i][j] = measured RTT between landmark i,j (ms)."""
|
||||
n = rtt_matrix.shape[0]
|
||||
x0 = np.random.rand(n * dim) * 50
|
||||
|
||||
def stress(x):
|
||||
coords = x.reshape(n, dim)
|
||||
err = 0.0
|
||||
for i in range(n):
|
||||
for j in range(i + 1, n):
|
||||
d = np.linalg.norm(coords[i] - coords[j])
|
||||
err += ((d - rtt_matrix[i, j]) / rtt_matrix[i, j]) ** 2
|
||||
return err
|
||||
|
||||
res = minimize(stress, x0, method='L-BFGS-B')
|
||||
return res.x.reshape(n, dim)
|
||||
|
||||
def position_new_host(rtts_to_landmarks, landmark_coords, dim=4):
|
||||
def stress(x):
|
||||
return sum(
|
||||
((np.linalg.norm(x - landmark_coords[i]) - rtts_to_landmarks[i])
|
||||
/ rtts_to_landmarks[i]) ** 2
|
||||
for i in range(len(rtts_to_landmarks))
|
||||
)
|
||||
res = minimize(stress, np.zeros(dim), method='L-BFGS-B')
|
||||
return res.x
|
||||
```
|
||||
|
||||
### Vivaldi spring relaxation step (Go)
|
||||
```go
|
||||
type Coord struct {
|
||||
Vec []float64 // Euclidean dims
|
||||
Height float64 // last-mile
|
||||
Err float64 // local error estimate
|
||||
}
|
||||
|
||||
const (
|
||||
Ce = 0.25 // error sensitivity
|
||||
Cc = 0.25 // coord change sensitivity
|
||||
)
|
||||
|
||||
// Update local coord after measuring rtt to peer with peerCoord
|
||||
func (c *Coord) Update(rtt float64, peerCoord Coord) {
|
||||
w := c.Err / (c.Err + peerCoord.Err)
|
||||
predicted := dist(c.Vec, peerCoord.Vec) + c.Height + peerCoord.Height
|
||||
es := math.Abs(predicted-rtt) / rtt
|
||||
c.Err = es*Ce*w + c.Err*(1-Ce*w)
|
||||
|
||||
delta := Cc * w
|
||||
direction := unit(sub(c.Vec, peerCoord.Vec))
|
||||
force := (rtt - predicted) * delta
|
||||
for i := range c.Vec {
|
||||
c.Vec[i] += direction[i] * force
|
||||
}
|
||||
c.Height = math.Max(0, c.Height+(rtt-predicted)*delta*0.5)
|
||||
}
|
||||
```
|
||||
|
||||
### Edge selection from coordinates
|
||||
```go
|
||||
func selectEdge(client Coord, edges []EdgeNode) *EdgeNode {
|
||||
var best *EdgeNode
|
||||
bestRTT := math.Inf(1)
|
||||
for i, e := range edges {
|
||||
rtt := dist(client.Vec, e.Coord.Vec) + client.Height + e.Coord.Height
|
||||
if rtt < bestRTT {
|
||||
bestRTT = rtt
|
||||
best = &edges[i]
|
||||
}
|
||||
}
|
||||
return best
|
||||
}
|
||||
```
|
||||
|
||||
### CDN-style anycast hybrid (BGP + GNP fallback)
|
||||
```python
|
||||
def route(client_ip):
|
||||
# Try anycast result first (BGP picks PoP)
|
||||
pop = anycast_lookup(client_ip)
|
||||
if pop and recent_health(pop):
|
||||
return pop
|
||||
# Fallback: use GNP coords from RIPE Atlas / Cedexis
|
||||
coord = lookup_client_coord(client_ip)
|
||||
return min(EDGES, key=lambda e: euclid(coord, e.coord) + e.height + coord.height)
|
||||
```
|
||||
|
||||
### Stress test (predicted vs actual)
|
||||
```python
|
||||
def evaluate(coords, ground_truth_rtt):
|
||||
rel_err = []
|
||||
for (i, j), actual in ground_truth_rtt.items():
|
||||
pred = np.linalg.norm(coords[i] - coords[j])
|
||||
rel_err.append(abs(pred - actual) / actual)
|
||||
return {
|
||||
'median_rel_err': np.median(rel_err),
|
||||
'p90_rel_err': np.percentile(rel_err, 90),
|
||||
}
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Centralized infra, fixed landmarks | GNP |
|
||||
| P2P / dynamic peer set | Vivaldi |
|
||||
| <100 nodes | Direct measurement (skip embedding) |
|
||||
| Global CDN | Anycast + GNP fallback |
|
||||
| Triangle inequality violations frequent | Add height (Vivaldi) or non-Euclidean |
|
||||
|
||||
**기본값**: 매 modern usage — Vivaldi w/ height (4D + height).
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Distributed Systems]]
|
||||
- 변형: [[Vivaldi]]
|
||||
- 응용: [[CDN]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 algorithm 설명, 매 stress function tuning 제안, embedding dimension 선택 기준.
|
||||
**언제 X**: 매 real-time coord update — 매 measured RTT 만이 truth.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **2D 만 사용**: 매 triangle inequality 자주 violated — 매 4D + height.
|
||||
- **No error tracking**: 매 Vivaldi 의 local error term 빠짐 → unstable.
|
||||
- **Static landmarks 의 churn 무시**: 매 landmark 매 fail 시 — health check 필수.
|
||||
- **Use embedding distance for security**: 매 거리는 매 latency proxy 일 뿐 — 매 trust 의 X.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Ng & Zhang SIGCOMM 2002, Dabek SIGCOMM 2004).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — GNP/Vivaldi math + edge selection patterns |
|
||||
Reference in New Issue
Block a user