Tính sẵn sàng cao là phần trăm thời gian mà hệ thống đang làm việc và đáp ứng theo nhu cầu của doanh nghiệp. Đối với các hệ thống cơ sở dữ liệu sản xuất, ưu tiên cao nhất là giữ cho nó gần 100%. Chúng tôi xây dựng các cụm cơ sở dữ liệu để loại bỏ tất cả các điểm lỗi duy nhất. Nếu một phiên bản không khả dụng, một nút khác sẽ có thể nhận khối lượng công việc và tiếp tục từ đó. Trong một thế giới hoàn hảo, một cụm cơ sở dữ liệu sẽ giải quyết tất cả các vấn đề về tính khả dụng của hệ thống. Thật không may, trong khi tất cả có thể trông đẹp trên giấy, thực tế thường khác. Vậy nó có thể bị sai ở đâu?
Hệ thống cơ sở dữ liệu giao dịch đi kèm với các công cụ lưu trữ phức tạp. Giữ dữ liệu nhất quán trên nhiều nút làm cho nhiệm vụ này trở nên khó khăn hơn. Phân cụm giới thiệu một số biến mới phụ thuộc nhiều vào mạng và cơ sở hạ tầng bên dưới. Không có gì lạ khi một phiên bản cơ sở dữ liệu độc lập đang chạy tốt trên một nút đột nhiên hoạt động kém trong môi trường cụm.
Trong số những thứ có thể ảnh hưởng đến tính khả dụng của cụm, các vấn đề về độ trễ đóng một vai trò quan trọng. Tuy nhiên, độ trễ là gì? Nó chỉ liên quan đến mạng?
Thuật ngữ "độ trễ" thực sự đề cập đến một số loại độ trễ phát sinh trong quá trình xử lý dữ liệu. Mất bao lâu để một phần thông tin chuyển từ giai đoạn này sang giai đoạn khác.
Trong bài đăng trên blog này, chúng ta sẽ xem xét hai giải pháp tính khả dụng cao chính cho MySQL và MariaDB và cách chúng có thể bị ảnh hưởng bởi các vấn đề về độ trễ.
Ở cuối bài viết, chúng ta sẽ xem xét các công cụ cân bằng tải hiện đại và thảo luận cách chúng có thể giúp bạn giải quyết một số loại vấn đề về độ trễ.
Trong một bài báo trước, đồng nghiệp của tôi là Krzysztof Książek đã viết về "Đối phó với mạng không đáng tin cậy khi tạo giải pháp HA cho MySQL hoặc MariaDB". Bạn sẽ tìm thấy các mẹo có thể giúp bạn thiết kế kiến trúc HA sẵn sàng cho sản xuất của mình và tránh một số vấn đề được mô tả ở đây.
Bản sao Master-Slave để có tính khả dụng cao.
MySQL master-slave replication có lẽ là kiểu cụm cơ sở dữ liệu phổ biến nhất trên hành tinh. Một trong những điều chính bạn muốn theo dõi trong khi chạy cụm sao chép chủ-nô lệ của mình là độ trễ nô lệ. Tùy thuộc vào yêu cầu ứng dụng của bạn và cách bạn sử dụng cơ sở dữ liệu của mình, độ trễ sao chép (độ trễ nô lệ) có thể xác định xem dữ liệu có thể được đọc từ nút phụ hay không. Dữ liệu được cam kết trên máy chủ nhưng chưa có sẵn trên máy chủ không đồng bộ có nghĩa là máy chủ có trạng thái cũ hơn. Khi không thể đọc từ máy chủ, bạn cần phải chuyển đến máy chủ và điều đó có thể ảnh hưởng đến hiệu suất ứng dụng. Trong trường hợp xấu nhất, hệ thống của bạn sẽ không thể xử lý tất cả khối lượng công việc trên một bản chính.
Độ trễ và dữ liệu cũ của nô lệ
Để kiểm tra trạng thái của bản sao master-slave, bạn nên bắt đầu bằng lệnh dưới đây:
SHOW SLAVE STATUS\G
MariaDB [(none)]> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.0.3.100
Master_User: rpl_user
Master_Port: 3306
Connect_Retry: 10
Master_Log_File: binlog.000021
Read_Master_Log_Pos: 5101
Relay_Log_File: relay-bin.000002
Relay_Log_Pos: 809
Relay_Master_Log_File: binlog.000021
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 5101
Relay_Log_Space: 1101
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 3
Master_SSL_Crl:
Master_SSL_Crlpath:
Using_Gtid: Slave_Pos
Gtid_IO_Pos: 0-3-1179
Replicate_Do_Domain_Ids:
Replicate_Ignore_Domain_Ids:
Parallel_Mode: conservative
1 row in set (0.01 sec)
Sử dụng thông tin trên, bạn có thể xác định độ trễ sao chép tổng thể tốt như thế nào. Giá trị bạn thấy trong "Seconds_Behind_Master" càng thấp, thì tốc độ truyền dữ liệu để sao chép càng tốt.
Một cách khác để theo dõi độ trễ của nô lệ là sử dụng giám sát sao chép ClusterControl. Trong ảnh chụp màn hình này, chúng ta có thể thấy trạng thái sao chép của Cụm Master-Slave (2x) không đối xứng với ProxySQL.Có một số điều có thể ảnh hưởng đến thời gian sao chép. Rõ ràng nhất là thông lượng mạng và lượng dữ liệu bạn có thể truyền. MySQL đi kèm với nhiều tùy chọn cấu hình để tối ưu hóa quá trình sao chép. Các tham số thiết yếu liên quan đến sao chép là:
- Áp dụng song song
- Thuật toán đồng hồ lôgic
- Nén
- Sao chép master-slave có chọn lọc
- Chế độ sao chép
Áp dụng song song
Không có gì lạ khi bắt đầu điều chỉnh nhân rộng bằng cách cho phép áp dụng quy trình song song. Lý do cho điều đó là theo mặc định, MySQL đi kèm với áp dụng nhật ký nhị phân tuần tự và một máy chủ cơ sở dữ liệu điển hình đi kèm với một số CPU để sử dụng.
Để áp dụng nhật ký tuần tự, cả MariaDB và MySQL đều cung cấp bản sao song song. Việc triển khai có thể khác nhau tùy theo nhà cung cấp và phiên bản. Ví dụ. MySQL 5.6 cung cấp sao chép song song miễn là một lược đồ phân tách các truy vấn trong khi MariaDB (bắt đầu từ phiên bản 10.0) và MySQL 5.7 đều có thể xử lý sao chép song song giữa các lược đồ. Các nhà cung cấp và phiên bản khác nhau đi kèm với các giới hạn và tính năng của chúng, vì vậy hãy luôn kiểm tra tài liệu.
Việc thực thi các truy vấn thông qua các chuỗi nô lệ song song có thể tăng tốc luồng sao chép của bạn nếu bạn viết nhiều. Tuy nhiên, nếu bạn không làm vậy, tốt nhất là bạn nên sử dụng cách sao chép đơn luồng truyền thống. Để kích hoạt xử lý song song, hãy thay đổi slave_parallel_workers thành số luồng CPU bạn muốn tham gia vào quy trình. Bạn nên giữ giá trị thấp hơn số luồng CPU có sẵn.
Sao chép song song hoạt động tốt nhất với các cam kết của nhóm. Để kiểm tra xem bạn có cam kết nhóm đang xảy ra hay không, hãy chạy truy vấn sau.
show global status like 'binlog_%commits';
Tỷ lệ giữa hai giá trị này càng lớn càng tốt.
Đồng hồ lôgic
Slave_parallel_type =LOGICAL_CLOCK là một triển khai của thuật toán đồng hồ Lamport. Khi sử dụng nô lệ đa luồng, biến này chỉ định phương thức được sử dụng để quyết định giao dịch nào được phép thực hiện song song trên nô lệ. Biến không ảnh hưởng đến các nô lệ mà đa luồng không được bật vì vậy hãy đảm bảo slave_parallel_workers được đặt cao hơn 0.
Người dùng MariaDB cũng nên kiểm tra chế độ lạc quan được giới thiệu trong phiên bản 10.1.3 vì nó cũng có thể mang lại cho bạn kết quả tốt hơn.
GTID
MariaDB đi kèm với việc triển khai GTID của riêng nó. Trình tự của MariaDB bao gồm miền, máy chủ và giao dịch. Miền cho phép sao chép nhiều nguồn với ID riêng biệt. Các ID miền khác nhau có thể được sử dụng để sao chép phần dữ liệu không theo thứ tự (song song). Miễn là ứng dụng của bạn ổn, điều này có thể giảm độ trễ sao chép.
Kỹ thuật tương tự áp dụng cho MySQL 5.7 cũng có thể sử dụng kênh chủ đa nguồn và các kênh sao chép độc lập.
Nén
Nguồn CPU ngày càng ít tốn kém hơn theo thời gian, vì vậy sử dụng nó để nén binlog có thể là một lựa chọn tốt cho nhiều môi trường cơ sở dữ liệu. Tham số slave_compressed_protocol cho MySQL biết sử dụng tính năng nén nếu cả master và slave đều hỗ trợ nó. Theo mặc định, thông số này bị tắt.
Bắt đầu từ MariaDB 10.2.3, các sự kiện đã chọn trong nhật ký nhị phân có thể được nén tùy chọn để lưu chuyển mạng.
Định dạng sao chép
MySQL cung cấp một số chế độ sao chép. Chọn định dạng sao chép phù hợp giúp giảm thiểu thời gian truyền dữ liệu giữa các nút cụm.
Nhân rộng nhiều quản trị viên để có tính khả dụng cao
Một số ứng dụng không đủ khả năng hoạt động trên dữ liệu đã lỗi thời.
Trong những trường hợp như vậy, bạn có thể muốn thực thi tính nhất quán trên các nút bằng cách sao chép đồng bộ. Để giữ dữ liệu đồng bộ yêu cầu một plugin bổ sung và đối với một số người, giải pháp tốt nhất trên thị trường cho đó là Galera Cluster.
Galera cluster đi kèm với API wsrep chịu trách nhiệm truyền các giao dịch đến tất cả các nút và thực thi chúng theo thứ tự trên toàn cụm. Điều này sẽ chặn việc thực thi các truy vấn tiếp theo cho đến khi nút đã áp dụng tất cả các bộ ghi từ hàng đợi applier của nó. Mặc dù đây là một giải pháp tốt để đảm bảo tính nhất quán, nhưng bạn có thể gặp phải một số hạn chế về kiến trúc. Các vấn đề về độ trễ phổ biến có thể liên quan đến:
- Nút chậm nhất trong cụm
- Thao tác ghi và chia tỷ lệ theo chiều ngang
- Các cụm được định vị địa lý
- Ping cao
- Quy mô giao dịch
Nút chậm nhất trong cụm
Theo thiết kế, hiệu suất ghi của cụm không thể cao hơn hiệu suất của nút chậm nhất trong cụm. Bắt đầu xem xét cụm của bạn bằng cách kiểm tra tài nguyên máy và xác minh các tệp cấu hình để đảm bảo tất cả chúng đều chạy trên cùng một cài đặt hiệu suất.
Song song hóa
Các luồng song song không đảm bảo hiệu suất tốt hơn, nhưng nó có thể tăng tốc độ đồng bộ hóa của các nút mới với cụm. Trạng thái wsrep_cert_deps_distance cho chúng ta biết mức độ song song có thể có. Nó là giá trị của khoảng cách trung bình giữa các giá trị seqno cao nhất và thấp nhất có thể được áp dụng song song. Bạn có thể sử dụng biến trạng thái wsrep_cert_deps_distance để xác định số luồng phụ tối đa có thể.
Chia tỷ lệ theo chiều ngang
Bằng cách thêm nhiều nút hơn trong cụm, chúng tôi có ít điểm có thể bị lỗi hơn; tuy nhiên, thông tin cần phải trải qua nhiều trường hợp cho đến khi được cam kết, điều này sẽ nhân lên thời gian phản hồi. Nếu bạn cần ghi có thể mở rộng, hãy xem xét một kiến trúc dựa trên sharding. Một giải pháp tốt có thể là một công cụ lưu trữ Spider.
Trong một số trường hợp, để giảm thông tin được chia sẻ trên các nút cụm, bạn có thể cân nhắc sử dụng một người viết tại một thời điểm. Nó tương đối dễ thực hiện khi sử dụng bộ cân bằng tải. Khi bạn thực hiện việc này theo cách thủ công, hãy đảm bảo rằng bạn có quy trình để thay đổi giá trị DNS khi nút ghi của bạn gặp sự cố.
Các cụm được định vị địa lý
Mặc dù Galera Cluster là đồng bộ, có thể triển khai một Galera Cluster trên các trung tâm dữ liệu. Sao chép đồng bộ như MySQL Cluster (NDB) thực hiện cam kết hai giai đoạn, trong đó thông báo được gửi đến tất cả các nút trong một cụm trong giai đoạn 'chuẩn bị' và một tập hợp thông báo khác được gửi trong giai đoạn 'cam kết'. Cách tiếp cận này thường không phù hợp với các nút khác nhau về mặt địa lý, do độ trễ trong việc gửi thông báo giữa các nút.
Ping cao
Galera Cluster với cài đặt mặc định không xử lý tốt độ trễ mạng cao. Nếu bạn có mạng có nút hiển thị thời gian ping cao, hãy xem xét việc thay đổi các tham số evs.send_window và evs.user_send_window. Các biến này xác định số lượng gói dữ liệu tối đa trong bản sao tại một thời điểm. Đối với thiết lập WAN, biến có thể được đặt thành giá trị cao hơn đáng kể so với giá trị mặc định là 2. Thông thường, bạn nên đặt nó thành 512. Các tham số này là một phần của wsrep_provider_options.
--wsrep_provider_options="evs.send_window=512;evs.user_send_window=512"
Quy mô giao dịch
Một trong những điều bạn cần xem xét khi chạy Galera Cluster là quy mô của giao dịch. Tìm kiếm sự cân bằng giữa quy mô giao dịch, hiệu suất và quy trình chứng nhận Galera là điều bạn phải ước tính trong đơn đăng ký của mình. Bạn có thể tìm thêm thông tin về điều đó trong bài viết Cách cải thiện hiệu suất của Galera Cluster cho MySQL hoặc MariaDB của Ashraf Sharif.
Số liệu đọc về tính nhất quán của Bộ cân bằng tải
Ngay cả với rủi ro được giảm thiểu về các vấn đề độ trễ dữ liệu, sao chép không đồng bộ MySQL tiêu chuẩn vẫn không thể đảm bảo tính nhất quán. Vẫn có thể dữ liệu chưa được sao chép sang nô lệ trong khi ứng dụng của bạn đang đọc nó từ đó. Sao chép đồng bộ có thể giải quyết vấn đề này, nhưng nó có giới hạn về kiến trúc và có thể không phù hợp với các yêu cầu ứng dụng của bạn (ví dụ:ghi số lượng lớn chuyên sâu). Vậy khắc phục bằng cách nào?
Bước đầu tiên để tránh đọc dữ liệu cũ là làm cho ứng dụng biết về độ trễ sao chép. Nó thường được lập trình trong mã ứng dụng. May mắn thay, có những bộ cân bằng tải cơ sở dữ liệu hiện đại với sự hỗ trợ của định tuyến truy vấn thích ứng dựa trên theo dõi GTID. Phổ biến nhất là ProxySQL và Maxscale.
ProxySQL 2.0
ProxySQL Binlog Reader cho phép ProxySQL biết GTID nào đã được thực thi trên mọi máy chủ MySQL, nô lệ và chính trong thời gian thực. Nhờ đó, khi một máy khách thực hiện một lần đọc cần cung cấp các lần đọc nhất quán nhân quả, ProxySQL ngay lập tức biết truy vấn có thể được thực thi trên máy chủ nào. Nếu vì bất kỳ lý do gì mà việc ghi chưa được thực thi trên bất kỳ nô lệ nào, ProxySQL sẽ biết rằng trình ghi đã được thực thi trên bản chính và gửi bản đọc đến đó.
Maxscale 2.3
MariaDB đã giới thiệu các lần đọc thông thường trong Maxscale 2.3.0. Cách thức hoạt động của nó tương tự như ProxySQL 2.0. Về cơ bản, khi kích hoạt causal_reads, bất kỳ lần đọc nào tiếp theo được thực hiện trên các máy chủ phụ sẽ được thực hiện theo cách ngăn chặn độ trễ sao chép ảnh hưởng đến kết quả. Nếu máy chủ không theo kịp cái chính trong thời gian đã định cấu hình, thì truy vấn sẽ được thử lại trên cái chính.