Understanding Data Center Fabrics - Part 8: Advanced Underlay Control Planes
Mục lục
- 1. Giới thiệu: hai control plane nâng cao — Dynamic Flooding và RIFT
- 2. Dynamic Flooding: nguồn gốc từ mạng MANET
- 3. Forward optimization
- 4. Reverse optimization
- 5. Resilience: dùng CSNP làm cơ chế dự phòng
- 6. Hiệu quả thực tế của Dynamic Flooding
- 7. Cách tiếp cận khác: bầu Flooding Leader
- 8. RIFT — Routing In Fat Trees
- 9. So sánh Dynamic Flooding (modified IS-IS) và RIFT
1. Giới thiệu: hai control plane nâng cao — Dynamic Flooding và RIFT
Hai lựa chọn control plane nâng cao thường được nhắc tới cho underlay của data center fabric: Dynamic Flooding (từng là một phần của OpenFabric control plane) và RIFT.
Tại thời điểm video gốc được thực hiện, cả hai chủ yếu tồn tại dưới dạng code thử nghiệm (experimental), khó tiếp cận trong thực tế: FRRouting có sẵn một OpenFabric daemon — gọi là fabricd (có thể chạy trong production nếu đang dùng FRRouting làm routing protocol stack), còn RIFT thì cần biết đúng người để xin được bản implementation. Kể từ đó, cả hai đã tiến xa hơn đáng kể trong quá trình chuẩn hóa — xem cập nhật ở mục Nguồn tham khảo cuối bài.
Vì sao IS-IS/OSPF tiêu chuẩn "hụt hơi" trên fabric có fan-out cao?
Cơ chế flood mặc định của IS-IS và OSPF được thiết kế cho mạng có mật độ liên kết vừa phải: mỗi router nhận một LSA/LSP mới sẽ reflood nó cho toàn bộ neighbor, trừ đúng neighbor vừa gửi tới. Trên một Clos/spine-leaf fabric, đặc điểm cốt lõi lại chính là thật nhiều đường đi song song (fan-out ECMP cao) — mỗi leaf nối tới hàng chục spine, mỗi spine nối tới hàng chục hoặc hàng trăm leaf. Flood kiểu "gửi cho tất cả" trên một topology dày đặc như vậy khiến số bản tin trùng lặp mà một thiết bị phải nhận và xử lý tăng rất nhanh theo số neighbor trong vùng — càng nhiều đường đi song song (vốn là mục tiêu thiết kế của Clos fabric để tăng băng thông), control plane càng phải trả giá bằng một khối lượng bản tin flood dư thừa khổng lồ, kéo dài thời gian hội tụ và tốn CPU xử lý ở mọi thiết bị.
Dynamic Flooding và RIFT là hai câu trả lời khác nhau cho đúng một vấn đề gốc rễ này: Dynamic Flooding chọn cách giữ nguyên mô hình link-state truyền thống của IS-IS nhưng làm cho khâu flooding thông minh hơn (chỉ flood trên một tập con topology thay vì toàn bộ), còn RIFT chọn cách thiết kế lại mô hình thông tin định tuyến, khai thác đúng cấu trúc phân tầng của fat tree để mỗi tầng chỉ cần biết đúng lượng thông tin cần thiết cho vai trò của mình. Phần tiếp theo đi sâu vào từng cách tiếp cận.
2. Dynamic Flooding: nguồn gốc từ mạng MANET
Dynamic Flooding thực chất là một phiên bản chỉnh sửa của IS-IS. Nguồn gốc: từ những năm 1990, trong lĩnh vực mobile ad hoc network (MANET) — phổ biến trong các hệ thống quân sự và các mạng vận tải quân sự — người ta cần các giao thức link-state hiệu quả cao, và một nhóm nghiên cứu (bao gồm tác giả) đã làm việc để tối ưu hóa flooding và các hoạt động khác của link-state protocol cho loại mạng này. Dynamic Flooding là sự lặp lại/điều chỉnh (repetition/modification) của công trình đó để áp dụng cho data center fabric.
Nói ngắn gọn cho người chưa quen thuật ngữ này: MANET (Mobile Ad hoc NETwork) là một mạng gồm các node di động (ví dụ xe quân sự, thiết bị cầm tay) kết nối với nhau qua sóng vô tuyến mà không có hạ tầng cố định (không router/switch cắm dây sẵn) — mỗi node vừa là host vừa tự đóng vai trò router, và vì các node di chuyển liên tục nên topology thay đổi rất nhanh và khó lường. Đây là thuật ngữ chuẩn của ngành, gắn với IETF MANET Working Group (nhóm làm việc thuộc routing area của IETF), chuyên phát triển các giao thức định tuyến cho đúng loại mạng biến động cao này. Vấn đề cốt lõi của MANET — làm sao flood thông tin link-state hiệu quả khi topology thay đổi liên tục và băng thông vô tuyến hạn chế — hóa ra lại rất giống với bài toán flooding trên một fabric có fan-out ECMP cao: quá nhiều liên kết ngang hàng, dễ gây bùng nổ số bản tin trùng lặp nếu flood theo kiểu "gửi cho tất cả mọi neighbor". Đó là lý do các kỹ thuật tối ưu hóa từ MANET được mang sang áp dụng cho data center fabric.
Điểm quan trọng cần lưu ý: các tối ưu hóa trong Dynamic Flooding hoạt động được trên mọi loại topology, không bị giới hạn riêng cho data center fabric như một số lựa chọn khác (ví dụ RIFT) — đây đơn thuần là các tối ưu hóa tổng quát, chỉ tình cờ hoạt động rất tốt trên các mạng có fan-out ECMP cao.
Có hai loại tối ưu hóa flooding trong Dynamic Flooding: forward optimization và reverse optimization (đúng theo cách gọi trong draft IETF).
Vì sao flood "gửi cho tất cả" lại bùng nổ trên fabric mật độ cao?
Hãy hình dung một area/level phẳng gồm N intermediate system, tất cả nằm trong cùng một flooding domain (trường hợp phổ biến ở level 2 của một fabric 2-tier hay 3-tier tương đối gọn). Với flood mặc định, mỗi khi có một LSP thay đổi, thiết bị phát hiện thay đổi gửi nó cho toàn bộ neighbor trực tiếp; mỗi neighbor đó lại reflood tiếp cho toàn bộ neighbor của chính nó (trừ nơi vừa nhận) — và cứ thế lan tỏa. Trên một topology có độ kết nối cao, một thiết bị nằm giữa fabric có thể nhận cùng một LSP fragment qua rất nhiều đường khác nhau gần như cùng lúc, vì nó có nhiều neighbor và mỗi neighbor đều đang làm đúng nhiệm vụ "reflood cho tất cả" của mình. Số bản copy trùng lặp không tăng tuyến tính mà tăng rất nhanh theo mật độ liên kết — mục 6 phía dưới sẽ định lượng cụ thể mức độ này.
Ý tưởng cốt lõi của Dynamic Flooding là tách rời flooding topology khỏi physical topology. Physical topology — toàn bộ liên kết vật lý thật trong fabric — vẫn được dùng để forward traffic dữ liệu bình thường (SPF với cost thật vẫn chạy trên toàn bộ topology để tính best path). Nhưng LSA/LSP chỉ được flood trên một flooding topology là một tập con thưa (sparse subset) của physical topology, miễn tập con đó vẫn đảm bảo mọi thiết bị liên thông được với nhau — draft IETF khuyến nghị tập con này nên biconnected (tồn tại ít nhất một đường dự phòng nếu một liên kết trong flooding topology bị đứt), đổi lại một phần flooding dư thừa để lấy khả năng chịu lỗi. Diagram dưới đây minh họa trực quan khác biệt giữa hai cách flood này trên cùng một topology vật lý.
💡 Hình dung như thế này: giống một khu chung cư đông người muốn báo tin khẩn (cháy, mất điện) cho toàn bộ cư dân. Cách flood "gửi cho tất cả" giống việc mọi căn hộ đều tự gõ cửa báo tin cho tất cả hàng xóm liền kề — tin lan rất nhanh nhưng mỗi hộ nhận đi nhận lại cùng một tin từ hàng chục hướng khác nhau, gây hỗn loạn không cần thiết. Dynamic Flooding giống việc ban quản lý chỉ định trước một vòng cư dân làm nhiệm vụ truyền tin chính thức (flooding topology) — tin vẫn đến được mọi căn hộ, chỉ khác là đi theo đúng một tuyến gọn thay vì tỏa ra khắp mọi hướng cùng lúc.
3. Forward optimization
Sau khi trao đổi LSDB, mỗi intermediate system có thể xây dựng một local flooding tree dựa trên topology cục bộ quanh nó. Cách làm: chạy SPF với chi phí mọi liên kết đặt bằng 1, thay vì dùng chi phí thật — kết quả không phải là "đường đi tối ưu" mà là một view topology cục bộ, dùng để xây flooding tree tối ưu (không nhằm tối ưu đường đi định tuyến).
Từ kết quả SPF cost=1, mỗi intermediate system biết được tập neighbor trực tiếp và tập neighbor cách 2 hop. Từ đó nó chọn ra một tập neighbor để flood tới sao cho tập này đủ để phủ toàn bộ 2-hop neighborhood: flood tới một số neighbor theo cách cho phép chúng reflood tiếp, còn với các neighbor còn lại thì flood theo cách báo hiệu (dùng link-local packet signaling) rằng "nhận gói này vào database, dùng cho SPF cục bộ, nhưng không được reflood".
Ví dụ minh họa: ở tầng đầu tiên, một router phải flood cho cả 4 intermediate system kết nối trực tiếp vì mỗi cái có tập 2-hop-neighbor khác nhau — tất cả đều được phép reflood. Nhưng ở tầng tiếp theo, nếu router phát hiện hai neighbor có cùng một tập neighbor, nó chỉ cần flood cho một trong hai theo kiểu cho phép reflood, còn cái còn lại chỉ nhận vào database mà không reflood — giảm số lượng bản tin flood dư thừa.
Vì sao dùng SPF với cost bằng 1 thay vì cost thật?
Điểm dễ gây nhầm lẫn nhất của forward optimization là: nó chạy SPF, nhưng không phải để tìm đường đi tốt nhất cho traffic. Nếu dùng cost thật, kết quả SPF sẽ ưu tiên các liên kết băng thông cao/độ trễ thấp — đúng mục tiêu của routing, nhưng lại không phản ánh đúng "khoảng cách" theo nghĩa số hop mà bài toán flooding cần. Bài toán flooding chỉ quan tâm một câu hỏi duy nhất: nếu flood cho neighbor X, thì X sẽ tiếp tục reflood cho những ai — và tập đó có trùng với tập đã flood cho neighbor Y hay không? Câu hỏi này thuần túy là bài toán đồ thị theo số hop, không liên quan gì tới cost đường truyền. Đặt toàn bộ cost bằng 1 buộc SPF trả về đúng dữ liệu cần: ai là neighbor 1-hop, ai là neighbor 2-hop — thông tin thô để xây flooding tree, hoàn toàn tách biệt khỏi việc chọn best path cho dữ liệu thật (việc đó vẫn do SPF chạy với cost thật đảm nhiệm, song song và độc lập).
Về bản chất, bài toán "chọn tập neighbor tối thiểu để phủ hết 2-hop neighborhood" là một biến thể của bài toán minimum dominating set trong lý thuyết đồ thị — một bài toán NP-hard nếu muốn lời giải tối ưu tuyệt đối trên đồ thị bất kỳ. Dynamic Flooding không cố tìm lời giải tối ưu toàn cục; nó dùng một heuristic cục bộ, dựa đúng trên thông tin 2-hop mà mỗi node tự thấy, để có một lời giải đủ tốt, tính toán nhanh, và không cần bất kỳ sự phối hợp tập trung nào giữa các node — mỗi thiết bị tự quyết định độc lập dựa trên view cục bộ của chính nó.
4. Reverse optimization
Vấn đề phát sinh khi dùng flood có chọn lọc: router nhận được bản tin theo hướng bị "chặn reflood" vẫn có xu hướng muốn flood ngược lại đúng đường nó vừa nhận. Reverse optimization giải quyết việc này bằng quy tắc: nếu một intermediate system nhận LSP từ một neighbor, và nó có một neighbor khác đang nằm trên (hoặc là một phần của) shortest-path-tree quay ngược lại nguồn gốc của thay đổi đó, thì nó sẽ không flood LSP đó ngược lại theo hướng của neighbor kia — vì hướng đó đã/sẽ nhận được thông tin theo đường ngắn hơn rồi.
Cơ chế này giúp giảm đáng kể lượng flooding cả hai chiều (forward lẫn reverse) trong fabric.
Vì sao reverse optimization không làm mất thông tin?
Câu hỏi tự nhiên đặt ra: nếu một hướng "bị chặn reflood ngược lại", liệu có nguy cơ một phần fabric bị bỏ sót update? Chìa khóa nằm ở điều kiện áp dụng: quy tắc "không reflood ngược" chỉ kích hoạt khi intermediate system xác nhận được rằng neighbor kia đã nằm trên hoặc đang là một phần của shortest-path-tree quay về đúng nguồn gốc thay đổi — nghĩa là thiết bị đó chắc chắn sẽ (hoặc đã) nhận được thông tin qua một đường ngắn hơn hoặc bằng, không phải phỏng đoán. Nói cách khác, reverse optimization không cắt bớt thông tin một cách tùy tiện — nó chỉ loại bỏ đúng những bản copy chắc chắn dư thừa, dựa trên thông tin topology mà mọi node trong fabric đều đã có sẵn từ LSDB.
Kết hợp forward và reverse optimization, Dynamic Flooding về bản chất đang giải quyết hai chiều của cùng một bài toán: forward optimization giới hạn ai được phép nhận và tiếp tục lan truyền (ai reflood, ai chỉ ghi vào database), còn reverse optimization giới hạn việc lan truyền ngược lại đúng hướng vừa đến. Cả hai cùng hướng tới một mục tiêu: mỗi LSP thay đổi chỉ nên đi qua mỗi liên kết trong flooding topology đúng một lần theo mỗi chiều, thay vì lặp lại nhiều lần như flood mặc định.
5. Resilience: dùng CSNP làm cơ chế dự phòng
Nếu chỉ chọn đúng một neighbor làm "reflector" (điểm reflood duy nhất) và thiết bị đó gặp sự cố ngay sau khi nhận bản tin, cần có cơ chế dự phòng. Dynamic Flooding tận dụng khả năng CSNP (Complete Sequence Number PDU) sẵn có của IS-IS: sau khi flood, mỗi intermediate system đặt một timer (ví dụ khoảng 1 giây), rồi kiểm tra CSNP với tất cả adjacency của nó để đảm bảo LSDB của mình khớp với các neighbor — đây chính là lớp dự phòng/khả năng phục hồi (resilience) cho cơ chế flooding có chọn lọc.
CSNP hoạt động ra sao để phát hiện thiếu sót?
CSNP vốn là một cơ chế đã có sẵn trong IS-IS từ trước Dynamic Flooding rất lâu — không phải phát minh riêng cho Dynamic Flooding, mà được tận dụng lại đúng mục đích. Về bản chất, CSNP là một "bảng mục lục" tóm tắt toàn bộ LSDB của một thiết bị: với mỗi LSP đang có, CSNP liệt kê LSP ID, sequence number và checksum — không mang theo nội dung LSP đầy đủ, chỉ mang đủ thông tin để so sánh. Khi hai neighbor trao đổi CSNP, mỗi bên nhanh chóng nhận ra LSP nào bên kia có mà mình thiếu (sequence number cao hơn, hoặc LSP hoàn toàn vắng mặt trong danh sách của mình), từ đó chủ động yêu cầu gửi lại đúng phần còn thiếu qua PSNP (Partial Sequence Number PDU).
Việc Dynamic Flooding dùng lại CSNP làm lớp dự phòng rất hợp lý về mặt thiết kế: forward/reverse optimization đã cố tình cắt giảm số bản copy một LSP được gửi đi, nghĩa là chấp nhận đánh đổi một chút rủi ro — nếu đúng node duy nhất được chỉ định reflood lại gặp sự cố đúng lúc đó thì sao. Thay vì xây thêm một cơ chế phát hiện lỗi hoàn toàn mới, Dynamic Flooding chỉ cần định kỳ so sánh CSNP giữa các neighbor: nếu LSDB giữa hai bên đã khớp nhau thì không cần làm gì thêm, còn nếu lệch thì cơ chế đồng bộ chuẩn của IS-IS (đã được kiểm chứng qua nhiều thập kỷ vận hành) sẽ tự động vá lại phần thiếu, mà không cần chờ một sự kiện lỗi tường minh nào được báo trước.
💡 Hình dung như thế này: forward/reverse optimization giống việc một tòa soạn báo chỉ in và phát hành qua đúng một số đại lý chính thay vì phát cho mọi sạp báo cùng lúc, để tiết kiệm giấy in. Nhưng nếu đúng đại lý đó đóng cửa đột xuất, một khu vực có thể chưa kịp nhận báo hôm đó. CSNP đóng vai trò như buổi đối chiếu sổ sách định kỳ giữa các đại lý: mỗi đại lý so sánh mục lục số báo mình đang có với đại lý bên cạnh, phát hiện ngay chỗ thiếu và bổ sung kịp thời — không cần chờ độc giả phàn nàn mới biết có sự cố.
6. Hiệu quả thực tế của Dynamic Flooding
Theo quan sát thực tế, các tối ưu hóa kiểu này có thể giảm thời gian hội tụ khoảng 50% hoặc hơn — ví dụ một mạng vốn hội tụ trong khoảng 40 giây có thể giảm xuống còn khoảng 20-25 giây.
Về mặt số lượng bản tin flood: trước đó đã ghi nhận trường hợp một thiết bị có thể nhận 40-60 bản copy của cùng một LSP fragment trong một flooding domain level 2 phẳng, thiết lập theo kiểu flood mặc định. Với kiểu tối ưu hóa này, con số đó giảm xuống còn 1-4 bản copy — có thể tinh chỉnh thêm về timing để đưa xuống đúng 1 bản, nhưng khi đã giảm xuống khoảng 4 bản thì việc tối ưu thêm không còn tạo tác động đáng kể tới tốc độ hội tụ nữa, nên không cần quá lo lắng về việc ép xuống chính xác 1.
Vì sao chỉ cần giảm xuống còn "vài bản copy" là đủ, không cần ép về đúng 1?
Lý do nằm ở bản chất chi phí xử lý một LSP trùng lặp: bước tốn kém nhất khi xử lý một bản copy dư thừa là giải mã, kiểm tra checksum, và so khớp với LSDB hiện có để xác nhận đây đúng là bản đã biết — bước này gần như tốn chi phí cố định bất kể là bản copy thứ 2 hay thứ 40. Vì vậy, phần lớn lợi ích về tốc độ hội tụ đã đạt được ngay từ bước giảm mạnh đầu tiên (từ hàng chục bản xuống còn một vài bản); mỗi bước tối ưu thêm sau đó (ví dụ từ 4 xuống 1) chỉ tiết kiệm một phần xử lý rất nhỏ so với tổng thời gian hội tụ, trong khi độ phức tạp của thuật toán tính flooding tree lại tăng lên đáng kể nếu cố ép về đúng 1 bản trong mọi trường hợp topology. Đây là đánh đổi kinh điển giữa "tối ưu tuyệt đối" và "đủ tốt cho thực tế" — Dynamic Flooding chọn vế thứ hai.
Cũng cần lưu ý: các con số cụ thể ở trên phụ thuộc nhiều vào mật độ liên kết thực tế của topology thử nghiệm — một fabric có fan-out thấp hơn, hoặc ít node cùng nằm trong một flat level-2 domain hơn, sẽ cho con số khác. Điều đáng tin cậy hơn là xu hướng: mức giảm luôn tỉ lệ thuận với mật độ liên kết ban đầu, càng dày đặc thì lợi ích tối ưu hóa càng lớn. Số liệu thử nghiệm độc lập từ chính nhóm phát triển thuật toán này trên một mạng butterfly khoảng 2.500 node cho kết quả cùng bậc độ lớn: trung bình 40 bản copy một LSP fragment giảm còn trung bình 2 bản (nhiều trường hợp chỉ còn 1), và thời gian hội tụ tổng thể giảm khoảng một nửa — xem chi tiết ở mục Nguồn tham khảo.
7. Cách tiếp cận khác: bầu Flooding Leader
Một cách tiếp cận khác để tối ưu flooding là bầu ra một flooding leader — có thể là thiết bị ảo hoặc thiết bị vật lý thật, khá tương đồng với khái niệm route reflector trong BGP. Khi có thay đổi xảy ra ở đâu đó trong mạng, thiết bị phát hiện thay đổi sẽ gửi LSP thay đổi (in-band hoặc out-of-band) lên flooding leader; flooding leader sau đó sẽ reflood thông tin này cho toàn bộ mạng.
Flooding leader không chạy SPF hay tính best path — nó chỉ tính toán tập thiết bị tối ưu để flood tới (gọi là optimal flooding tree) dựa trên vị trí tập trung của nó: biết chính xác nếu flood tới một thiết bị nào đó, thiết bị đó sẽ reflood cho những ai — từ đó chọn một tập thiết bị để flood và chỉ định rõ ai được reflood cho ai, sao cho mỗi thiết bị trong mạng chỉ nhận đúng một bản copy của LSP thay đổi.
Có một draft IETF về hướng này (tác giả Tony Li). Ngoài ra, bài báo "Jupiter Rising" của Google mô tả một hệ thống gọi là Firepath, cũng dùng cơ chế flooding leader tập trung tương tự.
Cách bầu Flooding Leader hoạt động ra sao?
Cơ chế bầu flooding leader mà Tony Li đề xuất ban đầu, sau này được chính thức hóa thành một trong hai chế độ vận hành của Dynamic Flooding: centralized mode, đối lập với distributed mode — chính là forward/reverse optimization đã mô tả ở các mục 3-5 phía trên, nơi mỗi node tự tính flooding tree cục bộ của riêng mình. Trong centralized mode, một node duy nhất trong area được bầu làm Area Leader — thuật ngữ chính thức trong RFC, tương ứng với "flooding leader" nói ở trên.
Cơ chế bầu khá quen thuộc với ai từng làm việc với OSPF hay IS-IS: mỗi node đủ điều kiện quảng bá một giá trị priority; node có priority cao nhất được chọn làm Area Leader, nếu nhiều node cùng priority cao nhất thì node có system ID (IS-IS) hoặc Router ID (OSPF) cao nhất sẽ thắng — cùng kiểu thuật toán tie-break đã quen thuộc từ bầu DR/BDR trong OSPF hay DIS trong IS-IS, chỉ khác đối tượng được bầu ra không phải để đại diện quảng bá pseudonode, mà để làm trung tâm tính toán flooding tree cho cả area.
Sau khi được bầu, Area Leader thu thập đủ topology của toàn area (qua chính cơ chế flood thông thường ban đầu, trước khi flooding topology tối ưu được áp dụng), từ đó tính ra một flooding topology tối ưu cho toàn bộ area và quảng bá lại cho mọi node biết node nào cần reflood cho node nào. Từ thời điểm đó, các node không còn tự quyết định việc reflood theo kiểu cục bộ nữa — chúng chỉ đơn giản làm theo đúng chỉ định mà Area Leader đã tính sẵn.
💡 Hình dung như thế này: khác với việc một nhóm bạn tự truyền tin đồn cho nhau — mỗi người tự quyết định nên kể lại cho ai, đúng kiểu forward/reverse optimization ở các mục trên — cơ chế bầu leader giống một tổng đài viên duy nhất trong công ty nhận mọi cuộc gọi rồi tự quyết định chuyển tiếp thông báo cho đúng phòng ban nào. Không ai trong công ty phải tự đoán nên gọi cho ai nữa, tất cả chỉ cần biết đúng một số máy lẻ của tổng đài. Nếu tổng đài viên nghỉ đột xuất, người dự phòng đã biết trước quy trình sẽ tiếp quản ngay, không cần đào tạo lại từ đầu.
8. RIFT — Routing In Fat Trees
RIFT (Routing In Fat Trees) không phải một giao thức hoàn toàn mới, mà là một adaptation của IS-IS kết hợp thêm một số tính chất của distance-vector protocol, được thiết kế chuyên biệt để chạy tốt trên fat tree — cụ thể là trên spine-leaf/Clos fabric có fan-out ECMP cao.
Cách hoạt động: mỗi liên kết vẫn flood như IS-IS bình thường. Khi thông tin tới được fab layer, fab layer sẽ đóng vai trò như một ranh giới domain L1/L2: nó lấy chi phí (cost) đã học được qua flooding thông thường và gắn nó thành một destination khả đạt được kết nối cục bộ (tương tự type 3 trong OSPF, hoặc tương tự một level-2 LSP trong IS-IS).
Khi một spine nhận được advertisement kiểu distance-vector từ fab layer, nó sẽ truyền tiếp advertisement đó xuống các "remote" (leaf) của nó cũng dưới dạng distance-vector. Các top-of-rack switch được thiết lập tự động để không reflood — chúng chỉ gửi thông tin kiểu link-state lên trên; khi nhận update kiểu distance-vector từ trên xuống, chúng không re-flood lại cho ai khác vì bản thân không truyền tiếp loại thông tin này.
RIFT tự tối ưu hóa và giảm mạnh khối lượng thông tin định tuyến: các top-of-rack không thực sự chạy SPF trên phần lớn mạng — chúng chỉ dùng default route hướng về fab, đồng thời advertise thông tin link-state của chính mình lên trên. Ngược lại, các fab router có LSDB đầy đủ vì chúng nhận trọn vẹn thông tin link-state từ khắp nơi trong mạng.
💡 Hình dung như thế này: giống một công ty nơi nhân viên tầng dưới (leaf) chỉ cần nhớ đúng một câu "có thắc mắc gì thì hỏi sếp tổng ở tầng trên" (default route hướng về fab), không cần thuộc lòng sơ đồ tổ chức toàn công ty. Trong khi đó, sếp tổng (fab layer) mới là người nắm rõ toàn bộ sơ đồ tổ chức (full LSDB) vì mọi báo cáo từ các phòng ban đều đổ về đó. Mỗi cấp chỉ giữ đúng lượng thông tin cần thiết cho vai trò của mình — đây chính là cách RIFT tự động giảm tải bộ nhớ ở biên mạng.
Vì cơ chế này về bản chất đang thực hiện aggregation, RIFT cũng gặp đúng vấn đề aggregation black hole đã nói ở phần trước — và đây chính là lý do RIFT có sẵn cơ chế auto de-aggregation, nhằm ngăn chặn các routing black hole phát sinh từ việc aggregation này.
Vì sao RIFT được gọi là "anisotropic", và ZTP giúp gì?
RIFT tự mô tả mình là một giao thức anisotropic (bất đẳng hướng) — nghĩa là hành vi flood khác nhau tùy theo hướng: link-state theo hướng lên (northbound), distance-vector theo hướng xuống (southbound). Đây không phải một chi tiết cài đặt phụ, mà chính là cơ chế cốt lõi giúp RIFT giảm tải thông tin đúng ở nơi cần giảm: hướng lên (leaf gửi thông tin link-state của chính mình lên fab layer) cần đầy đủ chi tiết để fab layer xây được bức tranh topology hoàn chỉnh, còn hướng xuống (fab layer gửi default route xuống leaf) không cần chi tiết vì leaf chỉ cần biết "đi lên là ra được mọi nơi".
Đi kèm với thiết kế anisotropic này là Zero Touch Provisioning (ZTP) — một cơ chế giúp mỗi node RIFT tự xác định level của chính nó trong fat tree (leaf, spine hay superspine) mà gần như không cần cấu hình tay, chỉ dựa trên thông tin trao đổi qua gói LIE (Link Information Element) với neighbor trực tiếp. ZTP còn có khả năng tự phát hiện miscabling — ví dụ một liên kết bị đấu nhầm giữa hai leaf thay vì giữa leaf và spine — điều mà các giao thức link-state truyền thống như IS-IS hay OSPF không tự làm được, vì chúng không có khái niệm "level" gắn liền với vai trò trong fat tree. Đây là một lợi ích vận hành thực tế: giảm rủi ro cấu hình sai khi triển khai fabric quy mô lớn với hàng trăm hoặc hàng nghìn thiết bị.
Cơ chế auto de-aggregation ngăn black hole cụ thể ra sao?
Khi một leaf hoặc một liên kết trong fabric gặp sự cố, default route/aggregate mà fab layer đang quảng bá xuống có thể không còn chính xác nữa — một số spine vẫn quảng bá "tôi đi được tới leaf X" trong khi thực ra đường đó đã đứt, dẫn tới black hole nếu traffic bị route sai hướng. RIFT giải quyết việc này bằng hai kiểu disaggregation:
- Positive disaggregation: node quảng bá một prefix cụ thể hơn (more specific) để thu hút traffic đúng hướng — chỉ những spine nào thực sự còn đường tới đích mới advertise prefix cụ thể này, traffic sẽ theo longest-match mà đi đúng qua các spine đó.
- Negative disaggregation: node quảng bá một "exception" theo hướng ngược lại để đẩy traffic tránh xa một hướng cụ thể không còn khả dụng; loại này có tính chất transitive — có thể tiếp tục lan xuống các tầng thấp hơn khi mọi tuyến khả dụng khác đều đã bị loại trừ.
Cả hai cơ chế đều được tính toán và quảng bá tự động ngay khi RIFT phát hiện thay đổi topology, không cần can thiệp thủ công — đây chính là điểm khác biệt so với việc tự cấu hình static route dự phòng trên các giao thức truyền thống.
9. So sánh Dynamic Flooding (modified IS-IS) và RIFT
Không có câu trả lời "cái nào tốt hơn tuyệt đối" — mỗi lựa chọn có điểm mạnh và đánh đổi riêng, tùy vào mục tiêu scale:
- RIFT là giao thức phức tạp hơn, có nhiều cơ chế bên trong hơn, và gắn chặt trực tiếp với fat tree / spine-leaf / Clos fabric — đây chính là mục tiêu thiết kế của nó.
- Dynamic Flooding (modified IS-IS) thực hiện nhiều tối ưu hóa hơn theo hướng tổng quát, có thể chạy trên nhiều loại topology đa dạng hơn nhiều, không chỉ riêng data center fabric.
Về khả năng scale:
- Với modified IS-IS (Dynamic Flooding): có thể dễ dàng đạt tới khoảng 2.600 router và 120.000 route/destination khả đạt; các implementation thương mại có thể vượt xa hơn, nhưng khó có khả năng vượt quá mốc khoảng 500.000 route.
- Với RIFT: có thể scale cao hơn nhiều so với mốc đó. Đổi lại cho độ phức tạp cao hơn, RIFT cho route-count lớn hơn và đồng thời tự động giảm kích thước bảng định tuyến/FIB ở các thiết bị biên — rất hữu ích với các thiết bị có bộ nhớ hạn chế.
Tóm gọn lại: chọn cái nào tùy vào việc bạn có sẵn sàng đánh đổi độ phức tạp vận hành để lấy khả năng scale cao hơn và FIB nhỏ hơn ở biên (RIFT), hay muốn một giải pháp tổng quát hơn, đơn giản hơn, chạy được trên nhiều loại topology chứ không riêng fat tree (Dynamic Flooding).
Vì sao khác biệt kiến trúc lại dẫn tới khác biệt khả năng scale?
Gốc rễ của chênh lệch khả năng scale giữa hai giải pháp nằm ở chỗ chúng tối ưu hóa hai thứ khác nhau. Dynamic Flooding vẫn giữ nguyên mô hình link-state đầy đủ của IS-IS — mọi thiết bị vẫn phải giữ toàn bộ LSDB và tự chạy SPF trên toàn bộ topology; thứ được tối ưu chỉ là số bản tin flood dư thừa trong quá trình đồng bộ LSDB, không phải kích thước LSDB hay FIB. Vì vậy trần khả năng scale của Dynamic Flooding bị giới hạn bởi chính giới hạn cố hữu của mô hình link-state toàn cục: mỗi thiết bị vẫn phải xử lý và lưu trữ thông tin về toàn bộ mạng, dù việc lan truyền thông tin đó đã hiệu quả hơn nhiều.
RIFT thì khác về bản chất: nó không chỉ tối ưu việc lan truyền, mà còn tối ưu lượng thông tin mỗi tầng cần giữ. Nhờ mô hình anisotropic đã nói ở mục 8, một leaf (ToR) trong RIFT không cần giữ full LSDB của toàn mạng — nó chỉ cần một default route hướng lên fab layer, cộng với một số disaggregated route khi cần. Đây chính là lý do RIFT vừa scale được cao hơn, vừa giảm được kích thước FIB ở biên: chi phí bộ nhớ và CPU ở phần lớn số lượng thiết bị trong fabric (các leaf, luôn đông hơn spine/superspine rất nhiều) được giữ ở mức tối thiểu, bất kể mạng lớn tới đâu ở các tầng trên.
Đánh đổi đi kèm cũng nằm ở đúng chỗ đó: để đạt được việc giảm tải thông tin theo tầng, RIFT cần thêm nhiều cơ chế phối hợp hơn — ZTP, phân biệt northbound/southbound, disaggregation tích cực/tiêu cực — mỗi cơ chế đều là một điểm cần hiểu và troubleshoot khi vận hành thực tế. Dynamic Flooding không cần các cơ chế này vì nó không cố thay đổi mô hình thông tin, chỉ tối ưu đường đi lan truyền — đơn giản hơn để vận hành, nhưng đổi lại giới hạn quy mô sẽ đến sớm hơn.
Cả hai lựa chọn đều đã tiến xa hơn nhiều so với giai đoạn "code thử nghiệm" được mô tả ở trên — xem cập nhật trạng thái chuẩn hóa mới nhất ở mục Nguồn tham khảo.
Nguồn tham khảo
Nguồn gốc: Understanding Data Center Fabrics, Part 8: Advanced Underlay Control Planes — kênh Packet Pushers
Ghi chú thuật ngữ: bản transcript gốc (chuyển giọng nói tự động) ghi tên giao thức là "desktop flood" — đây gần như chắc chắn là lỗi nhận diện giọng nói của cụm "Dynamic Flooding" (tên draft IETF thực tế thuộc nhóm làm việc LSR, gắn với OpenFabric control plane mà video có nhắc tới). Bài viết đã dùng tên đúng "Dynamic Flooding" để tránh gây nhầm lẫn cho người đọc.
Cập nhật trạng thái chuẩn hóa (fact-check + mở rộng, truy cập 2026-07-13 — video gốc được thực hiện trước các mốc dưới đây nên mô tả "code thử nghiệm" trong bài đã lỗi thời):
- Dynamic Flooding đã được xuất bản thành RFC 9667 — "Dynamic Flooding on Dense Graphs" (tháng 10/2024), sản phẩm của LSR Working Group tại IETF, định nghĩa thay đổi cho cả IS-IS, OSPFv2 và OSPFv3. Cơ chế cốt lõi: tách rời flooding topology khỏi physical topology, để bản tin link-state chỉ được flood trên một flooding topology thưa (sparse) trong khi traffic thật vẫn forward theo physical topology đầy đủ. (RFC 9667)
- RIFT đã được xuất bản thành RFC 9692 — "RIFT: Routing in Fat Trees" (tháng 4/2025), kết thúc giai đoạn Internet-Draft (bản draft cuối là
draft-ietf-rift-rift-24). Cơ chế cốt lõi đúng như bài mô tả: kết hợp "link-state hướng lên spine" và "distance-vector hướng xuống leaf", cùng cơ chế auto-disaggregation khi có sự cố. (RFC 9692) - OpenFabric (draft-white-openfabric, hiện tới bản
-07) vẫn đang ở dạng individual Internet-Draft, chưa thấy tiến thành RFC riêng tính đến thời điểm tra cứu — daemonfabricdtrong FRRouting vẫn dựa trên draft này. Về quan hệ giữa hai công trình: OpenFabric ban đầu bao gồm cả phần tối ưu flooding, sau đó phần này được tách ra thành một work item riêng của LSR Working Group và trở thành RFC 9667 — khớp với mô tả "từng là một phần của OpenFabric control plane" trong bài. (draft-white-openfabric) - Firepath / Jupiter Rising: xác nhận chính xác — theo paper "Jupiter Rising: A Decade of Clos Topologies and Centralized Control in Google's Datacenter Network" (Google, SIGCOMM 2015), Firepath là giao thức định tuyến dùng cho các thế hệ fabric Firehose, Watchtower và Saturn (các thế hệ trước Jupiter), hoạt động theo đúng mô hình flooding leader tập trung: mỗi switch gửi view kết nối cục bộ lên một Firepath master trung tâm, master này tổng hợp và phân phối lại global link state cho toàn bộ switch. (Jupiter Rising paper, SIGCOMM 2015)