1. Giới thiệu:

Replication là cơ chế sao chép tự động từ một server database gốc (gọi là Master) sang các server khác (gọi là Slave). Cơ chế này giúp cho người dùng dễ dàng duy trì nhiều bản sao của dữ liệu trên các máy khác nhau.

Mô hình triển khai sử dụng Replication thông thường sẽ gồm 1 Master và nhiều Slave. Trong đó các request ghi (write) được thực thi ở server Master, server Slave sẽ chỉ phục vụ các request đọc (read-only replica).

2. Cơ chế hoạt động:

Tại server Master, tất cả các tác động tới database sẽ được ghi vào file binary-log dưới dạng nhị phân, Slave sẽ đọc binary-log (bắt đầu từ vị trí đã được cấu hình trước), tạo ra relay-log và dựa vào đó thực hiện việc nhân bản, relay-log sẽ bị xoá bỏ sau khi quá trình này hoàn tất.

Mặc định Replication là quá trình bất đồng bộ (Asynchronous). Có nghĩa các thao tác trên CSDL Master sẽ không cần chờ xác nhận dữ liệu đã được sao chép sang CSLD Slave hay chưa, bản thân các Slave cũng không cần phải kết nối liên tục để nhận được dữ liệu từ Master.

Cơ chế bất đồng bộ này giúp cho request ghi diễn ra nhanh hơn do server Master chỉ chuyên phục vụ thao tác này. Tuy nhiên bạn có thể phải đối mặt với việc các dữ liệu mới nhất chưa kịp được sao chép sang các Slave, dẫn tới việc ứng dụng sẽ không nhận được dữ liệu mới nhất. Hiện tượng này gọi là Replication Lag, và chỉ số Seconds_Behind_Master cho ta biết dữ liệu trên Slave đang bị trễ bao nhiêu giây so với Master.

3. Cấu hình server Master-Slave:

Giả sử chúng ta có 2 máy chủ như sau:

Master: 192.168.10.1

Slave: 192.168.10.2

Cấu hình Mysql trên Master:

  • bind-address: địa chỉ IP của server hiện tại
  • server-id: định danh cho mỗi server
  • log_bin: vị trí của file binary-log, đây là dữ liệu mà Slave sẽ lấy về để thực hiện quá trình replication.

Khởi động lại dịch vụ Mysql:

Chúng ta sẽ cần tạo một user để server Slave có thể thực hiện được quá trình sao chép:

Như đã đề cập, Slave sẽ cần biết vị trí hay toạ độ trong file binary-log của Master. Để có được vị trí chính xác, bắt buộc phải lock toàn bộ các bảng và dump dữ liệu trước:

File Position
mysql-bin.000028 799
1 row in set (0.00 sec)


Cấu
hình Mysql trên Slave:

Tương tự như cấu hình cho Master, thay đổi địa chỉ IP và server-id cho máy Slave, vị trí của các file binary-log, relay-log có thể giữ mặc định:

Có thể sử dụng các lựa chọn filter database, table cần sao chép cho Slave:

REPLICATE_DO_DB
REPLICATE_IGNORE_DB
REPLICATE_DO_TABLE
REPLICATE_IGNORE_TABLE

Khởi động lại dịch vụ Mysql:

Khôi phục lại dữ liệu đã dump từ server Master.
Cấu hình Slave:

Xác nhận lại đã kết nối Slave – Master thành công hay chưa:

************************************ 1. row *****************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.10.1
Master_User: replication_user
Master_Log_File: mysql-bin.000028
Read_Master_Log_Pos: 799
Last_Errno: 0
Last_IO_Errno: 0
Last_SQL_Errno: 0
Seconds_Behind_Master: 0
4. Một số lưu ý:
  • Trong trường hợp server Master xảy ra lỗi ngừng hoạt động, hệ thống vẫn xuất hiện thời gian downtime. Do việc khởi động lại master hoặc đưa server slave lên làm master đều phải thực hiện thủ công. Tuy nhiên việc triển khai Master-Slave có thể giúp giảm thời gian downtime xuống thấp nhất có thể.
  • Cơ chế sao chép bất đồng bộ (asynchronous) có thể gây ra hiện tượng lag dữ liệu, có thể giải quyết vấn đề này bằng cách gửi các request đọc (read) đến server Master thay vì Slave, hoặc cấu hình sử dụng cơ chế semi-synchronous cũng có thể giúp giảm thời gian lag dữ liệu.
  • Chỉ nên thực hiện các request thay đổi trên server Master, Slave chỉ phục vụ việc đọc dữ liệu nhằm tránh xung đột dữ liệu trong quá trình replication sau đó.
  • Có thể cấu hình Replication theo mô hình Master-Master, khi đó ứng dụng có thể đọc/ghi trên cả 2 server thay vì chia chức năng như mô hình Master-Slave. Tuy vậy đây là mô hình không nên áp dụng:
    • Không đảm bảo tính nhất quán của dữ liệu.
    • Cơ chế sao chép vẫn là bất đồng bộ.
    • Việc khôi phục dịch vụ khi gặp lỗi cũng sẽ rất mất thời gian và công sức.
    • Cần tốn thêm tài nguyên cho Database Proxy.
  • Nên sử dụng cơ chế GTID (Global Transaction ID) thay cho Binlog thông thường. GTID cho phép người dùng bỏ qua việc cấu hình vị trí trên file binary-log, mọi thay đổi trên database sẽ phát sinh một ID, việc xác định lại thời điểm sao chép có thể được thực hiện tự động dựa vào ID này.

Cấu hình bằng cách thêm gtid_mode = ON, enforce-gtid-consistency = ON vào file cấu hình mysql, thay đổi lệnh tạo kết nối Master-Slave:

  • Mysql hỗ trợ 3 cấp filter cho quy trình sao chép: Binary log, Database, Table giúp chọn lọc đối tượng sẽ được sao chép. Tuy nhiên chỉ nên cấu hình filter cấp Database và Table trên server Slave nhằm giữ lại đầy đủ log thay đổi dữ liệu trên server Master.
  • Trong trường hợp server Master có nhiều hơn 1 database, hãy chú ý đến database mặc định khi tạo connection trên ứng dụng. Ví dụ nếu có 2 DB trên Master: DB1, DB2 và có cấu hình binlog_format=’statement’ hoặc ‘mixed’ and set –replicate-do-db=DB1 trên Slave, thì câu lệnh sau sẽ không cập nhật dữ liệu như mong muốn:

Muốn update được DB1.table1 này thì cần phải use DB1; update table1…

  • Cân nhắc việc sử dụng Mysql Cluster cho các bài toán scaleout, server backup cần nhanh chóng thay thế khi server chính ngừng hoạt động, ví dụ: Galera, Percona, DRBD… kết hợp với database load balance.

Phạm Duy Anh – FPT Telecom

Tin liên quan: