1 điểm bởi GN⁺ 2025-11-16 | 1 bình luận | Chia sẻ qua WhatsApp
  • Một trường hợp đã xác minh bằng thực nghiệm lỗi race condition xảy ra trong AWS Aurora RDS và nhận được xác nhận nguyên nhân từ AWS
  • Trong quá trình mở rộng hệ thống xử lý sự kiện, Hightouch phát hiện hiện tượng chuyển đổi write instance thất bại trong quá trình failover của Aurora
  • Kết quả phân tích log cho thấy hai instance đồng thời thực hiện tác vụ ghi, gây xung đột ở tầng lưu trữ và làm tiến trình bị kết thúc
  • AWS chính thức xác nhận nguyên nhân là do vấn đề xử lý tín hiệu nội bộ, khiến writer cũ chưa bị hạ cấp xong thì writer mới đã được nâng cấp
  • Trường hợp này nhấn mạnh tầm quan trọng của kiểm soát đồng thời trong các hệ thống phân tán quy mô lớnsự cần thiết của quy trình dừng ghi khi failover

Bối cảnh

  • Ngày 20 tháng 10 năm 2025, tại region AWS us-east-1 đã xảy ra sự cố do lỗi race condition trong hệ thống quản lý DNS
  • Vì điều này, backlog xử lý sự kiện của Hightouch tăng vọt và hệ thống chạm đến giới hạn
  • Để đảm bảo thông lượng, vào ngày 23 tháng 10 công ty đã tiến hành nâng cấp instance Aurora RDS, và trong quá trình đó phát hiện thêm một lỗi race condition mới

Kiến trúc hệ thống sự kiện của Hightouch

  • Hệ thống phụ trách thu thập và truyền sự kiện được cấu thành từ Kubernetes, Kafka, Postgres(Aurora)
  • Postgres được dùng như hàng đợi metadata theo lô, xử lý 500.000 sự kiện mỗi giây trong vòng 1 giây
  • Aurora PostgreSQL gồm instance chỉ ghi (primary), instance chỉ đọc (replica)tầng lưu trữ dùng chung

Kế hoạch nâng cấp

  • Thêm instance đọc → nâng cấp reader hiện có và gán mức ưu tiên failover → thực hiện failover → nâng cấp writer hiện có → gỡ reader tạm thời
  • Đây là quy trình được nêu trong tài liệu AWS và đã được kiểm chứng bằng kiểm thử tải trong môi trường staging

Thử nâng cấp và phát sinh vấn đề

  • Lúc 16:39 EDT ngày 23 tháng 10, sau khi chạy failover đã xuất hiện hiện tượng writer cũ quay trở lại làm primary
  • Cả hai lần thử đều cho cùng kết quả, và một số dịch vụ gặp lỗi không thể ghi (DatabaseError: cannot execute UPDATE in a read-only transaction)
  • Kết quả phân tích log xác nhận có log cho thấy hai instance đồng thời thực hiện tác vụ ghi rồi bị dừng do xung đột lưu trữ

Nguyên nhân của race condition

  • Trong quá trình failover của Aurora, race condition xảy ra giữa bước 3 (hạ cấp writer cũ) và bước 4 (nâng cấp writer mới)
  • Vì vậy, hai instance đồng thời có quyền ghi và xảy ra xung đột
  • Khi thử lại trong trạng thái đã loại bỏ write traffic, failover hoàn tất bình thường, qua đó giả thuyết race condition được chứng minh

Xác nhận và ứng phó từ AWS

  • Sau khi rà soát nội bộ, AWS xác nhận nguyên nhân là lỗi xử lý tín hiệu hạ cấp writer, không liên quan đến cấu hình hay mẫu traffic của Hightouch
  • Bản sửa lỗi đã nằm trong roadmap, và biện pháp tạm thời được khuyến nghị là dừng ghi trong lúc failover

Biện pháp cuối cùng

  • Hightouch đã hoàn tất nâng cấp cluster, đồng thời
    • bổ sung quy trình dừng ghi trước khi failover có chủ đích
    • tăng cường giám sát theo dõi thay đổi vai trò writer
    • cập nhật sổ tay vận hành (playbook)

Bài học chính

  1. Cần chuẩn bị phương án khôi phục cho các chuyển đổi trạng thái ngoài dự kiến trong quá trình migration
  2. Đảm bảo observability là chìa khóa để phát hiện vấn đề
  3. Tầm quan trọng của thiết kế giảm thiểu ảnh hưởng giữa các thành phần trong hệ thống phân tán
  4. Cần nhận thức được sự khác biệt giữa môi trường kiểm thử và môi trường production thực tế

Không có thêm thông tin trong bài gốc

1 bình luận

 
GN⁺ 2025-11-16
Ý kiến trên Hacker News
  • Đọc bài này thì có vẻ như trong lúc failover thủ công nếu ứng dụng vẫn cố duy trì lưu lượng ghi như bình thường thì sẽ luôn thất bại
    Nhưng điều đó lại làm nảy sinh vài câu hỏi. Tại sao những người dùng Aurora khác không phải lúc nào cũng gặp vấn đề này, liệu AWS có thể không biết hay không, và nếu biết thì tại sao lại không xử lý như một sự cố khẩn cấp cấp P0
    Có lẽ có những điều kiện tinh vi như trạng thái giao dịch đang chạy hoặc timeout đang tác động vào đây

    • Theo kinh nghiệm của tôi khi xử lý vấn đề tương tự trên Azure, nhiều người có gặp nhưng vì khởi động lại là xong nên thường bỏ qua. Rất khó tìm ra nguyên nhân gốc rễ, còn quá trình phân tích cùng vendor thì quá đau khổ nên đa số đành bỏ cuộc
    • Bên tôi cũng đã xác nhận cùng một vấn đề khi làm việc với AWS. Mẫu lưu lượng không có gì đặc biệt, và ở các region khác thì không tái hiện được. Nhiều khả năng đây là lỗi nền tảng trong cơ chế failover của Aurora
    • Trước đây tôi từng gặp một bug khiến SELECT ... FOR UPDATE âm thầm thất bại và transaction chuyển sang chế độ autocommit trong tổ hợp Python + MySQL. Không ai quan tâm nên tôi cứ nói một mình, rồi vài tháng sau có người khác liên hệ bảo họ cũng gặp đúng vấn đề đó. Cuối cùng nó cũng được sửa, nhưng lúc ấy tôi đã thôi theo dõi rồi
      Liên kết liên quan: câu hỏi trên Stack Overflow
    • AWS hầu như không công khai thông tin nội bộ. Họ không cho biết chi tiết vượt quá cấp API, nên tạo cảm giác những vấn đề như thế này bị xem là trường hợp hiếm rồi bỏ qua
    • Một phần vấn đề cũng có thể đến từ cách ứng dụng phản ứng với failover bị đảo ngược. Có vẻ cache bị hỏng nên nó tiếp tục cố ghi vào primary sai. Những lỗi kiểu này dù thỉnh thoảng có xảy ra, nhưng retry lại thì thành công nên người dùng không báo cho AWS, khiến AWS có thể không hề biết
  • Tôi đã nhiều lần thấy hành vi ngoài dự kiến trên Aurora PostgreSQL
    Đặc biệt là trong lúc Zero Downtime Patching (ZDP), trạng thái session bị giữ sai nên ngay cả truy vấn đơn giản cũng bị hủy nhanh hơn rất nhiều so với statement_timeout
    Tôi đoán là khi client reconnect, Aurora đã kế thừa nguyên trạng thái timer cũ của session trước đó nên query bị hủy ngay lập tức

  • Bên tôi cũng thực hiện failover định kỳ trong môi trường có lưu lượng ghi rất cao, nhưng đang vận hành ổn định bằng quy trình tự động với AWS JDBC wrapper

    • Trên thực tế, lớp storage của Aurora đã ngăn vi phạm ACID, tức là tính toàn vẹn dữ liệu vẫn được giữ nguyên
  • Người ta trả tiền là để tin rằng Aurora sẽ giữ được những bất biến cơ bản như thế này, nên việc xảy ra vấn đề như vậy khá bất ngờ

    • Nhưng bản thân lớp storage vẫn hoạt động đúng khi chặn ghi đồng thời
  • Nhìn vào log và phần giải thích từ AWS thì có vẻ giả thuyết của tác giả bài gốc là không đúng
    Có vẻ sau khi promotion thất bại, một tiến trình giám sát bên ngoài đã phát hiện trạng thái cluster không nhất quán và buộc dừng bằng kill -9. Các thông báo liên quan đến subsystem storage xuất hiện sau đó

  • Tôi muốn hỏi về so sánh hiệu năng giữa Aurora và RDS Postgres.
    Nếu không cần multi-AZ hay failover nhanh, liệu cấu hình gp3 64k IOPS trên RDS có cho hiệu năng tốt hơn không? Aurora có vẻ đặc biệt chậm ở insert và chi phí cao. Các benchmark cũng không nêu rõ cấu hình RDS nên khó tin tưởng

    • Bên tôi đã có hiệu năng tốt hơn và chi phí thấp hơn với Aurora PG 14 trong cấu hình 1 writer + 1~2 reader. Aurora có lợi ở chỗ tính phí storage theo cấp cluster chứ không theo từng instance.
      Ngoài ra cũng không cần tự provision IOPS và có khoảng 80k IOPS.
      Cách tính phí IO cũng có hai kiểu: pay-per-IO phù hợp với môi trường tải thấp, còn chế độ phí cố định phù hợp hơn với workload nhiều IO.
      Nhân tiện, Serverless gần như lúc nào cũng không kinh tế. Nó chỉ hữu ích khi có các đợt tăng tải ngắn
    • Nhóm tôi từng gặp chi phí I/O tăng vọt trên Aurora Postgres RDS. Chỉ vài fuzzy query mà hóa đơn hàng tháng đã vượt $3,000, trong khi lẽ ra phải dưới $100
    • Chúng tôi thất vọng với cả chi phí, hiệu năng và độ trễ của Aurora nên cuối cùng đã chuyển sang PostgreSQL on-premise
    • Với Aurora MySQL, nếu muốn đạt cùng mức IOPS trên RDS thì chi phí đắt hơn nhiều
    • Aurora không dùng EBS và không thể chọn loại storage hay độ trễ. Bạn chỉ có thể chọn cách tính phí IO
  • Điều này thể hiện rất rõ “mô hình khối Lego” mà các kỹ sư AWS hay nói đến
    Họ thiết kế lớp storage hoàn toàn độc lập, nên ngay cả khi dịch vụ ở tầng trên lỗi thì tính nhất quán dữ liệu vẫn được đảm bảo. Tôi nghĩ đây là một ví dụ hay về kỹ thuật của AWS

  • Tôi nghe nói AWS đã khuyến nghị rằng hãy dừng ghi trong lúc failover, nên muốn hỏi liệu có thể chia sẻ mã case liên quan hay không

    • Bên tôi cũng dùng Aurora MySQL nên muốn xác nhận liệu khuyến nghị này có áp dụng cho MySQL không
  • Thật mừng khi biết không chỉ mình tôi gặp vấn đề này

    • AWS Support ban đầu phản bác rằng đó là do replication lag, nhưng họ lại dựa trên metric cũ từ 24 giờ trước để kết luận. Tôi thật sự muốn biết chúng tôi đã gặp kiểu lỗi gì, và tại sao ở region khác lại không tái hiện được
  • Kiến trúc tách rời compute-storage của Aurora khá thú vị
    Hyperscale của MSSQL cũng có cấu trúc tương tự, và đó gần như là sản phẩm duy nhất trong các dịch vụ Azure mà tôi cảm thấy thực sự đáng để dùng thử