MariaDB
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> MariaDB

Xử lý khối lượng dữ liệu lớn với MySQL và MariaDB

Hầu hết các cơ sở dữ liệu phát triển về quy mô theo thời gian. Sự tăng trưởng không phải lúc nào cũng đủ nhanh để tác động đến hiệu suất của cơ sở dữ liệu, nhưng chắc chắn có những trường hợp điều đó xảy ra. Khi nó xảy ra, chúng tôi thường tự hỏi có thể làm gì để giảm tác động đó và làm thế nào chúng tôi có thể đảm bảo hoạt động cơ sở dữ liệu trơn tru khi xử lý dữ liệu trên quy mô lớn.

Trước hết, chúng ta hãy thử xác định “khối lượng dữ liệu lớn” nghĩa là gì? Đối với MySQL hoặc MariaDB, đó là InnoDB không nén. InnoDB hoạt động theo cách mà nó được hưởng lợi mạnh mẽ từ bộ nhớ có sẵn - chủ yếu là vùng đệm InnoDB. Miễn là dữ liệu phù hợp ở đó, quyền truy cập đĩa được giảm thiểu để xử lý chỉ ghi - các lần đọc được cung cấp ra khỏi bộ nhớ. Điều gì xảy ra khi dữ liệu vượt quá bộ nhớ? Ngày càng có nhiều dữ liệu phải được đọc từ đĩa khi có nhu cầu truy cập vào các hàng hiện không được lưu trong bộ nhớ đệm. Khi lượng dữ liệu tăng lên, khối lượng công việc chuyển từ ràng buộc CPU sang ràng buộc I / O. Điều đó có nghĩa là nút thắt cổ chai không còn là CPU (đó là trường hợp khi dữ liệu nằm gọn trong bộ nhớ - truy cập dữ liệu trong bộ nhớ nhanh, chuyển đổi và tổng hợp dữ liệu chậm hơn) mà đó là hệ thống con I / O (hoạt động của CPU trên dữ liệu là cách nhanh hơn so với truy cập dữ liệu từ đĩa.) Với việc tăng cường áp dụng flash, khối lượng công việc ràng buộc I / O không còn khủng khiếp như trước đây trong thời gian ổ đĩa quay (truy cập ngẫu nhiên nhanh hơn với SSD) nhưng hiệu suất vẫn còn đó .

Một điều khác mà chúng tôi phải ghi nhớ rằng chúng tôi thường chỉ quan tâm đến tập dữ liệu đang hoạt động. Chắc chắn, bạn có thể có hàng terabyte dữ liệu trong lược đồ của mình nhưng nếu bạn chỉ phải truy cập 5GB cuối cùng, đây thực sự là một tình huống khá tốt. Chắc chắn, nó vẫn đặt ra những thách thức về hoạt động, nhưng về mặt hiệu suất thì nó vẫn sẽ ổn.

Chúng ta hãy chỉ giả sử cho mục đích của blog này và đây không phải là một định nghĩa khoa học, rằng theo khối lượng dữ liệu lớn, chúng tôi muốn nói đến trường hợp kích thước dữ liệu đang hoạt động lớn hơn đáng kể kích thước của bộ nhớ. Nó có thể là 100GB khi bạn có bộ nhớ 2GB, nó có thể là 20TB khi bạn có bộ nhớ 200GB. Điểm mấu chốt là khối lượng công việc của bạn bị ràng buộc I / O nghiêm ngặt. Hãy cùng chúng tôi thảo luận về một số tùy chọn khả dụng cho MySQL và MariaDB.

Phân vùng

Cách tiếp cận lịch sử (nhưng hoàn toàn hợp lệ) để xử lý khối lượng lớn dữ liệu là thực hiện phân vùng. Ý tưởng đằng sau nó là chia bảng thành các phân vùng, sắp xếp một bảng con. Sự phân chia diễn ra theo các quy tắc do người dùng xác định. Hãy xem một số ví dụ (ví dụ SQL được lấy từ tài liệu MySQL 8.0)

MySQL 8.0 đi kèm với các kiểu phân vùng sau:

  • RANGE
  • DANH SÁCH
  • CỘT
  • HASH
  • KEY

Nó cũng có thể tạo tiêu đề con. Chúng tôi sẽ không viết lại tài liệu ở đây nhưng chúng tôi vẫn muốn cung cấp cho bạn một số thông tin chi tiết về cách phân vùng hoạt động. Để tạo phân vùng, bạn phải xác định khóa phân vùng. Nó có thể là một cột hoặc trong trường hợp RANGE hoặc LIST, nhiều cột sẽ được sử dụng để xác định cách dữ liệu sẽ được chia thành các phân vùng.

Phân vùng HASH yêu cầu người dùng xác định một cột, cột này sẽ được băm. Sau đó, dữ liệu sẽ được chia thành số lượng phân vùng do người dùng xác định dựa trên giá trị băm đó:

CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT,
    store_id INT
)
PARTITION BY HASH( YEAR(hired) )
PARTITIONS 4;

Trong trường hợp này, hàm băm sẽ được tạo dựa trên kết quả được tạo bởi hàm YEAR () trên cột "được thuê".

Việc phân vùng KEY cũng tương tự với ngoại lệ là người dùng xác định cột nào nên được băm và phần còn lại do MySQL xử lý.

Trong khi phân vùng HASH và KEY phân phối dữ liệu ngẫu nhiên trên số lượng phân vùng, RANGE và LIST cho phép người dùng quyết định phải làm gì. RANGE thường được sử dụng với thời gian hoặc ngày tháng:

CREATE TABLE quarterly_report_status (
    report_id INT NOT NULL,
    report_status VARCHAR(20) NOT NULL,
    report_updated TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)
PARTITION BY RANGE ( UNIX_TIMESTAMP(report_updated) ) (
    PARTITION p0 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-01-01 00:00:00') ),
    PARTITION p1 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-04-01 00:00:00') ),
    PARTITION p2 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-07-01 00:00:00') ),
    PARTITION p3 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-10-01 00:00:00') ),
    PARTITION p4 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-01-01 00:00:00') ),
    PARTITION p5 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-04-01 00:00:00') ),
    PARTITION p6 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-07-01 00:00:00') ),
    PARTITION p7 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-10-01 00:00:00') ),
    PARTITION p8 VALUES LESS THAN ( UNIX_TIMESTAMP('2010-01-01 00:00:00') ),
    PARTITION p9 VALUES LESS THAN (MAXVALUE)
);

Nó cũng có thể được sử dụng với các loại cột khác:

CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT NOT NULL,
    store_id INT NOT NULL
)
PARTITION BY RANGE (store_id) (
    PARTITION p0 VALUES LESS THAN (6),
    PARTITION p1 VALUES LESS THAN (11),
    PARTITION p2 VALUES LESS THAN (16),
    PARTITION p3 VALUES LESS THAN MAXVALUE
);

Phân vùng LIST hoạt động dựa trên danh sách các giá trị sắp xếp các hàng trên nhiều phân vùng:

CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT,
    store_id INT
)
PARTITION BY LIST(store_id) (
    PARTITION pNorth VALUES IN (3,5,6,9,17),
    PARTITION pEast VALUES IN (1,2,10,11,19,20),
    PARTITION pWest VALUES IN (4,12,13,14,18),
    PARTITION pCentral VALUES IN (7,8,15,16)
);

Bạn có thể hỏi điểm gì khi sử dụng phân vùng? Điểm chính là việc tra cứu nhanh hơn đáng kể so với bảng không phân vùng. Giả sử bạn muốn tìm kiếm các hàng được tạo trong một tháng nhất định. Nếu bạn có nhiều năm dữ liệu được lưu trữ trong bảng, đây sẽ là một thách thức - một chỉ mục sẽ phải được sử dụng và, như chúng ta biết, các chỉ mục giúp tìm các hàng nhưng việc truy cập các hàng đó sẽ dẫn đến một loạt các lần đọc ngẫu nhiên từ toàn bộ bảng. Nếu bạn có phân vùng được tạo trên cơ sở năm tháng, MySQL có thể chỉ đọc tất cả các hàng từ phân vùng cụ thể đó - không cần truy cập chỉ mục, không cần thực hiện đọc ngẫu nhiên:chỉ cần đọc tất cả dữ liệu từ phân vùng một cách tuần tự, và chúng tôi tất cả đã được thiết lập.

Các phân vùng cũng rất hữu ích trong việc giải quyết việc luân chuyển dữ liệu. Nếu MySQL có thể dễ dàng xác định các hàng để xóa và ánh xạ chúng vào một phân vùng duy nhất, thay vì chạy bảng XÓA TỪ ĐÂU…, bảng sẽ sử dụng chỉ mục để định vị các hàng, bạn có thể cắt bớt phân vùng. Điều này cực kỳ hữu ích với phân vùng RANGE - theo ví dụ trên, nếu chúng ta chỉ muốn giữ dữ liệu trong 2 năm, chúng ta có thể dễ dàng tạo cron job, nó sẽ loại bỏ phân vùng cũ và tạo một phân vùng trống mới cho tháng tới.

Nén InnoDB

Nếu chúng ta có một khối lượng lớn dữ liệu (không nhất thiết phải nghĩ đến cơ sở dữ liệu), điều đầu tiên xuất hiện trong đầu chúng ta là nén nó lại. Có rất nhiều công cụ cung cấp tùy chọn để nén các tệp của bạn, giảm đáng kể kích thước của chúng. InnoDB cũng có một tùy chọn cho điều đó - cả MySQL và MariaDB đều hỗ trợ nén InnoDB. Ưu điểm chính của việc sử dụng tính năng nén là giảm hoạt động I / O. Dữ liệu khi được nén sẽ nhỏ hơn do đó đọc và ghi nhanh hơn. Trang InnoDB điển hình có kích thước 16KB, đối với SSD thì đây là 4 thao tác I / O để đọc hoặc ghi (SSD thường sử dụng trang 4KB). Nếu chúng tôi cố gắng nén 16KB thành 4KB, chúng tôi chỉ giảm hoạt động I / O xuống bốn. Nó không thực sự giúp ích nhiều về tỷ lệ bộ dữ liệu trên bộ nhớ. Trên thực tế, nó thậm chí có thể làm cho nó tồi tệ hơn - MySQL, để hoạt động trên dữ liệu, phải giải nén trang. Tuy nhiên, nó đọc trang nén từ đĩa. Điều này dẫn đến vùng đệm InnoDB lưu trữ 4KB dữ liệu nén và 16KB dữ liệu không nén. Tất nhiên, có các thuật toán được áp dụng để xóa dữ liệu không cần thiết (trang không được nén sẽ bị xóa khi có thể, chỉ giữ một trang được nén trong bộ nhớ) nhưng bạn không thể mong đợi quá nhiều cải tiến trong lĩnh vực này.

Điều quan trọng cần ghi nhớ là cách nén hoạt động liên quan đến việc lưu trữ. Ngày nay, ổ đĩa trạng thái rắn là tiêu chuẩn cho các máy chủ cơ sở dữ liệu và chúng có một vài đặc điểm cụ thể. Họ nhanh chóng, họ không quan tâm nhiều đến việc lưu lượng truy cập là tuần tự hay ngẫu nhiên (mặc dù họ vẫn thích truy cập tuần tự hơn là ngẫu nhiên). Chúng đắt tiền đối với khối lượng lớn. Chúng bị “mòn” vì chúng có thể xử lý một số chu kỳ ghi hạn chế. Nén giúp ích đáng kể ở đây - bằng cách giảm kích thước của dữ liệu trên đĩa, chúng tôi giảm chi phí của lớp lưu trữ cho cơ sở dữ liệu. Bằng cách giảm kích thước dữ liệu chúng tôi ghi vào đĩa, chúng tôi tăng tuổi thọ của SSD.

Thật không may, ngay cả khi nén có ích, đối với khối lượng dữ liệu lớn hơn, nó vẫn có thể không đủ. Một bước khác là tìm kiếm thứ gì đó khác ngoài InnoDB.

MyRocks

MyRocks là một công cụ lưu trữ có sẵn cho MySQL và MariaDB dựa trên một khái niệm khác với InnoDB. Đồng nghiệp của tôi, Sebastian Insausti, có một blog rất hay về việc sử dụng MyRocks với MariaDB. Ý chính là, do thiết kế của nó (nó sử dụng Log Structured Merge, LSM), MyRocks về mặt nén tốt hơn đáng kể so với InnoDB (dựa trên cấu trúc B + Tree). MyRocks được thiết kế để xử lý lượng lớn dữ liệu và giảm số lần ghi. Nó bắt nguồn từ Facebook, nơi có khối lượng dữ liệu lớn và yêu cầu truy cập dữ liệu cao. Vì vậy, bộ lưu trữ SSD - vẫn còn, trên quy mô lớn như vậy, mọi lợi ích trong quá trình nén là rất lớn. MyRocks có thể cung cấp khả năng nén tốt hơn gấp đôi so với InnoDB (có nghĩa là bạn giảm số lượng máy chủ xuống hai). Nó cũng được thiết kế để giảm độ khuếch đại ghi (số lần ghi cần thiết để xử lý thay đổi nội dung hàng) - nó yêu cầu ghi ít hơn 10 lần so với InnoDB. Điều này rõ ràng làm giảm tải I / O nhưng quan trọng hơn là nó sẽ tăng tuổi thọ của SSD lên gấp 10 lần so với việc xử lý cùng một tải bằng InnoDB). Từ quan điểm hiệu suất, khối lượng dữ liệu càng nhỏ thì truy cập càng nhanh, do đó, các công cụ lưu trữ như vậy cũng có thể giúp lấy dữ liệu ra khỏi cơ sở dữ liệu nhanh hơn (mặc dù nó không phải là ưu tiên cao nhất khi thiết kế MyRocks).

Kho dữ liệu Columnar

Các tài nguyên liên quan ClusterControl Performance Management Hiểu tác động của độ trễ cao trong giải pháp MySQL và MariaDB có tính khả dụng cao Bảng lừa hiệu suất MySQL

Tại một số điểm, tất cả những gì chúng ta có thể làm là thừa nhận rằng chúng ta không thể xử lý khối lượng dữ liệu như vậy bằng MySQL. Chắc chắn, bạn có thể chia nhỏ nó, bạn có thể làm những điều khác nhau nhưng cuối cùng nó không còn ý nghĩa nữa. Đã đến lúc tìm kiếm các giải pháp bổ sung. Một trong số đó sẽ là sử dụng kho dữ liệu dạng cột - cơ sở dữ liệu, được thiết kế có tính đến phân tích dữ liệu lớn. Chắc chắn, chúng sẽ không giúp ích gì với loại lưu lượng truy cập OLTP nhưng phân tích ngày nay khá tiêu chuẩn vì các công ty cố gắng dựa trên dữ liệu và đưa ra quyết định dựa trên các con số chính xác, không phải dữ liệu ngẫu nhiên. Có rất nhiều kho dữ liệu dạng cột nhưng chúng tôi muốn đề cập ở đây hai trong số đó. MariaDB AX và ClickHouse. Chúng tôi có một số blog giải thích MariaDB AX là gì và cách sử dụng MariaDB AX. Điều quan trọng, MariaDB AX có thể được mở rộng dưới dạng một cụm, cải thiện hiệu suất. ClickHouse là một tùy chọn khác để chạy phân tích - ClickHouse có thể dễ dàng được định cấu hình để sao chép dữ liệu từ MySQL, như chúng ta đã thảo luận trong một trong các bài đăng trên blog của mình. Nó nhanh, miễn phí và nó cũng có thể được sử dụng để tạo một cụm và phân đoạn dữ liệu để có hiệu suất tốt hơn nữa.

Kết luận

Chúng tôi hy vọng rằng bài đăng trên blog này đã cung cấp cho bạn thông tin chi tiết về cách có thể xử lý khối lượng lớn dữ liệu trong MySQL hoặc MariaDB. May mắn thay, có một số tùy chọn theo ý của chúng tôi và cuối cùng, nếu chúng tôi không thể thực sự làm cho nó hoạt động, có những lựa chọn thay thế tốt.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Sử dụng MariaDB Flashback trên MySQL Server

  2. Cách UNHEX () hoạt động trong MariaDB

  3. 2 cách liệt kê tất cả các hàm trong MariaDB

  4. Khắc phục “ERROR 1250 (42000):Không thể sử dụng bảng‘… ’từ một trong các SELECT trong mệnh đề ORDER” trong MariaDB

  5. Cách hoạt động của QUARTER () trong MariaDB