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