Evaluating MySQL Parallel Replication Part 2: Slave Group Commit

Bài tóm tắt Booking.com 2015 3. Quy mô lớn Độ khó: Khó

Booking.com · 2015 · 3. Quy mô lớn · Độ khó: Khó — bài gốc

Phần 2 của series "Evaluating MySQL Parallel Replication" (Jean-François Gagné); phần trước: Booking.com 2015, phần tiếp: Booking.com 2015 → Booking.com 2016. Đọc qua trình duyệt (Medium chặn crawler); ghi chú bằng lời của wiki.

Bối cảnh

  • MariaDB 10.0 và MySQL 5.7 có tham số trì hoãn commit trên master để nhiều transaction vào chung một nhóm (binlog_commit_wait_count/binlog_commit_wait_usec ở MariaDB, binlog_group_commit_sync_delay/..._no_delay_count ở MySQL): nhóm lớn hơn thì slave chạy song song được nhiều hơn, đổi lại master chậm đi một chút.
  • Tác dụng phụ ở MariaDB: một slave bật parallel replication và các tham số trên, dù nhận luồng đơn luồng từ phía trên, vẫn group commit được. Transaction chạy tuần tự, nhưng T1 sẵn sàng commit thì chờ một chút, T2 chạy ở luồng khác; nếu T2 xong trước khi hết hạn chờ thì T1 và T2 commit chung, và nhóm có thể kéo dài thêm.
  • Nhóm dừng khi đủ số lượng, khi hết thời gian chờ, hoặc khi gặp phụ thuộc (transaction sau bị khoá của transaction đang chờ commit). Trường hợp thứ ba ở MariaDB 10.0.16 làm pipeline đứng tới hết thời gian chờ, nên phụ thuộc dày mà thời gian chờ lớn thì slave lại lag. (Bản 10.0.18 và 10.1.4 sửa bằng MDEV-7249: gặp phụ thuộc thì commit ngay.)

Bài toán ở Booking

  • Triển khai điển hình: master M, các slave trong cùng DC, và một intermediate master M1 ở DC xa cùng slave của nó. Để sống sót khi máy M1 hỏng, database của M1 nằm trên đĩa dùng chung (DRBD hoặc SAN/iSCSI), nên M1 phải bật độ bền cao (sync_binlog = 1, innodb_flush_log_at_trx_commit = 1).
  • Độ bền cao trên slave đơn luồng nghĩa là mỗi transaction cần sync binlog và sync redo log. Một lần sync tốn khoảng 1 ms (round-trip mạng tới đĩa), nên trần là khoảng 500 (hoặc 1000) transaction/giây. Các slave lá thì không bị vì đĩa cục bộ có write cache có pin trên RAID controller và có thể nới độ bền.
  • Hệ quả: M1 là nút thắt, và mỗi đợt ghi dồn trên M làm DC xa bị trễ replication.

Thử nghiệm

  • A là master production (MySQL 5.6) → B là intermediate master MariaDB 10.0.16 đơn luồng → C là slave MariaDB 10.0.16 bật binlog, log-slave-updates, độ bền cao, đĩa cục bộ có write cache.
  • Kịch bản theo thời gian: đơn luồng có write cache; bật slave group commit (20 luồng, nhóm tối đa 15, chờ 40 ms); tắt write cache (vẫn group commit); tắt group commit; bật lại write cache.
  • Kết quả trên 4 slave: có write cache thì đơn luồng vẫn theo kịp; bật group commit vẫn theo kịp (thời gian chờ không gây trễ); tắt write cache thì 3/4 slave vẫn theo kịp nhờ group commit; tắt group commit khi không có write cache thì năng lực xử lý giảm mạnh và slave tụt lại.
  • B chỉ cần vì ở 10.0.16 đường code parallel replication chỉ chạy khi master cũng là MariaDB 10.0.

Vì sao

  • Chi phí cố định của mỗi lần sync (round-trip tới storage) chia cho cả nhóm thay vì trả cho từng transaction: đây là gom lô để khấu hao chi phí bền.
  • Nhóm commit trên slave còn sinh thông tin song song cho tầng sau, là điểm xuất phát của phép đo ở phần 3.

Bài học cho SWE

  • Khi trần thông lượng là số lần fsync/giây trên storage chậm (đĩa mạng, không có write cache), tăng kích thước nhóm thường hiệu quả hơn tăng độ song song (Batching và khấu hao round-trip).
  • Chờ để gom có cái giá: gặp phụ thuộc mà vẫn chờ thì pipeline đứng; cơ chế gom phải biết thả sớm.
  • Đặt database trên đĩa dùng chung để chịu được hỏng máy (một dạng Tách compute khỏi storage) chuyển độ trễ đĩa vào đường commit; cần tính lại trần ghi khi làm vậy (Failover, replica và dự phòng dữ liệu).

Liên quan