Về hiệu suất cơ sở dữ liệu đơn luồng so với đa luồng


58

H2 là một cơ sở dữ liệu luồng đơn có danh tiếng tốt về hiệu suất. Các cơ sở dữ liệu khác là đa luồng.

Câu hỏi của tôi là: khi nào một cơ sở dữ liệu đa luồng trở nên thú vị hơn một cơ sở dữ liệu luồng đơn? Có bao nhiêu người dùng? Có bao nhiêu quy trình? Kích hoạt là gì? Bất cứ ai cũng có kinh nghiệm để chia sẻ?

Tóm lược

  • Nút cổ chai thông thường là truy cập đĩa
  • SSD là nhanh, nhưng dễ vỡ (thủ tục thất bại là phải)
  • Một truy vấn dài trên một hệ thống luồng đơn sẽ chặn tất cả các truy vấn khác
  • Cấu hình hệ thống đa luồng có thể khó
  • Cơ sở dữ liệu đa luồng có lợi ngay cả trên các hệ thống lõi đơn

Chủ đề có nghĩa là "luồng hoặc quá trình" cho mục đích của câu hỏi này theo như tôi có thể nói - ví dụ: postgres không phải là đa luồng nhưng câu hỏi không cố gắng so sánh (H2, postgres) với (Oracle, SQL Server, v.v.)
Jack Douglas

Câu trả lời:


31

Đây là ý kiến ​​của tôi:

Thông thường nút cổ chai (hoặc phần chậm nhất) của hệ thống DB là đĩa. CPU chỉ tăng đột biến trong các hoạt động số học, xử lý hoặc bất kỳ tác vụ nào khác mà CPU thực hiện. Với kiến ​​trúc phù hợp, đa luồng có thể giúp bù đắp tải của truy vấn lên CPU thay vì đọc / ghi đĩa chậm. Có những trường hợp nhanh hơn để tính giá trị bằng cách sử dụng các chu kỳ CPU thay vì tạo cột được tính toán (đã được lưu trước đó vào đĩa) và đọc cột này từ đĩa.

Trong một số RDBMS, có một DB (tempdb) tạm thời được sử dụng bởi tất cả các DB trong trường hợp đó để sắp xếp, băm, các biến tạm thời, v.v ... Có thể sử dụng đa luồng và tách các tệp tempdb này để cải thiện thông lượng của tempdb , do đó cải thiện hiệu suất máy chủ tổng thể.

Sử dụng đa luồng (song song), tập hợp kết quả của một truy vấn có thể được tách ra để được xử lý trên các lõi khác nhau của máy chủ, thay vì chỉ sử dụng một lõi. Tính năng này không phải lúc nào cũng cải thiện hiệu suất, nhưng có những trường hợp nó hoạt động, và do đó tính năng này có sẵn.

Các luồng có sẵn cho DB được sử dụng cho nhiều mục đích: đọc / ghi vào đĩa, kết nối người dùng, công việc nền, khóa / chốt, IO mạng, v.v ... Tùy thuộc vào kiến ​​trúc hệ điều hành, các luồng được cung cấp trước cho CPU và quản lý bằng cách sử dụng chờ đợi và hàng đợi. Nếu CPU có thể xử lý các luồng này khá nhanh thì thời gian chờ sẽ thấp. DB đa luồng sẽ nhanh hơn DB đơn luồng, vì trong DB đơn luồng sẽ có chi phí tái chế chỉ một luồng thay vì có sẵn các rãnh khác.

Khả năng mở rộng cũng trở thành một vấn đề, vì sẽ cần nhiều luồng hơn để quản lý và thực thi hệ thống DB được chia tỷ lệ.


Cảm ơn vì sự sáng suốt. Tôi nghe mọi người ca ngợi ổ đĩa trạng thái rắn. Tôi đoán đầu tư vào đó có lẽ là điều tốt nhất để làm sau khi đảm bảo các truy vấn được viết tốt và ứng dụng được song song hợp lý.
Jérôme Verstrynge

@Stan - Tôi nghĩ multithreadedtrong bối cảnh này có nghĩa là một cái gì đó khác nhau , tức là tất cả các giao dịch được tuần tự hóa như Luke đề cập trong câu trả lời của mình.
Jack Douglas

@JVerstry ~ Không, không thực sự. Hãy đọc suy nghĩ của Jeff Atwood về SSD ... chúng có tỷ lệ thất bại cao. Điều tốt nhất để làm là lập chỉ mục dữ liệu đúng và có các truy vấn được viết tốt.
jcolebrand

@jcolebrand Ok, anh ta dường như chỉ ủng hộ họ vì tốc độ chỉ với một hệ thống dự phòng mạnh mẽ khi họ thất bại
Jérôme Verstrynge

2
@Jverstry ~ Vâng, và nếu bạn hiểu khái niệm đó, và đồng ý với nó, và đừng bận tâm đến việc xây dựng lại toàn bộ môi trường sản xuất của bạn (hoặc chờ một chuyển đổi dự phòng tự động khởi động và sau đó xây dựng lại vào một thời điểm nào đó trong tương lai gần) đi cho nó, họ sẽ làm mọi thứ nhanh hơn, vâng.
jcolebrand

47

Nếu có một điều tôi có thể nói về MySQL là InnoDB, công cụ lưu trữ giao dịch (tuân thủ ACID) của nó, thực sự là đa luồng. Tuy nhiên, nó cũng đa luồng như BẠN CẤU HÌNH NÓ !!! Ngay cả khi "ra khỏi hộp", InnoDB hoạt động rất tốt trong một môi trường CPU duy nhất với các cài đặt mặc định. Để tận dụng khả năng đa luồng của InnoDB, bạn phải nhớ kích hoạt rất nhiều tùy chọn.

innodb_thread_concurrency đặt giới hạn trên cho số lượng luồng đồng thời mà InnoDB có thể giữ mở. Số vòng tốt nhất để đặt cho điều này là (2 X Số lượng CPU) + Số lượng đĩa. CẬP NHẬT : Khi tôi đã học trực tiếp từ Hội nghị Percona NYC, bạn nên đặt giá trị này thành 0 để cảnh báo InnoDB Storage Engine để tìm số luồng tốt nhất cho môi trường mà nó đang chạy.

innodb_concurrency_tickets đặt số lượng chủ đề có thể bỏ qua việc kiểm tra đồng thời mà không bị trừng phạt. Sau khi đạt đến giới hạn đó, kiểm tra đồng thời luồng trở lại định mức.

innodb_commit_concurrency đặt số lượng giao dịch đồng thời có thể được cam kết. Vì mặc định là 0, không thiết lập điều này cho phép bất kỳ số lượng giao dịch nào được cam kết đồng thời.

innodb_thread_s ngủ_delay thiết lập số mili giây mà một chuỗi InnoDB có thể không hoạt động trước khi nhập lại hàng đợi InnoDB. Mặc định là 10000 (10 giây).

innodb_read_io_threadsinnodb_write_io_threads (cả kể từ MySQL 5.1,38) phân bổ số lượng chủ đề được chỉ định để đọc và ghi. Mặc định là 4 và tối đa là 64.

innodb numplication_delay áp đặt độ trễ của luồng trên một nô lệ là đạt đến innodb_thread_concurrency.

innodb_read_ahead_thr Ngưỡng cho phép đọc tuyến tính số lượng phạm vi đã đặt (64 trang [page = 16K]) trước khi chuyển sang đọc không đồng bộ.

Thời gian sẽ thoát khỏi tôi nếu tôi đặt tên cho nhiều lựa chọn hơn. Bạn có thể đọc về chúng trong Tài liệu của MySQL .

Hầu hết mọi người không biết về các tính năng này và khá hài lòng với InnoDB chỉ thực hiện các giao dịch tuân thủ ACID. Nếu bạn điều chỉnh bất kỳ tùy chọn nào trong số này, bạn sẽ làm điều đó một cách nguy hiểm.

Tôi đã chơi với MySQL 5.5 Nhiều bộ đệm nhóm (162GB trong 9 trường hợp bộ đệm) và đã cố gắng tự động phân vùng dữ liệu trong bộ nhớ theo cách này. Một số chuyên gia nói rằng điều này sẽ giúp bạn cải thiện hiệu suất 50%. Những gì tôi nhận được là một tấn khóa luồng thực sự khiến InnoDB thu thập dữ liệu. Tôi đã chuyển sang 1 bộ đệm (162GB) và tất cả đã hoạt động tốt trở lại trên thế giới. Tôi đoán bạn cần các chuyên gia Percona theo ý của bạn để thiết lập điều này. Tôi sẽ có mặt tại Hội nghị Percona MySQL ở New York vào ngày mai và sẽ hỏi về vấn đề này nếu có cơ hội.

Cuối cùng, InnoDB hoạt động tốt trong một máy chủ nhiều CPU với các cài đặt mặc định cho các hoạt động đa luồng. Tinh chỉnh chúng cần sự chăm sóc tuyệt vời, sự kiên nhẫn tuyệt vời, tài liệu tuyệt vời và cà phê tuyệt vời (hoặc Red Bull, Jolt, v.v.).

Chào buổi sáng, chào buổi tối và chúc ngủ ngon !!!

CẬP NHẬT 2011-05-27 20:11

Đã trở lại từ Hội nghị Percona MySQL ở New York vào thứ năm. Thật là một hội nghị. Đã học được rất nhiều, nhưng tôi đã nhận được câu trả lời tôi sẽ xem xét về InnoDB. Tôi đã được Ronald Bradford thông báo rằng việc đặt innodb_thread_concurrency thành 0 sẽ để InnoDB quyết định hướng hành động tốt nhất trong nội bộ với sự tương tranh của luồng. Tôi sẽ thử nghiệm điều này hơn nữa trong MySQL 5.5.

CẬP NHẬT 2011-06-01 11:20

Theo như một truy vấn dài, InnoDB tuân thủ ACID và hoạt động rất tốt khi sử dụng Điều khiển đồng thời MultiVersion . Các giao dịch phải có khả năng mang các mức cô lập (đọc lặp lại theo mặc định) để ngăn chặn người khác truy cập dữ liệu.

Đối với các hệ thống đa lõi, InnoDB đã đi một chặng đường dài. Trước đây, InnoDB không thể hoạt động tốt trong môi trường đa lõi. Tôi nhớ phải chạy nhiều phiên bản mysql trên một máy chủ để có được nhiều lõi để phân phối nhiều quá trình mysqld trên các CPU. Điều này không còn cần thiết nữa, nhờ Percona và sau này là MySQL (eh, Oracle, nói rằng điều đó vẫn khiến tôi bịt miệng), vì họ đã phát triển InnoDB thành một công cụ lưu trữ trưởng thành hơn, có thể truy cập các lõi một cách đơn giản mà không cần điều chỉnh nhiều. Phiên bản hiện tại của InnoDB ngày nay có thể hoạt động tốt trong một máy chủ lõi đơn.


11

Ngay khi bạn có nhiều người dùng hoặc quy trình đồng thời hoặc thậm chí một quy trình duy nhất có quyền truy cập cơ sở dữ liệu đa luồng, việc có một cơ sở dữ liệu hỗ trợ luồng sẽ trở nên thú vị.

H2 là an toàn luồng, nhưng tuần tự hóa tất cả các yêu cầu đến cơ sở dữ liệu, điều này có thể trở thành một vấn đề hiệu suất tiềm năng trong một kịch bản tải nặng. Liệu đây có thực sự là trường hợp của một dự án cụ thể hay không phụ thuộc vào sự kết hợp các yêu cầu hiệu suất của bạn, số lượng luồng / người dùng / quy trình truy cập cơ sở dữ liệu, tần suất truy vấn được thực hiện bởi các luồng này và hiệu suất trung bình và trường hợp xấu nhất của bạn truy vấn.

Chẳng hạn, nếu các yêu cầu về hiệu suất của bạn phải có phản hồi trong vòng một giây, bạn có không quá 10 người dùng đồng thời thực hiện một truy vấn duy nhất mất 0,05 giây để thực thi, cơ sở dữ liệu một luồng vẫn sẽ cho phép bạn đạt được các mục tiêu đó (mặc dù đa luồng có khả năng đã cung cấp một hiệu suất tăng đáng chú ý). Mặc dù có cùng một kịch bản với một truy vấn tiềm năng với hiệu suất trong trường hợp xấu nhất là nửa giây, việc tuần tự hóa truy cập cơ sở dữ liệu của bạn sẽ không cho phép bạn đáp ứng các mục tiêu hiệu suất của mình nữa.

Nếu bạn hiện đang sử dụng H2 cho dự án của mình, tôi khuyên bạn nên chạy một trình lược tả dựa trên cơ sở mã của bạn theo kịch bản tải (chỉ cần khởi động một số x luồng xử lý mã đồng thời sử dụng một số cách sử dụng điển hình). Điều này sẽ cung cấp cho bạn các số liệu thực tế về hiệu suất và các tắc nghẽn trong cơ sở mã của bạn, thay vì chỉ đưa ra lý thuyết. Nếu điều này cho thấy các yêu cầu của bạn dành phần lớn thời gian của họ chỉ chờ để truy cập cơ sở dữ liệu, thì đã đến lúc chuyển sang cơ sở dữ liệu theo luồng.


H2 có tuần tự hóa tất cả các yêu cầu - hay chỉ DML?
Jack Douglas

8

Từ những gì tôi có thể nói, "đơn luồng" là một chút sai lầm của H2. Vấn đề là nó tuần tự hóa tất cả các giao dịch (tức là thực hiện từng giao dịch một lần).

Câu hỏi quan trọng liên quan đến việc đó có "ok" hay không cho ứng dụng của bạn không phải là "Có bao nhiêu người dùng?" hoặc thậm chí "Có bao nhiêu quy trình?", nhưng "Giao dịch của tôi sẽ mất bao lâu?"

Nếu tất cả các giao dịch của bạn là giây phụ có thể ổn, nếu một số mất vài giờ để hoàn thành, điều đó có thể không ổn vì tất cả các giao dịch đang chờ xử lý khác sẽ chờ chúng kết thúc. Quyết định về việc đó có "ổn" hay không sẽ phụ thuộc vào yêu cầu hiệu suất của chính bạn - tức là thời gian chờ đợi cho người dùng của tôi truy cập cơ sở dữ liệu với các giao dịch là bao lâu.

--BIÊN TẬP

Có vẻ như H2 không thực sự tuần tự hóa các giao dịch - chỉ là DML. Nói cách khác, rất nhiều cập nhật ngắn trong một giao dịch dài sẽ không chặn các cập nhật khác . Tuy nhiên, trừ khi bạn đang sử dụng tính năng MVCC thử nghiệm , khóa bảng có nghĩa là điều này có tác dụng tương tự trong thực tế. Ngoài ra còn có một tính năng "multi_threaded" thử nghiệm nhưng nó không thể được sử dụng cùng lúc với MVCC


5

Trích dẫn các mẩu và mẩu từ trang PostgreQuery ... Xin lưu ý rằng tôi hoàn toàn không biết gì về giá trị của các đối số này - chúng chỉ không phù hợp với một nhận xét.

Từ Câu hỏi thường gặp dành cho nhà phát triển ("Tại sao chủ đề không được sử dụng ..."):

http://wiki.postgresql.org/wiki/Developer_FAQ#Why_don.27t_you_use_threads.2C_raw_devices.2C_async-I.2FO.2C_.3Cinsert_your_favorite_wizz-bang_feature_

Chủ đề hiện không được sử dụng thay vì nhiều quy trình cho phụ trợ vì: (...)

  • Một lỗi trong một phụ trợ có thể làm hỏng các phụ trợ khác nếu chúng là các luồng trong một quy trình
  • Cải thiện tốc độ bằng cách sử dụng các luồng nhỏ so với thời gian khởi động phụ trợ còn lại.
  • Chia sẻ ánh xạ thực thi chỉ đọc và sử dụng shared_buffers có nghĩa là các quy trình, như các luồng, rất hiệu quả về bộ nhớ
  • Việc tạo và phá hủy thường xuyên các quy trình giúp bảo vệ chống lại sự phân mảnh bộ nhớ, có thể khó quản lý trong các quy trình chạy dài

Từ danh sách Todo ("Các tính năng chúng tôi không muốn"):

http://wiki.postgresql.org/wiki/Todo#Features_we_Do_Not_Want

Tất cả các phụ trợ chạy dưới dạng các luồng trong một quy trình (không muốn)

Điều này giúp loại bỏ bảo vệ quá trình chúng ta nhận được từ thiết lập hiện tại. Việc tạo luồng thường có chi phí tương tự như quá trình tạo trên các hệ thống hiện đại, do đó dường như không khôn ngoan khi sử dụng một mô hình luồng thuần túy và MySQL và DB2 đã chứng minh rằng các luồng đưa ra nhiều vấn đề như chúng giải quyết. (...)

Vì vậy, một lần nữa ... Tôi hoàn toàn không biết gì về công trạng ở trên. Nó chỉ đơn thuần là quá dài để phù hợp với một bình luận.


-3

Một cơ sở dữ liệu đa luồng sẽ chỉ có lợi cho bạn khi bạn có nhiều hơn 1 truy vấn song song đến cơ sở dữ liệu. Nó phụ thuộc vào số lượng người dùng bạn có. Nếu bạn có hơn mười người dùng làm việc trên ứng dụng cùng một lúc, rất có thể họ sẽ tạo ra nhiều truy vấn trên cơ sở dữ liệu cùng một lúc.

Hơn nữa, cơ sở dữ liệu đa luồng chỉ có thể có lợi khi có nhiều lõi trên CPU. Nếu có lõi đơn, cơ sở dữ liệu đa luồng phải xếp hàng công việc và thực hiện chúng tuần tự trên lõi đơn. Khi có đa lõi, mỗi lõi có thể chạy song song một luồng. Do đó hiệu suất tốt hơn.

Điều này có trả lời câu hỏi của bạn không?


7
Cơ sở dữ liệu đa luồng có lợi ngay cả trên các hệ thống lõi đơn. Nó ngăn một truy vấn chạy dài duy nhất chặn tất cả các truy cập cơ sở dữ liệu khác, ngoài ra bạn có thể có một số luồng đang chờ trên đĩa hoặc I / O của mạng, trong khi một luồng khác đang tích cực phân tích truy vấn, xử lý dữ liệu được tìm nạp trước, v.v.

Một người dùng có thể đang sử dụng một chương trình làm tê liệt một số thao tác. Chương trình này có thể sẽ có lợi nhất nếu cơ sở dữ liệu có khả năng đa luồng / đa xử lý.
joanolo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.