Xử lý các giao dịch lớn luôn là một điểm khó khăn trong Galera Cluster. Cách thức hoạt động của chứng nhận bộ viết Galera gây ra sự cố khi các giao dịch kéo dài hoặc khi một hàng đơn lẻ đang được sửa đổi thường xuyên trên nhiều nút. Do đó, các giao dịch phải được khôi phục và thử lại khiến hiệu suất giảm xuống. May mắn thay, vấn đề này đã được giải quyết trong Galera 4, một phiên bản mới của Galera từ Codership. Thư viện này được sử dụng trong MariaDB 10.4, vì vậy cài đặt MariaDB 10.4 là cách dễ nhất để kiểm tra các tính năng mới được giới thiệu. Trong bài đăng trên blog này, chúng ta sẽ xem xét cách nhân rộng luồng có thể được sử dụng để giảm thiểu các vấn đề từng là vấn đề tiêu chuẩn trong các phiên bản Galera trước đây.
Chúng tôi sẽ sử dụng ba nút của cụm MariaDB Galera phiên bản 10.4.6, đi kèm với phiên bản Galera 26.4.2.
MariaDB [(none)]> show global status like 'wsrep_provider%';
+-----------------------------+------------------------------------------------------------------------------------------------------------------------------------------------+
| Variable_name | Value |
+-----------------------------+------------------------------------------------------------------------------------------------------------------------------------------------+
| wsrep_provider_capabilities | :MULTI_MASTER:CERTIFICATION:PARALLEL_APPLYING:TRX_REPLAY:ISOLATION:PAUSE:CAUSAL_READS:INCREMENTAL_WRITESET:UNORDERED:PREORDERED:STREAMING:NBO: |
| wsrep_provider_name | Galera |
| wsrep_provider_vendor | Codership Oy <[email protected]> |
| wsrep_provider_version | 26.4.2(r4498) |
+-----------------------------+------------------------------------------------------------------------------------------------------------------------------------------------+
4 rows in set (0.001 sec)
Có ba điểm khó khăn chính mà sao chép trực tuyến nhằm giải quyết:
- Giao dịch dài
- Các giao dịch lớn
- Điểm nổi bật trong bảng
Chúng ta hãy xem xét từng vấn đề một và xem cách nhân rộng phát trực tuyến có thể giúp chúng tôi giải quyết chúng như thế nào nhưng trước tiên hãy tập trung vào chứng nhận tập viết - nguyên nhân gốc rễ của những vấn đề đó.
Chứng nhận Writeset trong Galera Cluster
Cụm Galera bao gồm nhiều nút có thể ghi. Mỗi giao dịch được thực hiện trên cụm Galera tạo thành một bộ ghi. Mỗi bộ ghi phải được gửi đến tất cả các nút trong cụm để được chứng nhận - một quá trình đảm bảo rằng tất cả các nút có thể áp dụng giao dịch nhất định. Các bản ghi phải được thực thi trên tất cả các nút cụm nên nếu có bất kỳ xung đột nào, giao dịch không thể được thực hiện. Những lý do điển hình khiến giao dịch không thể được cam kết là gì? Chà, ba điểm chúng tôi đã liệt kê trước đó:
- Các giao dịch dài - giao dịch diễn ra lâu hơn, nhiều khả năng là trong thời gian chờ đợi, một nút khác sẽ thực hiện các cập nhật mà cuối cùng sẽ xung đột với bộ ghi và ngăn nó vượt qua chứng nhận
- Các giao dịch lớn - trước hết, các giao dịch lớn cũng dài hơn các giao dịch nhỏ, do đó gây ra vấn đề đầu tiên. Vấn đề thứ hai, liên quan chặt chẽ đến các giao dịch lớn, là khối lượng thay đổi. Nhiều hàng sẽ được cập nhật, nhiều khả năng một số dòng ghi trên một nút khác sẽ dẫn đến xung đột và toàn bộ giao dịch sẽ phải được khôi phục lại.
- Các điểm nóng trong bảng - nhiều khả năng hàng nhất định sẽ được cập nhật, nhiều khả năng quá trình cập nhật như vậy sẽ xảy ra đồng thời trên nhiều nút, dẫn đến một số giao dịch được khôi phục lại
Vấn đề chính ở đây là Galera không giới thiệu bất kỳ khóa nào trên các nút khác với nút ban đầu, nơi giao dịch được mở trên đó. Quá trình chứng nhận dựa trên hy vọng rằng nếu một nút có thể thực hiện một giao dịch, thì những nút khác cũng có thể thực hiện điều đó. Đúng là như vậy, nhưng như chúng ta đã thảo luận, có những trường hợp góc trong đó xác suất xảy ra điều này giảm đáng kể.
Trong Galera 4, với tính năng sao chép luồng, hành vi đã thay đổi và tất cả các khóa đang được thực hiện trong tất cả các nút. Các giao dịch sẽ được chia thành nhiều phần và mỗi phần sẽ được chứng nhận trên tất cả các nút. Sau khi chứng nhận thành công các hàng sẽ bị khóa trên tất cả các nút trong cụm. Có một số biến chi phối cách thực hiện chính xác việc này - wsrep_trx_fragment_size và wsrep_trx_fragment_unit xác định kích thước của phân mảnh và cách nó được định nghĩa. Đây là điều khiển rất chi tiết:bạn có thể xác định đơn vị phân mảnh dưới dạng byte, câu lệnh hoặc hàng để có thể chạy chứng nhận cho mọi hàng được sửa đổi trong giao dịch. Hãy xem cách bạn có thể hưởng lợi từ việc nhân rộng phát trực tuyến trong cuộc sống thực.
Làm việc với Sao chép Truyền trực tuyến
Hãy xem xét tình huống sau. Chúng tôi có một giao dịch để chạy mất ít nhất 30 giây:
BEGIN; UPDATE sbtest.sbtest1 SET k = k - 2 WHERE id < 2000 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 2000 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 2000 ; SELECT SLEEP(30); COMMIT;
Sau đó, trong khi nó đang chạy, chúng tôi sẽ thực thi SQL chạm vào các hàng tương tự. Điều này sẽ được thực thi trên một nút khác:
BEGIN; UPDATE sbtest.sbtest1 SET k = k - 1 WHERE id < 20 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 20 ; COMMIT;
Kết quả sẽ là gì?
Giao dịch đầu tiên được khôi phục ngay sau khi giao dịch thứ hai được thực hiện:
MariaDB [sbtest]> BEGIN; UPDATE sbtest.sbtest1 SET k = k - 2 WHERE id < 2000 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 2000 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 2000 ; SELECT SLEEP(30); COMMIT;
Query OK, 0 rows affected (0.001 sec)
Query OK, 667 rows affected (0.020 sec)
Rows matched: 667 Changed: 667 Warnings: 0
Query OK, 667 rows affected (0.010 sec)
Rows matched: 667 Changed: 667 Warnings: 0
Query OK, 667 rows affected (0.009 sec)
Rows matched: 667 Changed: 667 Warnings: 0
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
Query OK, 0 rows affected (0.001 sec)
Giao dịch trên nút thứ hai đã thành công:
MariaDB [(none)]> BEGIN; UPDATE sbtest.sbtest1 SET k = k - 1 WHERE id < 20 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 20 ; COMMIT;
Query OK, 0 rows affected (0.000 sec)
Query OK, 7 rows affected (0.002 sec)
Rows matched: 7 Changed: 7 Warnings: 0
Query OK, 7 rows affected (0.001 sec)
Rows matched: 7 Changed: 7 Warnings: 0
Query OK, 0 rows affected (0.004 sec)
Những gì chúng ta có thể làm để tránh nó là sử dụng tính năng sao chép trực tuyến cho giao dịch đầu tiên. Chúng tôi sẽ yêu cầu Galera xác nhận mọi thay đổi hàng:
MariaDB [sbtest]> BEGIN; SET SESSION wsrep_trx_fragment_size=1 ; SET SESSION wsrep_trx_fragment_unit='rows' ; UPDATE sbtest.sbtest1 SET k = k - 2 WHERE id < 2000 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 2000 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 2000 ; SELECT SLEEP(30); COMMIT; SET SESSION wsrep_trx_fragment_size=0;
Query OK, 0 rows affected (0.001 sec)
Query OK, 0 rows affected (0.000 sec)
Query OK, 0 rows affected (0.000 sec)
Query OK, 667 rows affected (1.757 sec)
Rows matched: 667 Changed: 667 Warnings: 0
Query OK, 667 rows affected (1.708 sec)
Rows matched: 667 Changed: 667 Warnings: 0
Query OK, 667 rows affected (1.685 sec)
Rows matched: 667 Changed: 667 Warnings: 0
Như bạn có thể thấy, lần này nó hoạt động tốt. Trên nút thứ hai:
MariaDB [(none)]> BEGIN; UPDATE sbtest.sbtest1 SET k = k - 1 WHERE id < 20 ; UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id < 20 ; COMMIT;
Query OK, 0 rows affected (0.000 sec)
Query OK, 7 rows affected (33.942 sec)
Rows matched: 7 Changed: 7 Warnings: 0
Query OK, 7 rows affected (0.001 sec)
Rows matched: 7 Changed: 7 Warnings: 0
Query OK, 0 rows affected (0.026 sec)
Điều thú vị là bạn có thể thấy rằng CẬP NHẬT mất gần 34 giây để thực hiện - điều này là do thực tế là giao dịch ban đầu, thông qua bản sao truyền trực tuyến, đã khóa tất cả các hàng đã sửa đổi trên tất cả các nút và giao dịch thứ hai của chúng tôi phải chờ giao dịch đầu tiên hoàn thành mặc dù cả hai giao dịch đều được thực hiện trên các nút khác nhau.
Về cơ bản đây là nó khi nói đến nhân rộng phát trực tuyến. Tùy thuộc vào yêu cầu và lưu lượng truy cập, bạn có thể sử dụng nó theo cách ít nghiêm ngặt hơn - chúng tôi đã chứng nhận mọi hàng nhưng bạn có thể thay đổi điều đó thành mọi hàng thứ n hoặc mọi câu lệnh. Bạn thậm chí có thể quyết định khối lượng dữ liệu để chứng nhận. Điều này phải đủ để phù hợp với các yêu cầu của môi trường của bạn.
Có một số điều nữa chúng tôi muốn bạn ghi nhớ và ghi nhớ. Trước hết, sao chép trực tuyến hoàn toàn không phải là một giải pháp nên được sử dụng theo mặc định. Đây là lý do tại sao nó, theo mặc định, bị vô hiệu hóa. Trường hợp sử dụng được đề xuất là quyết định thủ công các giao dịch sẽ được hưởng lợi từ việc nhân rộng luồng và kích hoạt nó ở cấp phiên. Đây là lý do tại sao các ví dụ của chúng tôi kết thúc bằng:
SET SESSION wsrep_trx_fragment_size=0;
Câu lệnh này (đặt wsrep_trx_fragment_size thành 0) vô hiệu hóa tính năng sao chép trực tuyến cho phiên hiện tại.
Một điều đáng ghi nhớ khác - nếu bạn tình cờ sử dụng sao chép trực tuyến, nó sẽ sử dụng bảng ‘wsrep_streaming_log’ trong lược đồ ‘mysql’ để lưu trữ liên tục dữ liệu đang truyền trực tuyến. Sử dụng bảng này, bạn có thể có một số ý tưởng về dữ liệu đang được chuyển qua cụm bằng cách sử dụng sao chép trực tuyến.
Cuối cùng là màn trình diễn. Đây cũng là một trong những lý do tại sao bạn không muốn sử dụng tính năng sao chép phát trực tuyến mọi lúc. Lý do chính cho điều đó là khóa - với sao chép trực tuyến, bạn phải có được các khóa hàng trên tất cả các nút. Điều này cần thời gian để có được các khóa và, nếu bạn phải khôi phục giao dịch, nó cũng sẽ gây áp lực lên tất cả các nút để thực hiện khôi phục. Chúng tôi đã chạy một bài kiểm tra rất nhanh về tác động hiệu suất mà bản sao phát trực tuyến có. Môi trường hoàn toàn là một thử nghiệm, vì vậy đừng cho rằng những kết quả đó giống nhau trên phần cứng cấp sản xuất, bạn nên xem tác động có thể là gì.
Chúng tôi đã thử nghiệm bốn tình huống:
- Đường cơ sở, đặt wsrep_trx_fragment_size =0 toàn cầu;
- set global wsrep_trx_fragment_unit ='row'; đặt toàn cầu wsrep_trx_fragment_size =1;
- set global wsrep_trx_fragment_unit ='statement'; đặt toàn cầu wsrep_trx_fragment_size =1;
- set global wsrep_trx_fragment_unit ='statement'; đặt toàn cầu wsrep_trx_fragment_size =5;
Chúng tôi đã sử dụng thử nghiệm r / w sysbench:
sysbench /root/sysbench/src/lua/oltp_read_write.lua --threads=4 --events=0 --time=300 --mysql-host=10.0.0.141 --mysql-user=sbtest --mysql-password=sbtest --mysql-port=3306 --tables=32 --report-interval=1 --skip-trx=off --table-size=100000 --db-ps-mode=disable run
Kết quả là:
- Giao dịch:82,91 mỗi giây, truy vấn:1658,27 mỗi giây. (100%)
- Giao dịch:54,72 mỗi giây, truy vấn:1094,43 mỗi giây. (66%)
- Giao dịch:54,76 mỗi giây, truy vấn:1095,18 mỗi giây. (66%)
- Giao dịch:70,93 mỗi giây, truy vấn:1418,55 mỗi giây. (86%)
Như bạn có thể thấy, tác động là đáng kể, hiệu suất giảm thậm chí 33%.
Chúng tôi hy vọng bạn thấy bài đăng trên blog này có nhiều thông tin và nó cung cấp cho bạn một số thông tin chi tiết về bản sao phát trực tuyến đi kèm với Galera 4 và MariaDB 10.4. Chúng tôi đã cố gắng đề cập đến các trường hợp sử dụng và các nhược điểm tiềm ẩn liên quan đến công nghệ mới này.