Sự không khớp về tính năng đã làm hỏng bộ nhớ đệm MySQL trong Cloudflare Hyperdrive như thế nào
Cloudflare đã khắc phục một lỗi hiếm gặp trong hỗ trợ MySQL của Hyperdrive, nơi các bộ nhớ đệm CDN dùng chung trả về kết quả trống do sự không khớp về tính năng giao thức giữa các nút.
Được dịch tự động từ bản gốc tiếng Anh.
Cloudflare đã thông báo phiên bản chính thức (general availability) cho hỗ trợ MySQL trong Hyperdrive, trình quản lý kết nối cơ sở dữ liệu (connection pooler) dành cho Workers. Bản phát hành này tiếp nối giai đoạn beta, trong đó các kỹ sư đã xác định và giải quyết một lỗi bộ nhớ đệm tinh vi khiến một số phản hồi truy vấn đôi khi trả về kết quả trống. Bản sửa lỗi này đảm bảo dịch vụ đáp ứng mục tiêu khả dụng 99,99% cho các khối lượng công việc MySQL.
Chuyện gì đã xảy ra
Hyperdrive ban đầu ra mắt với hỗ trợ Postgres, cho phép các Workers serverless chia sẻ các kết nối cơ sở dữ liệu đang hoạt động (warm connections) và lưu trữ kết quả truy vấn trên phạm vi toàn cầu. Khi hỗ trợ MySQL bước vào giai đoạn beta năm ngoái, nhóm đã đặt mục tiêu đạt được độ tin cậy tương đương với triển khai Postgres của họ. Trong giai đoạn thử nghiệm này, những khách hàng có khối lượng truy cập lớn báo cáo một tỷ lệ lỗi nhất quán nhưng hiếm gặp, trong đó các truy vấn trả về kết quả trống thay vì dữ liệu mong đợi. Vấn đề này xảy ra ở khoảng 0,001% yêu cầu, khiến nó khó tái hiện và truy vết.
Cuộc điều tra tiết lộ rằng vấn đề cụ thể nằm ở các instance Hyperdrive có bật bộ nhớ đệm. Các kỹ sư đã truy vết nguyên nhân đến cách Hyperdrive xử lý giao thức client/server của MySQL, đặc biệt liên quan đến thương lượng tính năng (capability negotiation). Khác với Postgres, MySQL sử dụng các cờ tính năng (capability flags) để xác định cách định dạng và kết thúc các tập kết quả. Sự không khớp giữa những gì driver của Worker mong đợi và những gì Hyperdrive lưu trữ trong bộ nhớ đệm dẫn đến các phản hồi bị hỏng hoặc không đọc được khi các nút chia sẻ bộ nhớ đệm.
Để đạt được phiên bản chính thức, nhóm đã triển khai hai mươi bản sửa lỗi, bao gồm các chỉnh sửa cho mã hóa bảng ký tự và hành vi đặt lại kết nối. Bản sửa lỗi quan trọng nhất giải quyết logic bộ nhớ đệm để đảm bảo tất cả các kết quả truy vấn được lưu trữ đều sử dụng một định dạng chuẩn (canonical format). Với những thay đổi này được triển khai, các lỗi phản hồi trống đã biến mất và dịch vụ đạt được các mục tiêu về độ tin cậy.
Cách thức hoạt động
Hyperdrive sử dụng kiến trúc tách biệt bao gồm một Nút Client và một Nút Endpoint. Nút Client chạy gần Worker, xử lý các yêu cầu cục bộ và bộ nhớ đệm, trong khi Nút Endpoint nằm gần cơ sở dữ liệu gốc hơn, quản lý pool kết nối. Cả hai nút đều tận dụng bộ nhớ đệm CDN cục bộ của Cloudflare. Khi Nút Client và Nút Endpoint cùng reside trong một trung tâm dữ liệu, chúng chia sẻ bộ nhớ đệm này để cải thiện hiệu suất bằng cách phục vụ các truy vấn lặp lại mà không cần chạm tới cơ sở dữ liệu.
Giao thức MySQL dựa vào thương lượng tính năng trong giai đoạn kết nối. Một tính năng quan trọng là CLIENT_DEPRECATE_EOF, thay đổi cách các tập kết quả được kết thúc. Các máy chủ hiện đại bỏ qua gói EOF sau các định nghĩa cột và thay thế EOF cuối cùng bằng một gói OK nếu tính năng này được thương lượng. Tuy nhiên, một số thư viện client, chẳng hạn như mysql2 cho Node.js, không hỗ trợ cờ này. Hyperdrive phải chuyển đổi phản hồi giữa định dạng của máy chủ gốc và định dạng mà Worker mong đợi.
Lỗi nảy sinh vì lớp bộ nhớ đệm giả định rằng nó có thể lưu trữ chính xác các byte gửi tới Worker. Nếu Nút Endpoint lưu trữ một phản hồi sử dụng các tính năng nội bộ của Hyperdrive, nhưng Nút Client lấy nó ra và gửi các byte thô đó tới một Worker mong đợi định dạng khác, Worker sẽ hiểu sai dữ liệu. Ngược lại, nếu Nút Client lưu trữ các byte đã được chuyển đổi, Nút Endpoint có thể lấy chúng và thất bại trong việc xử lý đúng cách. Bản sửa lỗi đảm bảo rằng chỉ một phiên bản chuẩn của phản hồi, được mã hóa với các tính năng của Hyperdrive, mới được ghi vào bộ nhớ đệm dùng chung.
Chi tiết chính
- Hyperdrive cho MySQL hiện đã có sẵn ở phiên bản chính thức, sau khi rời khỏi giai đoạn beta.
- Dịch vụ nhắm tới khả dụng 99,99% cho các kết nối client từ Workers.
- Một lỗi hiếm gặp khiến 0,001% các truy vấn được cache trả về kết quả trống hoặc treo.
- Vấn đề bắt nguồn từ việc xử lý không khớp tính năng
CLIENT_DEPRECATE_EOF. - Việc sửa lỗi đòi hỏi đảm bảo mã hóa byte chuẩn trong bộ nhớ đệm CDN dùng chung.
- Các bản sửa lỗi bổ sung giải quyết mã hóa
utf8mb4và các lần đặt lại trạng tháiCOM_RESET_CONNECTION.
Tại sao điều này quan trọng
Đối với các nhà phát triển xây dựng trên nền tảng serverless, quản lý kết nối cơ sở dữ liệu là một thách thức dai dẳng. Thiết lập các kết nối mới cho mỗi yêu cầu thêm độ trễ đáng kể và tiêu tốn tài nguyên. Các trình quản lý kết nối như Hyperdrive giảm thiểu điều này bằng cách giữ cho các kết nối luôn nóng, nhưng chúng giới thiệu sự phức tạp trong việc chuyển đổi giao thức. Hiểu cách các công cụ này xử lý giao thức truyền tải giúp các kỹ sư gỡ lỗi các vấn đề obscure xuất hiện khi trộn lẫn các thư viện client và phiên bản cơ sở dữ liệu khác nhau.
Sự cố này nhấn mạnh rủi ro của việc giả định sự đồng nhất giao thức giữa các hệ thống cơ sở dữ liệu khác nhau. Mặc dù Postgres và MySQL đều sử dụng SQL, các giao thức mạng cơ bản của chúng khác biệt đáng kể. Các kỹ sư tích hợp với hạ tầng đa giao thức phải nhận thức được rằng các lớp bộ nhớ đệm có thể cần chuẩn hóa định dạng dữ liệu để ngăn chặn sự mất đồng bộ. Bỏ qua những sắc thái này có thể dẫn đến các lỗi gián đoạn khó tái hiện trong môi trường phát triển cục bộ.
Hơn nữa, việc phụ thuộc vào các bộ nhớ đệm dùng chung trong các hệ thống phân tán đòi hỏi các đảm bảo nhất quán nghiêm ngặt. Khi nhiều thành phần đọc và ghi vào cùng một bộ nhớ đệm, chúng phải thống nhất về schema dữ liệu. Trong trường hợp này, việc thiếu một định dạng chuẩn có nghĩa là bộ nhớ đệm trở thành nguồn gây hỏng hóc thay vì cải thiện hiệu suất. Bài học này áp dụng rộng rãi cho bất kỳ hệ thống nào sử dụng bộ nhớ đệm trung gian cho việc chuyển đổi giao thức.
Bạn có thể làm gì
- Nâng cấp lên phiên bản chính thức của Hyperdrive cho MySQL để hưởng lợi từ các bản sửa lỗi ổn định.
- Xác minh rằng thư viện client MySQL của bạn hỗ trợ
utf8mb4để tránh các vấn đề mã hóa ký tự với emoji hoặc các ký tự đặc biệt. - Kiểm tra xem driver client của bạn có hỗ trợ
CLIENT_DEPRECATE_EOFhay không để hiểu cách các tập kết quả được kết thúc trong ứng dụng của bạn. - Giám sát ứng dụng của bạn để tìm các kết quả truy vấn trống gián đoạn nếu bạn đang sử dụng một driver MySQL tùy chỉnh hoặc cũ.
- Sử dụng CLI
wranglerđể tạo các instance Hyperdrive mới cho các cơ sở dữ liệu tương thích MySQL như PlanetScale. - Xem xét lại logic đặt lại kết nối của bạn để đảm bảo tính nhất quán.



