Understanding Data Center Fabrics - Part 7: Link State Protocol In The Underlay
Mục lục
- 1. Chọn IS-IS hay OSPF cho underlay?
- 2. IS-IS "đủ tốt": bằng chứng scale thực tế
- 3. Hai vấn đề scale của link-state trên topology ECMP cao
- 4. Flooding hoạt động thế nào trong một fabric
- 5. Wait timer và exponential backoff
- 6. Aggregation black hole
- 7. Auto-disaggregation
- 8. Lời khuyên: đừng aggregate nếu không cần
1. Chọn IS-IS hay OSPF cho underlay?
Nếu chọn link-state protocol làm underlay, có hai lựa chọn: OSPF và IS-IS. Tác giả nghiêng về IS-IS cho vai trò này (không khẳng định dùng OSPF là sai, chỉ nêu lý do cá nhân). Dưới đây là 3 lý do chính, xếp theo mức độ ảnh hưởng tới vận hành thực tế — từ chi tiết vận hành hàng ngày (định dạng gói tin, auto config) tới thứ quyết định trực tiếp tốc độ hội tụ khi mạng có sự cố (partial SPF):
-
Định dạng gói tin và cách flood hiệu quả hơn — từng có thời điểm OSPF hiệu quả hơn IS-IS, nhưng theo thời gian OSPF được bổ sung quá nhiều option/tính năng, nên trong trường hợp đơn giản (một flooding domain), kể cả ở quy mô lớn, IS-IS vẫn hiệu quả hơn một chút.
-
Auto configuration — không nhất thiết cần IP address trên các liên kết fabric nếu implementation hỗ trợ route tới unnumbered interface. Với IS-IS, không cần IP address để bring up adjacency/peering giữa hai intermediate system. OSPFv3 cũng có thể làm được điều này, nhưng khi nói "OSPF" phần lớn người ta đang nói tới OSPFv2.
-
Partial SPF — về lý thuyết mọi implementation link-state đều có thể chạy partial SPF, nhưng do cách đóng gói packet, OSPF khó chạy partial SPF hơn nhiều. Ví dụ: nếu một liên kết leaf (không ảnh hưởng tới hình dạng cây SPF) biến mất khỏi mạng, router ở xa vẫn phải chạy full SPF với OSPF. Với IS-IS, mọi implementation mà tác giả biết đều tự động chạy partial SPF theo mặc định, không cần cấu hình gì thêm. OSPF cũng hỗ trợ việc này nhưng thường chỉ áp dụng cho route external, không áp dụng cho route internal.
Trong IS-IS, cơ chế này còn có tên riêng: Partial Route Calculation (PRC) — khác OSPF (nơi partial SPF chỉ áp dụng cho route liên vùng/external), PRC trong IS-IS áp dụng cho mọi prefix trong domain, vì IS-IS tách bạch rõ thông tin topology (IS Reachability TLV) khỏi thông tin prefix — đây chính là lý do IS-IS có khả năng scale tốt hơn trong một area/level duy nhất.
Vì sao gói tin của IS-IS lại nhẹ hơn?
IS-IS không chạy trên IP — nó đóng gói trực tiếp bên trong khung tầng liên kết dữ liệu (data-link layer), kế thừa từ chồng giao thức OSI (CLNP/ES-IS), và nhận diện thiết bị bằng System ID (một dạng địa chỉ NSAP) thay vì địa chỉ IP. Vì không phải mang theo IP header và không phụ thuộc vào IP để hình thành adjacency, phần khung sườn giao thức của IS-IS gọn hơn ngay từ thiết kế gốc. OSPF thì ngược lại: chạy thẳng trên IP, mỗi LSA phải mang theo IP header, và qua nhiều năm liên tục được bổ sung các loại LSA mới (opaque LSA, LSA cho MPLS TE, LSA cho segment routing…) khiến bộ máy xử lý ngày càng cồng kềnh dù chức năng lõi không đổi.
Chính vì tách khỏi IP, IS-IS cũng không cần địa chỉ IP để dựng adjacency — hai router bắt tay bằng System ID, không phải IP. Đây là lý do liên kết giữa hai node trong fabric có thể để unnumbered (không gán IP riêng cho từng liên kết vật lý) mà IS-IS vẫn build được adjacency và tính route bình thường — chỉ cần gán IP (thường là loopback) cho phần prefix cần advertise. Với một fabric có hàng trăm, hàng nghìn liên kết spine-leaf, việc không phải quản lý một dải IP riêng cho từng liên kết vật lý giảm đáng kể gánh nặng vận hành: không cần IPAM cho interface link, không lo xung đột subnet giữa các cặp thiết bị.
Vì sao tách bạch topology khỏi prefix lại giúp SPF nhanh hơn?
💡 Hình dung như thế này: SPF giống việc vẽ bản đồ đường đi giữa các thành phố — chỉ cần vẽ lại khi có một con đường mới mở hoặc bị chặn. Đổi tên một khu phố trong thành phố đó (một prefix) không đòi hỏi vẽ lại bản đồ, chỉ cần cập nhật đúng nhãn tại vị trí đã có sẵn.
Thuật toán SPF (Dijkstra) dựng cây đường đi ngắn nhất chỉ cần một đầu vào duy nhất: topology graph — router nào nối với router nào, qua interface nào, cost bao nhiêu. Prefix (địa chỉ IP/subnet) không nằm trong đồ thị đó — chúng chỉ là nhãn gắn thêm vào một node sau khi cây đã dựng xong. Nếu chỉ có prefix thay đổi (một subnet leaf được thêm/bớt, còn cấu trúc cây mạng vẫn nguyên), router hoàn toàn không cần chạy lại Dijkstra — chỉ cần cập nhật đúng nhãn gắn vào node đã biết trong LSDB. Đây là lý do PRC "rẻ" hơn full SPF rất nhiều: chi phí gần như tuyến tính theo số prefix cần cập nhật, không phụ thuộc vào kích thước hay độ phức tạp của topology.
IS-IS làm được điều này triệt để nhờ kiến trúc TLV tách bạch rõ ràng: IS Reachability TLV (topology) và IP Reachability TLV (prefix) là hai loại TLV độc lập, router có thể vá riêng phần prefix trong LSDB mà không đụng tới phần topology. OSPF thì gộp chung thông tin link và prefix ngay trong Router-LSA (Type-1) — bất kỳ thay đổi nào ở LSA này, kể cả chỉ một stub link (một prefix leaf) lên/xuống, đều buộc phải chạy lại full SPF, vì bản thân OSPF không có cách tách riêng "đây chỉ là thay đổi prefix, topology vẫn nguyên". Cisco có bổ sung thêm iSPF (incremental SPF) để xử lý một phần vấn đề này cho thay đổi topology intra-area, nhưng đây là tính năng mở rộng riêng của vendor, không phải hành vi mặc định theo chuẩn RFC 2328 gốc.
# Cisco IOS-XR — xem log các lần chạy SPF, phân biệt Full SPF và Partial (PRC)
show isis spf-log
show isis rib-log
# Juniper JunOS — xem thống kê SPF gần nhất (Full vs partial route calculation)
show isis spf log detail
show isis statistics
2. IS-IS "đủ tốt": bằng chứng scale thực tế
Nhiều người phàn nàn IS-IS khó học (những con số dài, cách đánh địa chỉ lạ…) nhưng có rất nhiều tài liệu để học — sách của Jeff Doyle, loạt video "Intermediate System" dài 6 giờ trên Safari Books, sách IS-IS: Deployment in IP Networks (Addison-Wesley, 2003) của Alvaro Retana và tác giả — Russ White (có lời tựa từ Mike Shand — một trong những người phát minh IS-IS cùng Radia Perlman, và ông đã review cuốn sách), sách "Computer Networking Problems and Solutions" cũng có phần giải thích cách link-state hoạt động và IS-IS.
Trước khi vào số liệu, cần làm rõ khái niệm flooding domain: đây là ranh giới mà trong đó mọi LSP được flood tới toàn bộ router thành viên — mọi router trong cùng flooding domain đều giữ chung một bản LSDB (link-state database) và chạy SPF trên đúng một bức tranh topology đó. IS-IS chia flooding domain thành hai cấp — Level 1 (nội bộ một area) và Level 2 (backbone nối các area lại với nhau), tương tự khái niệm area trong OSPF — nhằm giới hạn phạm vi flood/SPF khi mạng quá lớn để gom chung một domain duy nhất. Khi tài liệu này nói một mạng chạy "phẳng, không chia level 1/level 2", nghĩa là toàn bộ router nằm chung một flooding domain — không cắt nhỏ theo area/level — nên các con số quy mô nêu dưới đây phản ánh đúng giới hạn "tệ nhất": không được hưởng lợi gì từ việc chia nhỏ ranh giới.
IS-IS đã được chứng minh chạy tốt ở quy mô rất lớn: tác giả từng thấy IS-IS chạy trong một flooding domain phẳng, không chia level 1/level 2 với 5.000-6.000 router và 10.000-30.000 route; từng thấy một mạng khoảng 2.500+ router (kiểu 2620) với 120.000 route trong một flooding domain, hội tụ ban đầu dưới 40 giây, và hội tụ khi có sự cố đơn lẻ (single link/node failure) chỉ trong vài trăm mili-giây — thậm chí trong môi trường ảo hóa (chỉ chạy trên một phần processor, không phải full CPU riêng). Kết luận: link-state protocol scale lớn hơn nhiều so với những gì người ta thường nghĩ.
IS-IS cũng được triển khai rộng rãi ở các mạng transit của nhà cung cấp dịch vụ lớn — từng thấy một flooding domain level 2 duy nhất mang hơn 5.000 thiết bị với 10.000-20.000 route hoặc hơn. Các implementation IS-IS hiện có (kể cả FRRouting mã nguồn mở, Juniper, Cisco, Arista, và cả các startup nhỏ) nhìn chung đều rất tốt.
Vì sao một flooding domain phẳng lại gánh được quy mô lớn như vậy? Ba yếu tố cộng hưởng với nhau. Thứ nhất, PRC/partial SPF (đã nói ở mục trên) giữ chi phí tính toán gần như hằng số theo số prefix, thay vì tăng theo kích thước topology. Thứ hai, exponential backoff (mục 5 bên dưới) ngăn CPU bị dồn ứ khi nhiều sự kiện xảy ra dồn dập cùng lúc. Thứ ba, các implementation hiện đại đã được tối ưu hoá việc parse/encode LSP và duy trì LSDB qua nhiều thế hệ phần cứng, nên phần chi phí cố định trên mỗi router ngày càng nhỏ đi. Nói cách khác, con số 120.000 route trên 2.500+ router không phải giới hạn lý thuyết của giao thức — nó là bằng chứng cho thấy các cơ chế tối ưu này đã đủ trưởng thành để gánh tải thực tế lớn hơn nhiều so với định kiến phổ biến rằng "link-state không scale".
3. Hai vấn đề scale của link-state trên topology ECMP cao
Khi chạy link-state protocol như IS-IS trên một topology có độ mesh cao, fan-out ECMP lớn (kiểu Clos hoặc butterfly fabric), có hai vấn đề chính cần lưu ý:
- Wait timer và max age.
- Flooding — lượng bản tin flood trong các mạng dạng này khá lớn.
Vì sao mesh cao lại làm cả SPF lẫn flooding tăng vọt?
Butterfly/Clos fabric được thiết kế để tối đa hoá số đường đi song song (ECMP) giữa hai điểm bất kỳ — và chính đặc điểm này, khác hẳn một topology dạng cây/thưa truyền thống, là gốc rễ của cả hai vấn đề nêu trên. Chi phí xử lý của một link-state protocol không tỷ lệ theo số router trong mạng, mà tỷ lệ theo số adjacency — tức số cạnh trong đồ thị topology. Một topology thưa (mỗi router chỉ có 2-3 neighbor) và một fabric Clos dày ECMP (mỗi leaf/spine có thể có 8, 16, thậm chí 32+ neighbor) hoàn toàn có thể có cùng số lượng router, nhưng số cạnh trong đồ thị của chúng lệch nhau gấp nhiều lần — và hệ quả lệch theo đúng tỷ lệ đó, ở cả hai khâu:
- SPF phải duyệt qua nhiều cạnh hơn để dựng cây đường đi ngắn nhất — độ phức tạp của Dijkstra phụ thuộc vào cả số đỉnh lẫn số cạnh của đồ thị; càng nhiều cạnh, thời gian duyệt càng dài. Vẫn rất nhanh ở quy mô mili-giây như đã nói ở mục 2, nhưng xu hướng tăng là có thật và cộng dồn khi fabric lớn dần.
- Flooding nhân bản đúng theo fan-out — mỗi lần một node nhận LSP mới, nó re-flood tới TẤT CẢ neighbor của nó (trừ neighbor vừa gửi LSP tới). Một node fan-out 8 tạo ra nhiều bản flood hơn hẳn một node fan-out 2, và hiệu ứng này nhân dồn qua từng hop — đúng cơ chế sẽ minh hoạ cụ thể ở mục 4 ngay sau đây.
💡 Hình dung như thế này: giống việc lan truyền một tin đồn trong một nhóm bạn. Nếu mỗi người chỉ quen 2-3 người (topology thưa), tin lan chậm và ít người phải nhắc lại. Nếu ai cũng quen hết cả chục người trong nhóm (mesh dày), cùng một tin sẽ dội lại tai bạn hàng chục lần từ hàng chục hướng khác nhau — và tất cả những người đó cũng tốn công nhắc lại dù tin chẳng còn gì mới.
4. Flooding hoạt động thế nào trong một fabric
Xét một butterfly fabric nhỏ chạy trong một flooding domain level 2 duy nhất. Khi một liên kết bị đứt, hai intermediate system (router) hai đầu liên kết đó sẽ flood thông tin thay đổi tới tất cả thiết bị đang kết nối trực tiếp; các thiết bị đó lại tiếp tục flood tiếp tới tất cả thiết bị mà chúng kết nối — quá trình này giống hệt việc dò tất cả đường đi có thể trong ví dụ hội tụ BGP đã nói ở phần trước.
Flooding chỉ dừng lại khi một intermediate system nhận được đúng LSP (fragment) mà nó đã nhận trước đó — lúc này nó sẽ không flood tiếp. Trong các mạng quy mô lớn, có thể quan sát thấy một thiết bị nhận tới 40-60 bản copy của cùng một LSP fragment trong một flooding domain level 2 phẳng, quy mô lớn.
Dù nhận nhiều bản copy, thiết bị chỉ chạy SPF (hoặc partial SPF) đúng một lần. Với trường hợp chỉ một leaf hanging off tree bị thay đổi (không làm thay đổi cấu trúc bên trong cây), các thiết bị chỉ cần chạy partial SPF — rất nhanh: một lần chạy SPF đầy đủ thường chỉ mất khoảng 8-10ms (tùy phần cứng); nếu thấy SPF chạy mất 100-200ms thì cần xem lại việc tối ưu mạng hoặc chia lại ranh giới flooding domain. Partial SPF còn nhanh hơn nữa vì thực chất không cần chạy thuật toán SPF — chỉ cần vào LSDB (link-state database) và xóa liên kết đó đi.
Vì sao mỗi node lại re-flood tới TẤT CẢ neighbor thay vì chỉ báo lại cho node cần biết? Vì bản thân node nhận LSP không biết trước ai "cần" thông tin đó và ai không — cách duy nhất để đảm bảo mọi router trong flooding domain rốt cuộc đều nhận được là gửi đi theo mọi hướng còn lại, trừ hướng vừa nhận về. Đây là lý do gốc của hiện tượng "40-60 bản copy": mỗi router trên đường đi đều lặp lại đúng hành vi đó một cách độc lập, không có cơ chế phối hợp toàn cục nào để tránh gửi trùng trước khi gửi. Trên các liên kết point-to-point, mỗi lần re-flood còn kèm theo một PSNP (Partial Sequence Number PDU) xác nhận đã nhận — nghĩa là ngoài chính các bản LSP trùng lặp, mạng còn phải gánh thêm lượng PSNP tương ứng. Cộng đồng chuẩn hoá IS-IS (LSR working group tại IETF) cũng nhìn nhận đây là vấn đề nghiêm túc chứ không chỉ là tiểu tiết vận hành: đề xuất IS-IS Fast Flooding, vốn nhắm thẳng vào việc giảm tải flooding dư thừa này trên liên kết băng thông cao, đã được chuẩn hoá thành RFC 9681 (Experimental, công bố 11/2024).
# Cisco IOS-XR — xem thống kê flooding: số LSP nhận về, số bản trùng lặp, số lần chạy SPF
show isis statistics
# Output minh họa (rút gọn)
IS-IS Level-2 statistics:
LSPs sourced (own) : 42
LSPs received (total) : 1845
LSPs received (duplicate, no-op) : 1761
LSP retransmissions (P2P) : 3
SPF calculations (full) : 4
SPF calculations (partial/PRC) : 187
(Output minh họa — cấu trúc và tên field đúng theo lệnh thật, số liệu cụ thể chỉ mang tính ví dụ.)
Đọc bảng trên: router này chỉ tự tạo ra 42 LSP, nhưng nhận về 1.845 bản — trong đó 1.761 bản là trùng lặp (đã có sẵn trong LSDB, không cần xử lý gì thêm ngoài gửi PSNP xác nhận nếu là liên kết P2P). Đây chính xác là hiện tượng "40-60 bản copy" đã nói ở trên, phản chiếu qua số liệu thống kê thực tế. Hai dòng cuối mới là phần quyết định tải CPU thực sự: full SPF chỉ chạy 4 lần, còn PRC chạy tới 187 lần — đúng như kỳ vọng, vì phần lớn thay đổi trong một mạng đang chạy ổn định chỉ là biến động prefix, không phải biến động topology.
5. Wait timer và exponential backoff
Có ba loại wait timer liên quan tới link-state protocol:
- Wait timer khi tạo thông tin thay đổi — ví dụ advertisement interval, cho biết chờ bao lâu trước khi phát ra thông tin về một thay đổi vừa quan sát được trong mạng.
- Wait timer sau khi nhận thông báo thay đổi topology (một LSP/LSA) — chờ bao lâu trước khi chạy SPF.
Cả hai đều có thể cấu hình được trong hầu hết implementation.
Vì sao các timer này không nên đặt bằng 0? Vì việc flood và chạy SPF tiêu tốn tài nguyên xử lý, bộ nhớ, năng lượng — trên các processor chậm, việc chuyển sang tiến trình routing để flood và chạy SPF là một context switch, có thể tốn đáng kể thời gian. Vì vậy người ta có xu hướng gộp nhiều thay đổi lại thành từng nhóm để giảm tải CPU.
Với processor hiện đại và liên kết tốc độ cao, có thể muốn đặt các timer này về 0 để phản ứng ngay lập tức — nhưng điều này sẽ gây ra rất nhiều lượt chạy SPF và flooding hơn. Giải pháp thường dùng là exponential backoff: phản ứng rất nhanh với sự kiện đầu tiên (gần như 0 giây, chỉ vài mili-giây), nhưng nếu các thay đổi tiếp tục xảy ra dồn dập, tốc độ phản ứng sẽ chậm dần lại. Cơ chế này cho phép kiểm soát tốc độ báo cáo thay đổi trong link-state protocol: thay đổi đầu tiên được báo rất nhanh (hội tụ nhanh), nhưng khi mạng biến động dồn dập, hệ thống sẽ tự động giảm tốc độ phản ứng thay vì phản ứng ngay với từng thay đổi. Thuật toán này đã được IETF chuẩn hoá thành RFC 8405 — "SPF Back-off Delay Algorithm for Link-State IGPs", với mục tiêu để các implementation khác nhau (Cisco, Juniper, FRRouting…) có cùng một hành vi backoff khi cùng tham gia một mạng, tránh trường hợp router này hội tụ nhanh trong khi router khác vẫn đang throttle, gây bất đồng bộ tạm thời trong quá trình hội tụ.
Xem và cấu hình backoff thực tế
# Juniper JunOS — xem cấu hình SPF backoff hiện tại và số lần SPF đã chạy dồn dập gần nhất
show isis overview | match "SPF|Backoff"
# Output minh họa
SPF delay: 200 ms, SPF holddown: 5000 ms, SPF rapid runs: 3
Last SPF run: 00:00:42 ago, triggered by: IS reachability TLV change
Backoff state: steady (initial delay in effect)
(Output minh họa — cấu trúc và tên field đúng theo lệnh thật, số liệu cụ thể chỉ mang tính ví dụ; riêng "SPF delay: 200 ms" và "SPF rapid runs: 3" là giá trị mặc định thật của JunOS.)
Ba tham số trong spf-options của JunOS ánh xạ đúng ba khái niệm đã nói ở trên: delay là thời gian chờ trước khi chạy SPF sau sự kiện đầu tiên (mặc định 200ms — đúng như mô tả "phản ứng gần như ngay lập tức"), rapid-runs là số lần SPF được phép chạy liên tiếp ở tốc độ nhanh trước khi backoff bắt đầu kéo dài khoảng chờ (mặc định 3 lần), và holddown là khoảng nghỉ bắt buộc sau khi chạm giới hạn rapid-runs. Nhìn vào output, có thể suy ra ngay router đang ở trạng thái ổn định (không có sự kiện dồn dập) hay đang bị backoff kéo dài (nhiều sự kiện liên tiếp trong thời gian ngắn) — đây là cách nhanh nhất để xác nhận cấu hình backoff có thực sự đang hoạt động đúng như kỳ vọng hay không, thay vì chỉ tin vào file cấu hình.
Max age và LSP refresh: nguồn tải flooding định kỳ hay bị bỏ quên
Ở mục 3, "wait timer và max age" được liệt kê là một trong hai vấn đề scale — phần trên mới nói về wait timer (khi phát sinh thay đổi và khi chạy SPF). Còn max age là một cơ chế khác, ít được để ý hơn nhưng cũng tạo ra tải flooding định kỳ trong một fabric ECMP dày: mỗi LSP mang theo một bộ đếm "thời gian sống còn lại" (Remaining Lifetime), giảm dần theo thời gian; khi về 0, LSP bị coi là hết hạn (MaxAge) và bị xoá khỏi LSDB nếu không được refresh trước đó. Theo kiến trúc gốc của IS-IS (ISO 10589), MaxAge là một hằng số kiến trúc cố định 1.200 giây (20 phút) — không thể tuỳ ý đổi khác giữa các router trong cùng domain, vì nếu lệch nhau, các router sẽ đồng bộ sai lệch thời điểm một LSP "chết".
Để LSP không bị hết hạn oan dù topology/route thực tế không đổi gì, router nguồn phải chủ động refresh — phát lại đúng LSP đó (tăng sequence number) trước khi Remaining Lifetime chạm 0. Cisco khuyến nghị đặt refresh interval nhỏ hơn max-lsp-lifetime khoảng 300 giây (mặc định refresh khoảng 900 giây với lifetime 1.200 giây); JunOS tính refresh interval tự động bằng lifetime trừ 317 giây (mặc định khoảng 883 giây). Nói cách khác, cứ khoảng 15 phút, mọi LSP trong domain lại được flood lại một lượt — dù chẳng có gì thay đổi trong mạng.
Trong một topology thưa, đây chỉ là một đợt flood nhỏ, định kỳ, gần như vô hình. Nhưng trong một fabric ECMP dày đặc như đã phân tích ở mục 3, fan-out cao khiến đợt refresh định kỳ này cũng bị nhân bản y hệt cơ chế flooding khi có sự cố — tạo ra một nhịp tải nền (baseline load) lặp lại đều đặn mà nhiều người vận hành quên tính đến khi ước lượng băng thông control-plane cho một fabric lớn.
6. Aggregation black hole
Một vấn đề thiết kế quan trọng khi dùng route aggregation trong các protocol có hỗ trợ multiple flooding domain hoặc route aggregation: aggregation black hole.
Trong một butterfly fabric, một spine switch thường chỉ có đúng một đường đi (one path) tới mỗi thiết bị/port cụ thể ở tier trên nó. Giả sử tier 3 (super spine/fab layer) chỉ advertise một default route ra ngoài — đây là cách giảm state trong mạng thường thấy với aggregation.
Nếu liên kết duy nhất từ router A3 (một router ở tier dưới, tầng spine) tới đích 100::/64 bị đứt: router A2 phía trên vẫn đang dùng ECMP để rải traffic qua nhiều liên kết (bao gồm cả liên kết tới A3), vì A2 không có cách nào biết A3 đã mất kết nối tới đích đó — do A3 vẫn chỉ advertise default route như bình thường. Kết quả: traffic A2 gửi qua A3 tới đích đó sẽ bị vứt bỏ — đây chính là một routing black hole.
💡 Hình dung như thế này: giống một tổng đài lễ tân chỉ biết nói "cứ chuyển hết cho phòng ban X" mà không biết đường dây riêng tới đúng người cần gặp trong phòng ban X vừa bị đứt. Khách gọi tới vẫn được chuyển hướng như bình thường — nhưng cuộc gọi rơi vào khoảng không, vì lễ tân chỉ nắm thông tin tổng quát (default route), không biết chi tiết đường dây nào trong phòng ban đó còn sống.
Sơ đồ dưới đây đặt lại đúng 3 router trong ví dụ (A2, A3 và các router cùng tier với A3) lên một topology cụ thể, để thấy rõ traffic của A2 vẫn tiếp tục chảy đều vào cả nhánh đã chết như thế nào:
Vì sao BFD hay fast-reroute không tự giải quyết được vấn đề này?
Nhiều người nghĩ chỉ cần bật BFD (Bidirectional Forwarding Detection) để phát hiện lỗi nhanh là đủ — nhưng BFD chỉ phát hiện được liên kết/neighbor ngay kế cạnh bị chết, không phát hiện được việc một prefix cụ thể phía sau một neighbor còn sống trở nên unreachable. Trong ví dụ trên, liên kết giữa A2 và A3 hoàn toàn bình thường — A2-A3 vẫn up, BFD giữa hai router này vẫn pass. Cái chết nằm ở một liên kết khác, xa hơn, giữa A3 và đích. A2 không có adjacency trực tiếp với đoạn liên kết đó, nên không cơ chế phát hiện lỗi cục bộ nào — BFD hay bất kỳ dạng link-down detection nào — chạm tới được.
Đây chính là bản chất của vấn đề: aggregation che giấu thông tin theo đúng thiết kế của nó — nó đánh đổi khả năng quan sát chi tiết (visibility) để lấy về ít state hơn, và khi đánh đổi đó xảy ra đúng lúc có sự cố, cái giá phải trả là traffic bị rơi vào khoảng không mà không router nào trong control-plane hay biết. Vấn đề này cũng không phải hiện tượng đặc thù của một topology hay một giao thức cụ thể nào — bất kỳ thiết kế nào kết hợp route aggregation với ECMP multipath đều tiềm ẩn rủi ro tương tự, vì hai cơ chế này vốn phục vụ hai mục tiêu khác nhau (aggregation để giảm state, ECMP để rải tải đều) và không cơ chế nào trong hai cái tự thân biết về sự tồn tại của cái còn lại. Đây chính là động lực trực tiếp dẫn tới cơ chế auto-disaggregation ở mục tiếp theo.
7. Auto-disaggregation
Một cách xử lý vấn đề aggregation black hole là auto disaggregation — đây là cơ chế mà giao thức RIFT sử dụng: khi A2 phát hiện A3 không còn tập neighbor giống như trước (ví dụ mất kết nối tới A4), A2 sẽ nhận về các route cụ thể hơn (ít nhất là các route chỉ có thể tới được qua liên kết bị đứt đó) thay vì chỉ nhận default route tổng quát như trước.
RIFT là gì, và vì sao nó cần cơ chế này?
RIFT (Routing in Fat Trees) là một giao thức định tuyến được IETF chuẩn hoá riêng cho topology Clos/fat-tree (RFC 9692, với RFC 9696 bàn thêm về khả năng áp dụng thực tế trong vận hành). RIFT ra đời sau khi cộng đồng vận hành data center nhận ra cả link-state truyền thống (IS-IS/OSPF) lẫn distance-vector (BGP) đều cần "vá" thêm khá nhiều để chạy tối ưu trên một fabric ba tier trở lên. Một trong những vấn đề RIFT được thiết kế để giải quyết ngay từ đầu chính là aggregation black hole vừa mô tả ở mục trên — thay vì để đây là hệ quả phụ phải tự xử lý sau bằng cấu hình thủ công, RIFT tích hợp sẵn phản ứng tự động: auto-disaggregation.
Cơ chế này hoạt động theo hai chiều, tuỳ vào việc cần "vá" theo hướng nào:
- Positive disaggregation: khi một số router ở tier trên (spine/fab layer) vẫn còn đường đi đầy đủ tới một đích, trong khi router khác cùng tier đã mất một phần kết nối (trường hợp gọi là "fallen leaf" — như A3 trong ví dụ trên), các router còn đủ đường đi sẽ chủ động advertise thêm route cụ thể hơn (specific hơn default) xuống tier dưới, để tier dưới biết "muốn chắc chắn tới đích này, hãy ưu tiên tôi". Đây là cách hiểu đầy đủ hơn của cơ chế đã mô tả ở trên: phần route cụ thể xuất hiện thêm trong bảng của A2 không phải nhờ A2 "hỏi rồi mới nhận trả lời", mà là advertisement được kích hoạt tự động ngay khi một router phát hiện tập neighbor của chính nó (hoặc của router khác cùng tier) đã thay đổi.
- Negative disaggregation: ngược lại, khi một router mất kết nối tới một đích cụ thể, thay vì im lặng (khiến traffic vẫn tiếp tục bị gửi tới do default route không đổi), nó chủ động advertise "tôi không tới được prefix này nữa" — một dạng route phủ định giúp các router phía trên loại trừ nó khỏi tập ECMP cho đúng prefix đó, thay vì phải chờ toàn bộ default route thay đổi (vốn ảnh hưởng tới mọi đích, không riêng đích đang gặp sự cố).
💡 Hình dung như thế này: giống một nhân viên giao hàng phát hiện một con phố phía sau vừa bị chặn — thay vì im lặng và vẫn nhận đơn giao tới cả khu vực đó như bình thường (khiến đơn hàng bị trả lại), họ chủ động báo lại tổng đài: "khu vực chung vẫn giao được, riêng con phố X thì đừng gửi qua tôi nữa." Tổng đài (A2) nhận được thông tin cụ thể hơn và từ đó định tuyến đúng — không cần chờ ai hỏi mới báo.
Auto-disaggregation từng được implement trong EIGRP (dù chưa bao giờ thực sự được deploy/ship chính thức), và hiện được implement trong giao thức RIFT — với khung chuẩn hoá đầy đủ qua RFC 9692/9696, dù mức độ triển khai thương mại rộng rãi tại thời điểm viết tài liệu này vẫn còn hạn chế hơn nhiều so với IS-IS hay BGP truyền thống.
8. Lời khuyên: đừng aggregate nếu không cần
Với các bằng chứng scale thực tế đã nêu (underlay có thể scale tới 120.000 route trên 2.600 thiết bị), câu hỏi đặt ra: tại sao còn cần phải aggregate? Mục tiêu khi xây data center fabric là dựng các vertical layer — underlay, overlay, và có thể thêm layer controller/orchestration — để tạo ra một module lớn hơn, phẳng hơn, tránh phải xử lý những vấn đề này bên trong module đó. Nếu đã scale out được tốt, lời khuyên đầu tiên là: đừng aggregate trong phạm vi data center fabric nếu không thực sự cần thiết.
Một hướng khác từng được thử nhưng chưa bao giờ triển khai tốt: nén (compression) giữa routing table và FIB (forwarding table trên thiết bị vật lý thực hiện việc forward gói tin) — có implement trong Cisco IOS nhưng theo tác giả chưa bao giờ thực sự được ship rộng rãi.
Vẫn có những trường hợp aggregation là bắt buộc, không phải tuỳ chọn — thường là ở biên fabric, nơi underlay kết nối ra ngoài (WAN edge, kết nối liên miền/inter-AS, hoặc nơi một fabric khác của tổ chức khác cần nhìn vào fabric này). Ở biên đó, quảng bá toàn bộ route nội bộ ra ngoài vừa không cần thiết (bên ngoài không quan tâm chi tiết topology nội bộ của bạn), vừa rủi ro bảo mật vì lộ chi tiết hạ tầng. Nguyên tắc ở đây là: aggregate ở biên, giữ phẳng bên trong — chứ không aggregate ngay giữa lòng fabric chỉ vì muốn "cho gọn". Nếu buộc phải aggregate ở đâu đó bên trong (chẳng hạn giới hạn phần cứng route table chưa thể nâng cấp ngay), cơ chế auto-disaggregation ở mục 7 chính là lưới an toàn giảm thiểu rủi ro black hole đi kèm quyết định đó — chứ không thay thế được lời khuyên gốc: chỉ nên xem đây là biện pháp dự phòng, không phải chiến lược thiết kế mặc định.
Phần tiếp theo sẽ tiếp tục bàn về các vấn đề nâng cao hơn của underlay protocol, cùng các sửa đổi trong RIFT và các chủ đề liên quan.
Nguồn tham khảo
Nguồn gốc: Understanding Data Center Fabrics, Part 7: Link State Protocol In The Underlay — kênh Packet Pushers
Ghi chú fact-check (truy cập 2026-07-13):
- Claim về Partial Route Calculation (PRC) trong IS-IS áp dụng cho mọi prefix trong domain (khác OSPF chỉ áp dụng cho inter-area/external) là chính xác, khớp với tài liệu kỹ thuật độc lập về SPF/PRC trong IS-IS và OSPF — đây là lý do được ghi nhận rộng rãi giúp IS-IS scale tốt hơn OSPF trong một area/level phẳng.
- Các con số quy mô cụ thể (2.500+ router, 120.000 route, hội tụ dưới 40 giây, PRC 8-10ms...) là quan sát/kinh nghiệm cá nhân của diễn giả từ các mạng ông từng vận hành, không phải benchmark công khai hay số liệu công bố chính thức từ vendor — nên xem đây là minh họa thực tế đáng tham khảo, không phải con số cam kết chung cho mọi triển khai.
- Đã verify tên sách IS-IS nhắc ở mục 2 qua WebSearch: tên chính xác là IS-IS: Deployment in IP Networks (Addison-Wesley, 2003), đồng tác giả Russ White và Alvaro Retana — bản gốc trong tài liệu chỉ ghi "sách ISIS của Alvaro Retana và tác giả" mà không nêu tên sách/năm xuất bản đầy đủ, nay đã bổ sung để trích dẫn chính xác hơn. Cụm "tác giả" trong câu này là tự-tham chiếu hợp lệ (Russ White là đồng tác giả cuốn sách, không phải lỗi transcript video/khóa học cần dọn).
- Đề xuất IS-IS Fast Flooding đã được chuẩn hoá thành RFC 9681 (Experimental, 11/2024), không còn là Internet-Draft — 2026-08-17, RFC 9681
- RFC 8405, ISO 10589 MaxAge 1200s, RFC 9692/9696 (RIFT), default timer JunOS (
spf-optionsdelay 200ms/rapid-runs 3/holddown 5000ms, lsp refresh = lifetime − 317s) và Cisco (max-lsp-lifetime1200s/lsp-refresh-interval900s) đã verify khớp tài liệu chính thức — 2026-08-17, RFC 8405, RFC 9692, Juniper spf-options