Tuesday 21 October 2014

MySQL Community vs Enterprise vs Standard

Trong khoảng 2 năm làm việc của mình, database mình sử dụng thường xuyên nhất là MySQL, trong nhiều dự án khác nhau, vì tính phổ biến và dễ sử dụng.

Câu hỏi mình tự hỏi bản thân mình là tại sao MySQL lại có các phiên bản khác nhau như vậy? (Community - Standard - Enterprise). Có ai từng có câu hỏi tương tự như mình chưa nhỉ?

Thanks to Lynn Ferrante, mình tìm được câu trả lời từ một bài viết của anh ấy.

Community vs Enterprise

2 phiên bản community và enterprise khá là giống nhau, chỉ khác ở chỗ, ở bản enterprise được thêm vào một số tính năng:
- Support : support for mission critical issues and hot fixes.
- Backup : MEB ( MySQL Enterprise Backup ), online InnoDB,MyISAM backups.
- Monitoring Tools : MEM ( MySQL Enterprise Monitor ), Query Analyzer, Web Based configuration Plugins :
- Additional plugins for performance improvement i.e. thread pool, PAM authentication etc

Ta thấy tính năng quan trọng nhất của bản enterprise chính là sử dụng "thread pool" để tối ưu hiệu năng cho database. Vậy thread pool là gì? và tại sao nó làm tăng hiệu năng?

Đây là câu trả lời chính thức từ MySQL (rất đầy đủ và chi tiết):
Bản tóm tắt:
MySQL Thread Pool là plugin dùng để tăng khả năng quản lí kết nối (connection handling) của MySQL server, giới hạn số lượng kết nối đồng thời thực thi statement/query và transaction để đảm bảo mỗi connection đều có CPU và memory để thực hiện công việc của nó.
Bình thường MySQL sử dụng mô hình thread-handling (một connection đến sẽ có một thread xử lí). Do đó, càng nhiều client kết nối đến server và thực thi statement, hiệu suất chung sẽ giảm đi.
Thread Pool được tạo ra để thay thế thread-handling, làm giảm overhead và tăng performance, hiệu quả khi xử lí nhiều thread cho số lượng lớn kết nối, đặc biệt hệ thống mới (multi-CPU/Core system)
Thread Pool sử dụng cách "chia để trị" (devide and conquer) để giới hạn và cân bằng sự đồng thời. Nó tách biệt connection và thread, do đó không có quan hệ gì giữa thread xử lí và connection đến. Nó quản lí client connection theo từng thread group, chúng được đánh dấu độ ưu tiên và xếp hàng dựa vào bản chất của công việc của chúng.

Cơ chế hoạt động:
Thread được tổ chức thành 16 group (mặc định, có thể tăng lên thành 64 group). Mỗi group bắt đầu với 1 thread và có thể tăng lên đến maximum 4096 thread, additional thread được tạo ra khi cần thiết.
Mỗi connection đến được gán vào một group theo cơ chế Round robin. Mỗi group đều có một "listener thread" để lắng nghe yêu cầu kết nối đến.

 Khi có yêu cầu kết nối đến group, listener thread của group sẽ thực thi ngay lập tức nếu không bận và không có yêu cầu nào đang đợi. Nếu yêu cầu được thực hiện xong nhanh, listener thread sẽ trở về trạng thái chờ yêu cầu tiếp theo (ngăn chặn việc thêm một thread mới được tạo ra). Nếu yêu cầu đó không kết thúc nhanh (vẫn còn đang xử lí), một thread mới được tạo ra, trở thành lister thread mới.

Nếu listener thread đang bận xử lí, yêu cầu đến được xếp vào hàng đợi. Sẽ có một khoảng thời gian rất ngắn (thread_pool_stall_limit, mặc định là 60ms) ta phải đợi để biết câu lệnh đang thực thi có kết thúc nhanh hay không. Nếu nó hoàn thành nhanh (ít hơn thời gian của thread_pool_stall_limit), ta có thể sử dụng lại thread này cho yêu cầu tiếp theo trong hàng đợi, giúp loại trừ overhead việc tạo thread mới hay có quá nhiều statement ngắn để thực thi đồng thời (parrallel)


Thiết kế của thread pool là cố gắng có một thread thực thi trên một group bất kì lúc nào. Số lượng group (thread_pool_size_variable) là cực kì quan trọng, vì nó xấp xỉ với số lượng short-running statement thực thi đồng thời trong khoảng bất kì lúc nào. Long-running statement được ngăn chặn không gây ra việc đợi cho các statement khác, vì nếu chúng vượt quá thời gian (thread_pool_stall_limit), một thread khác sẽ được tạo ra, yêu cầu tiếp theo trong hàng đợi sẽ thực thi trên đó.

Có 2 loại hàng đợi cho waiting statement, low và high priority.
Hàng đợi low priority (ưu tiên thấp) bao gồm:
- tất cả các statement cho các loại non-transactional storage engine (MyISAM, ISAM)
- tất cả các statement nếu autocommit được enable.
- statement đầu tiên trong InnoDB transaction.
Các câu lệnh trên tất nhiên sẽ không nằm đợi mãi như vậy, vì nó sẽ bị đá đến hàng đợi hàng đợi high priority khi thời gian thread_pool_prio_kickup_timer hết. Tuy nhiên, chỉ có số lượng tối đa số statement được di chuyển trong một khoảng thời gian mà thôi(100 statement/s), đảm bảo mọi thứ trong tầm điều khiển.

Hàng đợi high priority (ưu tiên cao) bao gồm:
- bất kì câu lệnh tiếp theo nào trong InnoDB transaction.
- bất kì câu lệnh nào bị kick khỏi hàng đợi low priority.

Standard vs Enterprise
Bạn có thể thêm thông tin ở đây để biết nó khác nhau chỗ nào ;)

Some information links:
- http://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html#sysvar_thread_pool_algorithm
- http://dev.mysql.com/doc/refman/5.6/en/thread-pool-tuning.html