1 điểm bởi GN⁺ 4 giờ trước | Chưa có bình luận nào. | Chia sẻ qua WhatsApp
  • Hệ thống 13 năm tuổi từng xử lý hàng tỷ thông báo mỗi năm đã gặp timeout khi tạo ra hàng triệu thông báo cho mỗi creator lớn, và Patreon đã thiết kế lại hệ thống này với một lớp fanout tạo sẵn thông báo theo từng người nhận
  • Áp dụng fanout 2 giai đoạn, chia danh sách người nhận thành các batch nhỏ và xử lý độc lập feed trong ứng dụng, push và email, qua đó đạt khả năng mở rộng theo chiều ngang và cô lập lỗi theo kênh
  • Với các creator lớn, push và feed trong ứng dụng nhanh hơn 80%, email nhanh hơn 55%; khi lượng khán giả tăng gấp 4 lần, mức tăng độ trễ đầu-cuối cũng giảm từ 186% trước đây xuống lần lượt 33% và 60%
  • Chuẩn hóa việc lọc, kiểm tra đủ điều kiện và tạo payload bằng Notification Factory cùng API duy nhất send_fanout_notifications, đồng thời theo dõi timing theo từng giai đoạn và kết quả theo từng người nhận để đơn giản hóa vận hành và debug
  • 10 đội và hơn 30 kỹ sư đã chuyển đổi hơn 200 thông báo; tạo bản nháp bằng AI và hạn chót rõ ràng do lãnh đạo đặt ra đã góp phần giảm công việc lặp lại và thời gian vận hành song song kéo dài

Các creator lớn phơi bày giới hạn mở rộng

  • Patreon gửi hàng tỷ thông báo mỗi năm cho fan khi creator đăng bài hoặc bắt đầu livestream
  • Khi số fan trên mỗi creator tăng vọt nhờ việc ra mắt và tăng trưởng của gói thành viên miễn phí, đến đầu năm 2025 các nút thắt hiệu năng nghiêm trọng bắt đầu lộ rõ, đặc biệt quanh các creator lớn
  • Hệ thống thông báo bài đăng cũ có cấu trúc trong đó một tác vụ bất đồng bộ lấy toàn bộ người nhận, lọc theo thiết lập của từng người dùng, tạo payload cho từng người nhận rồi chuyển sang các hệ thống phân phối feed trong ứng dụng, push và email
  • Với creator lớn, một tác vụ đơn lẻ phải đảm nhiệm việc tạo hàng triệu thông báo, liên tục gặp timeout và khiến việc gửi thông báo ổn định tới lượng khán giả lớn trở nên khó khăn
  • Luồng cũ có hai giới hạn mang tính cấu trúc
    • Chi phí tạo theo từng người nhận bị dồn vào một tác vụ bất đồng bộ duy nhất, khiến mở rộng theo chiều ngang là không thể và tạo ra trần thông lượng rõ ràng
    • Feed trong ứng dụng, push và email bị ghép nối chặt chẽ, nên lỗi ở một kênh có thể chặn cả các kênh khác
  • Nhiều đội sản phẩm đã tạo cách mở rộng riêng cho từng loại thông báo lưu lượng cao, giải quyết được vấn đề ngắn hạn nhưng làm tăng độ phức tạp của nền tảng và khiến phát triển, vận hành, debug trở nên khó hơn
  • Họ quyết định giữ các hệ thống phân phối hiện có, nhưng đặt một lớp fanout chung phía trước để cung cấp khả năng mở rộng theo chiều ngang, cô lập kênh và khả năng quan sát

Sáu điều kiện thiết kế của nền tảng fanout

  • Lớp mới được thiết kế để chia danh sách người nhận lớn thành các batch nhỏ, tạo thông báo theo từng người nhận rồi chuyển đến các hệ thống feed trong ứng dụng, push và email hiện có
  • Nền tảng áp dụng sáu yêu cầu sau
    • Thân thiện với developer: Với mỗi thông báo lưu lượng cao, không nên phải giải quyết khả năng mở rộng và độ tin cậy từ đầu; cần hỗ trợ nhiều use case trong khi giảm lỗi sử dụng
    • Khả năng mở rộng theo chiều ngang: Danh sách người nhận phải được tự động chia thành các batch nhỏ và xử lý bất đồng bộ
    • Cô lập kênh: Feed trong ứng dụng, push và email phải chạy độc lập để lỗi ở một kênh không lan sang kênh khác
    • Xử lý theo ưu tiên: Thông báo nhạy cảm về thời gian phải dùng queue và worker pool riêng, tách khỏi thông báo thông thường
    • Khả năng quan sát: Phải có thể điều tra kết quả lọc và phân phối, cũng như đo độ trễ trong toàn bộ vòng đời thông báo
    • Khả năng mở rộng chức năng: Có thể bổ sung các tính năng tương lai như tạo danh sách người nhận mà không cần một lần refactor quy mô lớn khác

Tách business logic bằng Notification Factory

  • Để tách orchestration của nền tảng khỏi business logic theo từng thông báo, họ giới thiệu abstraction Notification Factory
  • Mỗi factory là bản thiết kế cho việc xử lý thông báo, định nghĩa các mục sau
    • Độ ưu tiên xử lý
    • Thiết lập thông báo sẽ áp dụng
    • Cách lọc người nhận
    • Kiểm tra đủ điều kiện theo từng thông báo
    • Cách tạo payload theo từng kênh
  • Pattern này dựa trên engine tác vụ phân tán nội bộ của Patreon và chia sẻ nhiều khái niệm với nó
  • Notification model định nghĩa các đối số tác vụ chứa dữ liệu riêng của một thông báo cụ thể nhưng được chia sẻ bởi tất cả người nhận
  • Lớp con BaseNotificationFactory liên kết với nó đóng vai trò như trình xử lý tác vụ, bao gồm cấu hình và phương thức để lọc người nhận và tạo thông báo
  • Để các tác vụ fanout chỉ nhận payload thông báo đã được serialize vẫn tìm được business logic cần chạy, họ sử dụng registry ánh xạ từng Notification model tới lớp factory tương ứng
  • Họ cần hỗ trợ nhiều loại thông báo khác nhau, đồng thời ngăn các lỗi triển khai phổ biến và các truy vấn dữ liệu kém hiệu quả
    • Vì Patreon có nhiều loại bản ghi người dùng và cách lọc khác nhau, interface người nhận được tổng quát hóa
    • Cung cấp các hook rõ ràng để triển khai thiết lập người dùng và kiểm tra đủ điều kiện theo từng thông báo

API duy nhất và fanout 2 giai đoạn

  • Trước đây, mỗi kênh dùng một API gửi riêng, khiến luồng feed trong ứng dụng, push và email có thể khác nhau, và các đội sản phẩm cũng phải cân nhắc hành vi theo từng kênh từ quá sớm
  • Sau khi thiết kế lại, điểm vào được hợp nhất thành một API duy nhất, send_fanout_notifications
    • Bên gọi truyền vào payload thông báo, danh sách người nhận và timestamp dùng để đo độ trễ phân phối
    • API tìm factory của thông báo đó, xác định kích thước batch và độ ưu tiên, rồi phân tán tác vụ theo từng kênh một cách độc lập
    • Lỗi hoặc độ trễ của một kênh không chặn các kênh khác
  • Giai đoạn đầu tiên phụ trách mở rộng việc tạo thông báo
    • Chia toàn bộ danh sách người nhận thành các batch nhỏ
    • Mỗi batch do một tác vụ FanoutNotifications xử lý
    • Tác vụ lọc người nhận, chạy kiểm tra đủ điều kiện theo từng thông báo, rồi dùng Notification Factory để tạo payload theo từng kênh
  • Giai đoạn thứ hai phụ trách mở rộng việc bàn giao phân phối
    • Fanout lại các thông báo đã tạo sang các tác vụ phân phối chuyên biệt cho feed trong ứng dụng, push và email
  • Trình xử lý tác vụ FanoutNotifications cốt lõi nằm giữa API và các hệ thống phân phối kênh hiện có, biến một tác vụ khổng lồ thành nhiều tác vụ nhỏ có thể xử lý độc lập

Quan sát và debug theo từng người nhận

  • Thông báo có thể thất bại hoặc bị bỏ qua vì nhiều lý do, chẳng hạn người dùng đã tắt thiết lập, không vượt qua kiểm tra đủ điều kiện, hoặc không thể gửi tới địa chỉ email
  • Trên nền tảng cũ, để kiểm tra kết quả xử lý của một thông báo cụ thể phải kết hợp log và dữ liệu từ nhiều hệ thống; cũng không có truy vết thực thi toàn diện theo từng người nhận, nên việc điều tra có thể mất hàng giờ
  • Nền tảng mới được thiết kế để trả lời các câu hỏi sau
    • Việc gửi thông báo mất bao lâu
    • Danh sách người nhận ban đầu lớn đến mức nào
    • Bao nhiêu người bị lọc, vì lý do gì
    • Theo từng kênh, bao nhiêu thông báo đã được gửi thành công
    • Vì sao một người dùng cụ thể nhận hoặc không nhận một thông báo cụ thể
  • Họ giới thiệu mô hình dữ liệu timing và logging được truyền xuyên suốt nền tảng
    • Ghi timestamp ở từng bước của luồng thông báo
    • Tạo metric và event cho cả kết quả tổng hợp lẫn kết quả theo từng người nhận
    • Developer có thể gắn thuộc tính logging để đưa các entity liên quan vào truy vết thực thi và event
  • Khi khả năng quan sát, cảnh báo, dashboard và công cụ debug được cải thiện, kỹ sư sản phẩm và đội support có thể tự điều tra nhiều vấn đề hơn mà không phụ thuộc vào kỹ sư nền tảng

Migration hơn 200 thông báo

  • Vì pattern Notification Factory đã thay đổi chính cách phát triển và duy trì thông báo, không thể chuyển đổi chỉ bằng một công cụ biến đổi mã (codemod) đơn giản
  • Cần giữ nguyên business logic, phụ thuộc dữ liệu, quy tắc đủ điều kiện và hành vi theo từng kênh của mỗi thông báo
  • Dựa trên tài liệu migration và các PR migration thủ công mẫu, họ xây dựng một AI skill
    • Developer có thể chạy /migrate-notif-fanout <notif_name> để tạo kết quả migration lần đầu
    • Công cụ này hiệu quả với các công việc lặp lại như tạo notification model, nối factory, sửa điểm gọi và áp dụng pattern nền tảng
  • AI có thể bỏ sót business logic tinh vi, gây hallucination hoặc tạo mã trùng lặp cần dọn dẹp, nên nó không thay thế phán đoán của kỹ sư
  • Họ đã migration hơn 200 thông báo, và nhờ hợp tác quy mô lớn bao gồm cả việc dùng AI, hoàn tất 80% còn lại chỉ trong 6 tuần

Cải thiện hiệu năng và tác động tới phát triển sản phẩm

  • Bằng cách chuyển việc tạo thông báo theo từng người nhận sang các tác vụ có thể mở rộng theo chiều ngang, họ có thể tạo ổn định hàng triệu thông báo cho mỗi creator mà không gặp timeout
  • Hiệu năng của các thông báo lưu lượng cao từ creator lớn được cải thiện đáng kể
    • Thông báo push và feed trong ứng dụng nhanh hơn 80%
    • Thông báo email nhanh hơn 55%
    • Khi lượng khán giả tăng gấp 4 lần, độ trễ đầu-cuối của push và feed trong ứng dụng tăng 33%, còn email tăng 60%
    • Trong cùng điều kiện, mức tăng độ trễ của nền tảng cũ là 186%
  • Các đội sản phẩm không còn cần thiết kế giải pháp mở rộng riêng cho từng thông báo lưu lượng cao, và tốc độ phát triển cũng được cải thiện
  • Nền tảng mới hỗ trợ các lần ra mắt lớn trong năm 2025 như Lives, Quips và việc thu hút các creator lớn
  • Nếu không có thiết kế lại fanout, các lần ra mắt này sẽ đụng phải nút thắt cũ và cần thêm thời gian kỹ thuật để tạo các giải pháp mở rộng một lần
  • Với metric timing theo từng giai đoạn, họ có thể xác định nơi thời gian bị tiêu tốn và điều chỉnh hạ tầng theo cân bằng giữa tốc độ và chi phí

9 tháng vận hành song song và phối hợp tổ chức

  • Phần khó nhất là thay đổi một hệ thống legacy đang vận hành trong khi điều phối migration giữa nhiều đội
  • Trong 9 tháng, họ vận hành song song hai hệ thống thông báo
    • Mọi thay đổi nền tảng đều phải tương thích với cả đường dẫn cũ lẫn đường dẫn fanout mới
    • Phạm vi có thể phát sinh bug và sự cố tăng lên, và migration càng kéo dài thì rủi ro vận hành càng lớn
    • Một vài sự cố nhỏ đã xảy ra do vấn đề tương thích, làm tăng nhu cầu hoàn tất migration nhanh chóng và an toàn
  • Ban đầu, họ chọn cách tiếp cận từ dưới lên, để mỗi đội sản phẩm tự ưu tiên migration thông báo của mình
    • Trong 6 tháng chỉ migration được khoảng 20%
    • Tiến độ chậm lại vì bị đẩy xuống sau roadmap sản phẩm và ưu tiên của các đội khác
  • Sau khi lãnh đạo kỹ thuật thống nhất hoàn tất trong quý 1 năm 2026 và đặt hạn chót rõ ràng cùng ưu tiên toàn công ty, phần migration còn lại được hoàn tất trong 6 tuần
  • Toàn bộ công việc có sự tham gia của 10 đội và hơn 30 kỹ sư
    • Quản lý tiến độ bằng tracker trên Notion và tự động hóa
    • Giao tiếp thường xuyên với các bên liên quan và phân tán công việc cho nhiều đội
    • Đội nền tảng thực hiện khoảng một nửa số migration, rồi bàn giao triển khai và dọn dẹp cho các đội sở hữu thông báo
    • Phân bổ tải để công việc không tập trung vào các đội có nhiều thông báo
  • Họ tổ chức tuần migration thông báo gồm office hours, leaderboard, phần thưởng và happy hour để tăng tốc tiến độ và ăn mừng hoàn thành
  • Họ dành được một khoảng đệm bằng cách hoàn tất bàn giao sớm hơn hạn chót tổng thể 2 tuần
    • Hỗ trợ các đội cần trợ giúp thêm và tìm kiếm các công việc bị bỏ sót trong codebase
    • Trong lần kiểm tra cuối, họ tìm thấy 4 migration mới cần làm và nhiều mục chưa hoàn tất, rồi kết thúc với tác động nhỏ tới lịch trình

Bài học từ migration nền tảng quy mô lớn

  • Nếu không có ưu tiên rõ ràng, migration trải rộng trên nhiều đội sẽ cạnh tranh với roadmap của từng đội và dễ bị đẩy xuống sau
    • Điều này đặc biệt nổi bật ở phần đuôi dài của các thông báo lưu lượng thấp, nơi hiệu quả mở rộng ít rõ ràng hơn
    • Sự thống nhất của lãnh đạo, ưu tiên chung và hạn chót rõ ràng là yếu tố quan trọng để hoàn tất migration trong khoảng thời gian hợp lý
  • Công việc nền tảng không kết thúc ở API

    • Trước đây, việc điều tra câu hỏi về thông báo và vấn đề phân phối của các đội khác chiếm phần đáng kể trong công việc on-call của kỹ sư nền tảng
    • Cần cải thiện đồng thời khả năng quan sát, cảnh báo, dashboard và công cụ debug để các đội sản phẩm và support có thể tự điều tra, đồng thời giảm gánh nặng on-call của nền tảng
    • Không chỉ cần cân nhắc nút thắt hiện tại mà cả nút thắt tiếp theo
    • Một dự án duy nhất không thể giải quyết mọi vấn đề mở rộng thông báo
    • Thiết kế để có thể tiếp nhận các tính năng tương lai giúp giảm khả năng phải thực hiện một lần refactor quy mô lớn khác khi lượng thông báo tăng

Nút thắt tiếp theo và kế hoạch tương lai

  • Việc tạo thông báo đã được mở rộng, nhưng nút thắt tiếp theo là tạo danh sách người nhận
  • Khi đối tượng nhận thông báo tiếp tục lớn hơn, việc truy vấn hiệu quả hàng triệu người nhận sẽ ngày càng quan trọng
  • Họ dự định đưa việc tạo danh sách người nhận vào Notification Factory để nền tảng đảm nhiệm nhiều hơn luồng thông báo đầu-cuối
  • Thiết lập thông báo cũng sẽ được cải thiện cho cả developer và fan
    • Hỗ trợ developer tạo và quản lý thiết lập mới dễ hơn
    • Cải thiện để fan dễ hiểu và kiểm soát tùy chọn thông báo của mình hơn

Chưa có bình luận nào.

Chưa có bình luận nào.