0

Amazon Aurora MySQL Bài 14: Replication Lag trong Aurora Read Replicas thấp đến mức nào và tại sao?

Trong các hệ thống cơ sở dữ liệu quy mô lớn, việc sử dụng các nút đọc phụ (Read Replicas) để chia tải các câu lệnh SELECT là chiến lược sống còn. Tuy nhiên, một trong những cơn đau đầu kinh điển của Backend Engineer là hiện tượng Replication Lag (Độ trễ đồng bộ).

Bài viết này sẽ mổ xem Replication Lag trong Aurora MySQL thấp đến mức nào và kiến trúc nào đứng sau sự kỳ diệu đó.

1. Nỗi đau Replication Lag ở MySQL truyền thống (Monolithic)

Ở MySQL tiêu chuẩn (hoặc RDS MySQL chạy mô hình Master-Slave truyền thống), cơ chế đồng bộ hoạt động dựa trên Binlog (Binary Log):

  1. Master thực hiện câu lệnh ghi (INSERT/UPDATE), ghi vào ổ cứng cục bộ và ghi ra tệp Binlog.

  2. Tiến trình IO Thread của Slave kết nối sang Master để kéo (pull) tệp Binlog này qua mạng.

  3. Tiến trình SQL Thread trên Slave đọc tệp Binlog đó và thực hiện chạy lại (replay) từng câu lệnh SQL hoặc sự kiện thay đổi dữ liệu trên ổ cứng cục bộ của Slave.

Hệ quả:

  • Quá trình "kéo log qua mạng rồi chạy lại tuần tự" tạo ra độ trễ cực lớn. Khi hệ thống chịu tải ghi cao (Write-heavy), Replication Lag có thể kéo dài từ vài trăm mili-giây lên đến hàng chục phút, khiến người dùng vừa bấm "Đổi mật khẩu" xong tải lại trang thấy thông tin cũ mèm.

2. Trong Aurora MySQL, Replication Lag thấp đến mức nào?

  • Con số thực tế: Trong điều kiện vận hành bình thường của Aurora MySQL, Replication Lag giữa Writer và các Read Replicas thường chỉ dưới 10 mili-giây (< 10ms), thậm chí đo lường thực tế thường chỉ quanh quẩn ở mức 1-3ms.

  • Nó gần như đạt trạng thái Real-time (Thời gian thực) đối với các truy vấn đọc thông thường của ứng dụng.

3. Bí mật kiến trúc nào giúp Aurora triệt tiêu Replication Lag?

Aurora đạt được độ trễ thấp khủng khiếp này nhờ triệt tiêu hoàn toàn cơ chế Replay Binlog truyền thống bằng hai điểm cốt lõi sau:

a. Kiến trúc chia sẻ chung ổ đĩa (Shared Storage Architecture)

  • Ở MySQL truyền thống, Slave phải sở hữu một bản sao dữ liệu độc lập trên ổ đĩa của nó và tự mình ghi lại từ đầu.

  • Trong Aurora, tất cả các Read Replicas đều dùng chung một Aurora Storage Volume duy nhất với Writer. Các Reader không cần phải tự mình ghi lại dữ liệu xuống đĩa hay chạy lại câu lệnh SQL.

b. Truyền tải Log Record thay vì Replay SQL

  • Khi Writer thực hiện ghi, nó chỉ gửi các Log Record nhỏ gọn xuống tầng lưu trữ phân tán (như đã phân tích ở Bài 2).

  • Tầng lưu trữ phân tán tự xử lý việc áp dụng các log này để cập nhật các trang dữ liệu (data pages).

  • Các Read Replicas khi cần đọc dữ liệu sẽ đọc trực tiếp từ tầng storage chung đó (kết hợp với bộ nhớ đệm Buffer Pool của riêng từng Reader instance). Khi tầng storage có dữ liệu mới, các Reader sẽ tự động đồng bộ trạng thái trang nhớ mà không phải gánh vác các tác vụ tính toán nặng nhọc của việc "phát lại transaction".

4. Những yếu tố hiếm hoi nào vẫn có thể gây ra Lag trên Aurora Reader?

Mặc dù replication lag cực thấp, trong một số trường hợp đặc biệt, bạn vẫn có thể thấy chỉ số ReplicaLag trên CloudWatch tăng lên:

  • Writer thực hiện các câu lệnh DDL cực lớn: Ví dụ chạy lệnh ALTER TABLE thêm cột vào bảng có hàng trăm triệu dòng trên Writer. Khi cấu trúc bảng thay đổi ở tầng storage, các Reader sẽ cần một chút thời gian để làm mới metadata của chúng.

  • Reader bị nghẽn CPU/RAM (Resource Contention): Nếu bạn cấu hình Reader có cấu hình phần cứng quá nhỏ (db.r6g.large) nhưng lại ném vào đó một câu lệnh thống kê SELECT quét toàn bộ bảng không có index (Full Table Scan) tiêu tốn hết RAM và CPU, Reader đó sẽ bị chậm trong việc xử lý và hiển thị kết quả truy vấn, tạo ra hiện tượng "lag" về mặt cảm nhận của ứng dụng.

5. Góc nhìn vận hành cho Backend Engineer

  • Giải pháp cho bài toán Read-After-Write Consistency: Mặc dù lag dưới 10ms, trong các nghiệp vụ đặc thù (như vừa bấm nút "Đặt hàng thành công", chuyển hướng sang trang chi tiết đơn hàng), nếu hệ thống ngay lập tức điều hướng request Đọc sang Reader Endpoint, đôi khi xác suất 0.01% sẽ rơi vào khoảng trống mili-giây đó và gây ra lỗi "Không tìm thấy đơn hàng".

    • Cách giải quyết: Như đã đề cập ở Bài 10, hãy sử dụng tính năng Sticky Sessions ở tầng ứng dụng (như cấu hình 'sticky' => true trong Laravel) để trong cùng một phiên HTTP request của user vừa thực hiện hành động ghi, các câu lệnh đọc ngay sau đó sẽ được giữ lại đọc từ Writer, triệt tiêu hoàn toàn lỗi lệch pha hiển thị.

All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí