2.3.5 라우팅 루프(Loop) 방지 기법 및 포워딩 최적화

2.3.5 라우팅 루프(Loop) 방지 기법 및 포워딩 최적화

버전 알림: 본 문서는 Zenoh 1.0.0 (및 1.0.0-rc 분기) 코어 아키텍처 규격을 기준으로 작성되었다.

인터넷 체급(Internet-scale)의 방대한 분산 라우팅 노드들이 메쉬(Mesh)와 혼합 토폴로지(Mixed Topology)를 자율적으로 직조해 나갈 때, 네트워크 아키텍트가 가장 두려워해야 할 죽음의 그림자는 바로 ‘라우팅 루프(Routing Loop)’ 현상이다. 특정 라우터 A가 다음 라우터 B로 패킷을 밀어냈는데, B가 다시 A에게 그 패킷을 반사해 내며 두 노드 사이를 미친 듯한 속도로 회전하는 무한 궤도의 타임아웃 트래픽 폭풍(Infinite Traffic Storm).

중앙의 전지전능한 통제 브로커(Central Broker)조차 존재하지 않는 Zenoh(제노)의 분산 브로커리스 망 환경에서 이 루프 현상이 발화하면, 엣지의 얇은 대역폭은 순식간에 질식해 버리고 전체 시스템 메모리는 OOM(Out of Memory)으로 치명적인 연쇄 크래시(Cascading Crash)를 맞이하게 된다. 본 절에서는 IP 패킷의 지루한 TTL(Time-To-Live) 소모전을 초월하여, 분산 네임스페이스 트레이서(Name-centric Router)의 포워딩 효율성을 극한으로 견인하는 Zenoh 런북(Runbook)의 선제적 라우팅 루프 방어막과 포워딩 패스 파헤치기 최적화 논리를 집중 해부한다.

1. 노드 식별자 스탬핑(Node ID Stamping)을 통한 추적 알고리즘 방어

전통적인 이더넷 계층의 커널이 패킷 무결성을 통제할 때 의지하던 것은, 단순하게 홉(Hop)을 거칠 때마다 숫자를 하나씩 까먹는 바보 같은 TTL 감가상각(TTL Decrement) 기능이었다. 이 원시적인 방식은 패킷이 수백 수천 번을 맹목적으로 무의미하게 회전(Looping)하고 나서야 수명이 다했다며 멍청하게 소멸(Drop Packet)시키는 가장 후진적인 트래픽 오염 방조 행위이다.

Zenoh 데몬(zenohd) 엔진의 코어 라우팅 포워더(Forwarder)는 애초에 이런 치명적인 낭비의 파이프라인 개통 자체를 허용하지 않는 선제 타격(Pre-emptive Prevention) 노선을 밟는다. 퍼블리셔(Publisher)가 데이터를 생산해 내어 첫 라우터 혹은 피어 데몬에게 넘기는 그 찰나의 순간, 와이어 헤더(Wire Header Payload) 위에는 최초 생산 단말의 고유한 128비트 UUID(Universal Unique Identifier) 급인 Zenoh ID(ZID)가 고정 도장(Stamping)으로 박힌다.

더욱 파괴적인 루틴은, 이 패킷이 라우터 교차로(Next-Hop Intersection)를 스쳐 지나갈 때마다 그 교차로를 경유한 모든 증인 라우터들의 ZID가 마치 꼬리표 훈장처럼 배열 메모리 포맷터(Path Tracer Array)에 줄줄이 인코딩(Trace Encoding Add)된다는 점이다. 한창 포워딩을 수행하던 특정 B 라우터가 B1, A를 거쳐 자기에게 날아온 바이트 덩어리를 받아 쥐었는데(Intercept Payload), 그 패킷 헤더의 꼬리표 배열 안에 예전에 한 번 경유했던 ‘자기 자신(B 라우터)의 ZID’ 문양이 이미 새겨져 있음을 감지하는 0.1 밀리초(ms)의 그 결정적 순간. B 엔진의 분산 논리 통제망 파서(Parser)는 “아, 이건 미친 핑퐁 루프에 빠진 데드락 좀비 궤적이다!“라고 인지하여 뒤도 돌아보지 않고 즉석(Fast-Drop) 파쇄 폐기 처분해 버린다. 백 홉(Count 100)을 돌 때까지 쓰레기를 나르는 잉여 폭주(Flooding Pollution)를 미연에 원천 차단하는 가장 잔혹하지만 우아한 스레딩(Thread Safety)의 승리이다.

2. 서브스크립션 트리(Subscription Forwarding Tree) 정제와 무한 증폭 확산 억제

루프(Loop) 현상이 단순히 데이터 패킷이 돌아오는 문제라면 스탬핑 파쇄로 제압할 수 있으나, 분산망의 진짜 지뢰는 각 노드들이 주변을 향해 쏟아내는 “나 어떤 토픽을 구독(Subscribe)한다!“라는 구독 관심사 선언문(Subscription Declaration Flood)이 얽혔을 때 발생하는 끔찍한 구조적 트리 폭풍(Tree Construction Storm)이다.

피어 A, B, C가 원형(Triangle Mesh)으로 엮여 있는 구조도. A가 /sensor/motor 토픽의 구독자 선언을 쏘았다. 이걸 받은 B가 C에게, C가 다시 그걸 A에게 나르면서, 전 세계 라우터가 똑같은 토픽 구독 요청을 무한정 수만 번 서로 핑퐁 선언하게 되는 끔찍한 사태(Subscription Infinite Diffusion). 브로커가 없는 탈중앙 환경의 가장 큰 저주가 이 FIB 지도를 그리는 파라미터 간섭 붕괴이다.

Zenoh 아키텍처는 이 지점에서 강력한 병합 간선 절단(Branch Pruning Edge Filter) 칼날을 뽑아 든다. 특정 라우터 트리 단말 데몬 B가 이미 A의 지시를 받아 자신의 라우팅 테이블(FIB) 장부에 “포트 2번 방향을 위해 /sensor/motor 토픽을 포워딩해줄 파이프를 열어두자!“고 한 번 결재(Mapping Match)해둔 상태다. 그 직후 C로부터 똑같이 생긴 경로(/sensor/motor)에 대한 다른 이음새의 중복 구독 선언(Duplicate Interest)이 기어들어 오는가? 스케줄러 데몬은 절대로 자신의 상위 라우터(Parent Node)를 향해 이 중복 멍청이 티켓을 또다시 메아리쳐 쏘지 않는다(Supress Redundant Declare). 자신 선에서 조용히 “나의 포트 3번도 이 패킷들을 뿌려줘야 할 포워딩 목록 어레이 테이블(Array Destination Table) 브랜치에 살포시 그냥 추가(Append Endpoint)“하고 입을 다물어버린다. 상위 네트워크를 불필요한 중복 선언 루프들로 과부하를 터뜨려 공작하는 사태를 극강의 캐시 맵 압축 포워더 지능으로 소멸시키는 이 효율성이야말로 토폴로지 루프 억제의 진정한 아방가르드이다.

3. 포워딩 매치(Forwarding Match) 병목 타파: 기수 트리(Radix Tree) 알고리즘 구조

방어막이 아무리 철저히 루프를 잡아낸다 한들, 한순간에 쏟아지는 10만 건의 트래픽 패킷 덩어리들의 헤더 이름 /factory/robot/01/sensor/1 등을 라우터의 램 상에 기록된 10만 줄의 구독 경로 조건문(Sub Route Rule Match)들과 일일이 대조하며 for 루프(Iterative String Equals)를 돈다면 라우터 CPU는 그 지연 속도에 질식하고(String Check Crash) 만다. 초저지연을 보장하기 위해선 이 무거운 문자열 탐색 병목을 단일 클럭 사이클 분쇄기로 갈아 치워야(Execution Lookup Time Nill) 한다.

제노 패브릭 포워더(zenohd) 엔지니어 진영은 FIB 라우팅 검색 테이블 구조에 원시적인 해시 맵(Hash Dictionary)이나 배열 리스트 구조를 도려내고, 유일무이한 기수 트리(Prefix Radix Tree, 또 다른 명칭 Patricia Trie 구조 결합 알고리즘) 메모리 구조를 이식해 내었다. 긴 이름 문자열의 패킷 토픽들이 라우터 검열소에 진입할 때 공통된 접두사 /factory/robot/ 구간은 트리의 메인 척추 경로를 타며 단 한 번의 바이트 대조(O(k) Time Complexity)만으로 수백, 수천 갈래의 필터링 조건문 가지치기를 일순간에 뭉텅이로 건너뛰어버린다(Instant String Prefix Evaluation).

와일드카드(Wildcard ***) 조건식까지 버무려진 미친 복잡도의 거대한 정규식 매칭 쿼리 문법들이 트리 안의 분기점 노드(Leaf & Internal Nodes Tracker)에서 나노초(ns) 단위로 일거에 스위치-오버 결판이 나버린다. 네트워크 경로 루프의 오류는 봉쇄되고, 10만 갈래의 매칭 병렬 연산 포워딩 판단은 단일 문자열 O(1)급 폭포수 계단 탐색으로 질주하는 이 오프로딩 정점의 퍼포먼스야말로 현대 라우터 아키텍처 세계에 하사된 신의 무기인 것이다.