MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

Viết cố vấn đầu tiên của bạn

Bạn có bao giờ tự hỏi điều gì kích hoạt lời khuyên trong ClusterControl rằng đĩa của bạn đang đầy không? Hoặc lời khuyên để tạo khóa chính trên bảng InnoDB nếu chúng không tồn tại? Các cố vấn này là các tập lệnh nhỏ được viết bằng Ngôn ngữ dành riêng cho Miền ClusterControl (DSL), một ngôn ngữ giống như Javascript. Các tập lệnh này có thể được viết, biên dịch, lưu, thực thi và lên lịch trong ClusterControl. Đó là nội dung của loạt blog ClusterControl Developer Studio.

Hôm nay, chúng tôi sẽ trình bày những kiến ​​thức cơ bản về Developer Studio và hướng dẫn bạn cách tạo cố vấn đầu tiên, nơi chúng tôi sẽ chọn hai biến trạng thái và đưa ra lời khuyên về kết quả của chúng.

Các cố vấn

Cố vấn là các tập lệnh nhỏ được thực thi bởi ClusterControl, theo yêu cầu hoặc sau một lịch trình. Chúng có thể là bất cứ điều gì từ lời khuyên cấu hình đơn giản, cảnh báo về ngưỡng hoặc các quy tắc phức tạp hơn cho các dự đoán hoặc các tác vụ tự động hóa toàn cụm dựa trên trạng thái của máy chủ hoặc cơ sở dữ liệu của bạn. Nói chung, các cố vấn thực hiện phân tích chi tiết hơn và đưa ra các đề xuất toàn diện hơn là cảnh báo.

Các cố vấn được lưu trữ bên trong cơ sở dữ liệu ClusterControl và bạn có thể thêm mới hoặc thay đổi / sửa đổi các cố vấn hiện có. Chúng tôi cũng có kho lưu trữ Github cố vấn nơi bạn có thể chia sẻ cố vấn của mình với chúng tôi và những người dùng ClusterControl khác.

Ngôn ngữ được sử dụng cho các cố vấn được gọi là ClusterControl DSL và là một ngôn ngữ dễ hiểu. Ngữ nghĩa của ngôn ngữ có thể tốt nhất so với Javascript với một vài điểm khác biệt, trong đó những điểm khác biệt quan trọng nhất là:

  • Dấu chấm phẩy là bắt buộc
  • Nhiều kiểu dữ liệu số khác nhau như số nguyên và số nguyên dài dài không dấu.
  • Mảng là mảng hai chiều và mảng một chiều là danh sách.

Bạn có thể tìm thấy danh sách đầy đủ các điểm khác biệt trong tham chiếu ClusterControl DSL.

Giao diện Studio dành cho nhà phát triển

Bạn có thể tìm thấy giao diện Developer Studio trong Cluster> Manage> Developer Studio. Thao tác này sẽ mở ra một giao diện như sau:

Cố vấn

Nút cố vấn sẽ tạo tổng quan về tất cả các cố vấn với kết quả đầu ra của họ kể từ lần cuối cùng họ chạy:

Bạn cũng có thể xem lịch trình của cố vấn ở định dạng crontab và ngày / giờ kể từ lần cập nhật cuối cùng. Một số cố vấn được lên lịch chỉ chạy một lần mỗi ngày nên lời khuyên của họ có thể không còn phản ánh đúng thực tế, ví dụ:nếu bạn đã giải quyết vấn đề mà bạn đã được cảnh báo. Bạn có thể chạy lại cố vấn theo cách thủ công bằng cách chọn cố vấn và chạy nó. Đi tới phần “biên dịch và chạy” để đọc cách thực hiện việc này.

Cố vấn nhập khẩu

Nút Nhập sẽ cho phép bạn nhập một tarball với các cố vấn mới trong đó. Tarball phải được tạo liên quan đến đường dẫn chính của các cố vấn, vì vậy nếu bạn muốn tải lên phiên bản mới của tập lệnh kích thước bộ nhớ cache truy vấn MySQL (s9s / mysql / query_cache / qc_size.js), bạn sẽ phải bắt đầu tarball từ thư mục s9s.

Cố vấn xuất khẩu

Bạn có thể xuất các cố vấn hoặc một phần của chúng bằng cách chọn một nút trong cây và nhấn nút Xuất. Điều này sẽ tạo một tarball với các tệp trong đường dẫn đầy đủ của cấu trúc được trình bày. Giả sử chúng ta muốn tạo một bản sao lưu của các cố vấn s9s / mysql trước khi thực hiện thay đổi, chúng ta chỉ cần chọn nút s9s / mysql trong cây và nhấn Export:

Lưu ý:đảm bảo rằng thư mục s9s có trong / home / myuser /.

Thao tác này sẽ tạo một tarball có tên /home/myuser/s9s/mysql.tar.gz với cấu trúc thư mục nội bộ s9s / mysql / *

Tạo cố vấn mới

Vì chúng tôi đã bao gồm xuất khẩu và nhập khẩu, bây giờ chúng tôi có thể bắt đầu thử nghiệm. Vì vậy, hãy tạo một cố vấn mới! Nhấp vào nút Mới để xem hộp thoại sau:

Trong hộp thoại này, bạn có thể tạo cố vấn mới của mình bằng một tệp trống hoặc điền trước bằng mẫu cụ thể của Galera hoặc MySQL. Cả hai mẫu sẽ bổ sung các thông tin cần thiết bao gồm (common / mysql_helper.js) và các điều cơ bản để truy xuất các nút Galera hoặc MySQL và lặp lại chúng.

Tạo một cố vấn mới với mẫu Galera trông giống như sau:

#include "common/mysql_helper.js"

Ở đây, bạn có thể thấy rằng mysql_helper.js được bao gồm để cung cấp cơ sở cho việc kết nối và truy vấn các nút MySQL.

Tệp này chứa các hàm mà bạn có thể gọi nếu cần, chẳng hạn như readVariable (, ) sẽ cho phép bạn nhận giá trị biến toàn cục hoặc gọi readStatusVariable (, ) cũng sẽ cho phép bạn để lấy các biến trạng thái toàn cục trong MySQL. Tệp này có thể được đặt trong cây như hình dưới đây:

var WARNING_THRESHOLD=0;
…
if(threshold > WARNING_THRESHOLD)

Ngưỡng cảnh báo hiện được đặt thành 0, nghĩa là nếu ngưỡng đo được lớn hơn ngưỡng cảnh báo, cố vấn sẽ cảnh báo người dùng. Lưu ý rằng ngưỡng biến chưa được đặt / sử dụng trong mẫu vì nó là bước khởi động cho cố vấn của riêng bạn.

var hosts     = cluster::Hosts();
var hosts     = cluster::mySqlNodes();
var hosts     = cluster::galeraNodes();

Các câu lệnh trên sẽ tìm nạp các máy chủ trong cụm và bạn có thể sử dụng điều này để lặp lại chúng. Sự khác biệt giữa chúng là câu lệnh đầu tiên bao gồm tất cả các máy chủ không phải MySQL (cũng là máy chủ CMON), câu lệnh thứ hai là tất cả các máy chủ MySQL và câu lệnh cuối cùng chỉ máy chủ Galera. Vì vậy, nếu cụm Galera của bạn có đính kèm nô lệ đọc không đồng bộ MySQL, thì những máy chủ đó sẽ không được bao gồm.

Ngoài ra, tất cả các đối tượng này sẽ hoạt động giống nhau và có khả năng đọc các biến, trạng thái và truy vấn đối với chúng.

Nút cố vấn

Bây giờ chúng tôi đã tạo một cố vấn mới, có sáu nút mới dành cho cố vấn này:

Lưu sẽ lưu các sửa đổi mới nhất của bạn vào cố vấn (được lưu trữ trong cơ sở dữ liệu CMON), Move sẽ chuyển cố vấn sang một con đường mới và Xóa rõ ràng sẽ xóa cố vấn.

Thú vị hơn là hàng nút thứ hai. Biên dịch cố vấn sẽ biên dịch mã của cố vấn. Nếu mã biên dịch tốt, bạn sẽ thấy thông báo này trong Tin nhắn đối thoại bên dưới mã của cố vấn:

Trong khi nếu quá trình biên dịch không thành công, trình biên dịch sẽ cung cấp cho bạn một gợi ý về nơi nó không thành công:

Trong trường hợp này, trình biên dịch chỉ ra lỗi cú pháp được tìm thấy trên dòng 24.

Việc biên dịch và chạy nút sẽ không chỉ biên dịch tập lệnh mà còn thực thi nó và đầu ra của nó sẽ được hiển thị trong hộp thoại Tin nhắn, Đồ thị hoặc Thô. Nếu chúng tôi biên dịch và chạy tập lệnh bộ nhớ cache của bảng từ auto_tuners, chúng tôi sẽ nhận được kết quả tương tự như sau:

Nút cuối cùng là lịch trình cái nút. Điều này cho phép bạn lên lịch (hoặc hủy bỏ lịch) các cố vấn của mình và thêm thẻ vào đó. Chúng tôi sẽ đề cập vấn đề này ở cuối bài đăng này khi chúng tôi đã tạo cố vấn riêng và muốn lên lịch cho nó.

Cố vấn đầu tiên của tôi

Bây giờ chúng ta đã trình bày những kiến ​​thức cơ bản về ClusterControl Developer Studio, cuối cùng chúng ta cũng có thể bắt đầu tạo một cố vấn mới. Như một ví dụ, chúng tôi sẽ tạo một cố vấn để xem xét tỷ lệ bảng tạm thời. Tạo một cố vấn mới như sau:

Lý thuyết đằng sau cố vấn mà chúng tôi sắp tạo rất đơn giản:chúng tôi sẽ so sánh số lượng bảng tạm thời được tạo trên đĩa với tổng số bảng tạm thời được tạo:

tmp_disk_table_ratio = Created_tmp_disk_tables / (Created_tmp_tables + Created_tmp_disk_tables) * 100;

Trước tiên, chúng ta cần thiết lập một số điều cơ bản trong phần đầu của script, như các ngưỡng và cảnh báo và thông báo ok. Tất cả các thay đổi và bổ sung được áp dụng bên dưới:

var WARNING_THRESHOLD=20;
var TITLE="Temporary tables on disk ratio";
var ADVICE_WARNING="More than 20% of temporary tables are written to disk. It is advised to review your queries, for example, via the Query Monitor.";
var ADVICE_OK="Temporary tables on disk are not excessive." ;

Chúng tôi đặt ngưỡng ở đây là 20 phần trăm được coi là khá tệ. Nhưng nhiều hơn về chủ đề đó khi chúng tôi đã hoàn thiện cố vấn của mình.

Tiếp theo, chúng ta cần lấy các biến trạng thái này từ MySQL. Trước khi chúng tôi chuyển đến kết luận và thực hiện một số truy vấn “HIỂN THỊ TÌNH TRẠNG TOÀN CẦU 'Created_tmp_%'”, đã có một hàm để truy xuất biến trạng thái của một cá thể MySQL, như những gì chúng tôi đã mô tả ở trên, nơi hàm này nằm trong common / mysql_helper. js:

statusVar = readStatusVariable(<host>, <statusvariablename>);

Chúng tôi có thể sử dụng hàm này trong trình cố vấn của mình để tìm nạp Created_tmp_disk_tables và Created_tmp_tables.

    for (idx = 0; idx < hosts.size(); ++idx)
    {
        host        = hosts[idx];
        map         = host.toMap();
        connected     = map["connected"];
        var advice = new CmonAdvice();
        var tmp_tables = readStatusVariable(host, ‘Created_tmp_tables’);
        var tmp_disk_tables = readStatusVariable(host, ‘Created_tmp_disk_tables’);

Và bây giờ chúng ta có thể tính toán tỷ lệ bảng đĩa tạm thời:

        var tmp_disk_table_ratio = tmp_disk_tables / (tmp_tables + tmp_disk_tables) * 100;

Và cảnh báo nếu tỷ lệ này lớn hơn ngưỡng chúng tôi đặt lúc đầu:

        if(checkPrecond(host))
        {
           if(tmp_disk_table_ratio > WARNING_THRESHOLD) {
               advice.setJustification("Temporary tables written to disk is excessive");
               msg = ADVICE_WARNING;
           }
           else {
               advice.setJustification("Temporary tables written to disk not excessive");
               msg = ADVICE_OK;
           }
        }

Điều quan trọng là gán Lời khuyên cho biến msg ở đây vì điều này sẽ được thêm vào sau này vào đối tượng lời khuyên với hàm setAdvice (). Tập lệnh đầy đủ cho sự hoàn chỉnh:

#include "common/mysql_helper.js"

/**
 * Checks the percentage of max ever used connections 
 * 
 */ 
var WARNING_THRESHOLD=20;
var TITLE="Temporary tables on disk ratio";
var ADVICE_WARNING="More than 20% of temporary tables are written to disk. It is advised to review your queries, for example, via the Query Monitor.";
var ADVICE_OK="Temporary tables on disk are not excessive.";

function main()
{
    var hosts     = cluster::mySqlNodes();
    var advisorMap = {};

    for (idx = 0; idx < hosts.size(); ++idx)
    {
        host        = hosts[idx];
        map         = host.toMap();
        connected     = map["connected"];
        var advice = new CmonAdvice();
        var tmp_tables = readStatusVariable(host, 'Created_tmp_tables');
        var tmp_disk_tables = readStatusVariable(host, 'Created_tmp_disk_tables');
        var tmp_disk_table_ratio = tmp_disk_tables / (tmp_tables + tmp_disk_tables) * 100;
        
        if(!connected)
            continue;
        if(checkPrecond(host))
        {
           if(tmp_disk_table_ratio > WARNING_THRESHOLD) {
               advice.setJustification("Temporary tables written to disk is excessive");
               msg = ADVICE_WARNING;
               advice.setSeverity(0);
           }
           else {
               advice.setJustification("Temporary tables written to disk not excessive");
               msg = ADVICE_OK;
           }
        }
        else
        {
            msg = "Not enough data to calculate";
            advice.setJustification("there is not enough load on the server or the uptime is too little.");
            advice.setSeverity(0);
        }
        advice.setHost(host);
        advice.setTitle(TITLE);
        advice.setAdvice(msg);
        advisorMap[idx]= advice;
    }
    return advisorMap;
}

Bây giờ, bạn có thể thử với ngưỡng 20, hãy thử giảm nó xuống 1 hoặc 2 chẳng hạn và sau đó bạn có thể thấy cố vấn này thực sự sẽ đưa ra lời khuyên cho bạn về vấn đề này như thế nào.

Như bạn có thể thấy, với một tập lệnh đơn giản, bạn có thể kiểm tra hai biến số chống lại nhau và báo cáo / lời khuyên dựa trên kết quả của chúng. Nhưng đó có phải là tất cả? Vẫn còn một số điều chúng tôi có thể cải thiện!

Những cải tiến đối với cố vấn đầu tiên của tôi

Điều đầu tiên chúng tôi có thể cải thiện là cố vấn này không có nhiều ý nghĩa. Những gì số liệu thực sự phản ánh là tổng số bảng tạm thời trên đĩa kể từ TÌNH TRẠNG FLUSH cuối cùng hoặc lần khởi động MySQL. Những gì nó không nói là tỷ lệ nó thực sự tạo ra các bảng tạm thời trên đĩa. Vì vậy, chúng tôi có thể chuyển đổi Created_tmp_disk_tables thành tỷ lệ sử dụng thời gian hoạt động của máy chủ:

    var tmp_disk_table_rate = tmp_disk_tables / uptime;

Điều này sẽ cung cấp cho chúng tôi số lượng bảng tạm thời mỗi giây và kết hợp với tmp_disk_table_ratio, điều này sẽ cho chúng tôi cái nhìn chính xác hơn về mọi thứ. Một lần nữa, khi chúng tôi đạt đến ngưỡng hai bảng tạm thời mỗi giây, chúng tôi không muốn gửi ngay một cảnh báo / lời khuyên.

Một điều khác mà chúng ta có thể cải thiện là không sử dụng hàm readStatusVariable (, ) từ thư viện common / mysql_helper.js. Hàm này thực thi một truy vấn tới máy chủ MySQL mỗi khi chúng tôi đọc một biến trạng thái, trong khi CMON đã truy xuất hầu hết chúng mỗi giây và chúng tôi không cần trạng thái thời gian thực. Nó không giống như hai hoặc ba truy vấn sẽ giết chết các máy chủ trong cụm, nhưng nếu nhiều cố vấn này được chạy theo kiểu tương tự, điều này có thể tạo ra một đống truy vấn bổ sung.

Trong trường hợp này, chúng ta có thể tối ưu hóa điều này bằng cách truy xuất các biến trạng thái trong bản đồ bằng cách sử dụng hàm host.sqlInfo () và truy xuất mọi thứ cùng một lúc dưới dạng bản đồ. Hàm này chứa thông tin quan trọng nhất của máy chủ, nhưng nó không chứa tất cả. Ví dụ:thời gian hoạt động biến mà chúng ta cần cho tỷ lệ không có sẵn trong bản đồ host.sqlInfo () và phải được truy xuất bằng hàm readStatusVariable (, ).

Bây giờ cố vấn của chúng tôi sẽ trông như thế này, với những thay đổi / bổ sung được in đậm:

#include "common/mysql_helper.js"

/**
 * Checks the percentage of max ever used connections 
 * 
 */ 
var RATIO_WARNING_THRESHOLD=20;
var RATE_WARNING_THRESHOLD=2;
var TITLE="Temporary tables on disk ratio";
var ADVICE_WARNING="More than 20% of temporary tables are written to disk and current rate is more than 2 temporary tables per second. It is advised to review your queries, for example, via the Query Monitor.";
var ADVICE_OK="Temporary tables on disk are not excessive.";

function main()
{
    var hosts     = cluster::mySqlNodes();
    var advisorMap = {};

    for (idx = 0; idx < hosts.size(); ++idx)
    {
        host        = hosts[idx];
        map         = host.toMap();
        connected     = map["connected"];
        var advice = new CmonAdvice();
        var hostStatus = host.sqlInfo();
        var tmp_tables = hostStatus['CREATED_TMP_TABLES'];
        var tmp_disk_tables = hostStatus['CREATED_TMP_DISK_TABLES'];
        var uptime = readStatusVariable(host, 'uptime');
        var tmp_disk_table_ratio = tmp_disk_tables / (tmp_tables + tmp_disk_tables) * 100;
        var tmp_disk_table_rate = tmp_disk_tables / uptime;
        
        if(!connected)
            continue;
        if(checkPrecond(host))
        {
           if(tmp_disk_table_rate > RATE_WARNING_THRESHOLD && tmp_disk_table_ratio > RATIO_WARNING_THRESHOLD) {
               advice.setJustification("Temporary tables written to disk is excessive: " + tmp_disk_table_rate + " tables per second and overall ratio of " + tmp_disk_table_ratio);
               msg = ADVICE_WARNING;
               advice.setSeverity(0);
           }
           else {
               advice.setJustification("Temporary tables written to disk not excessive");
               msg = ADVICE_OK;
           }
        }
        else
        {
            msg = "Not enough data to calculate";
            advice.setJustification("there is not enough load on the server or the uptime is too little.");
            advice.setSeverity(0);
        }
        advice.setHost(host);
        advice.setTitle(TITLE);
        advice.setAdvice(msg);
        advisorMap[idx]= advice;
    }
    return advisorMap;
}

Lên lịch cho cố vấn đầu tiên của tôi

Sau khi chúng tôi đã lưu cố vấn mới này, biên dịch nó và chạy, bây giờ chúng tôi có thể lên lịch cho cố vấn này. Vì chúng tôi không có quá nhiều công việc, chúng tôi có thể sẽ điều hành cố vấn này một lần mỗi ngày.

Chế độ lập lịch cơ sở tương tự như Cron, có cài đặt trước mỗi phút, 5 phút, giờ, ngày, tháng và đây chính xác là những gì chúng ta cần và rất dễ dàng để quản lý việc lập lịch. Thay đổi điều này thành nâng cao sẽ mở khóa các trường nhập xám khác. Các trường đầu vào này hoạt động giống hệt như crontab, vì vậy bạn thậm chí có thể lên lịch cho một ngày cụ thể, ngày trong tháng hoặc thậm chí đặt nó vào các ngày trong tuần.

Tiếp theo blog này, chúng tôi sẽ tạo trình kiểm tra SELinux hoặc kiểm tra bảo mật cho Spectre và Meltdown nếu các nút bị ảnh hưởng. Hãy theo dõi!


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Giới thiệu khái quát về khu vực MongoDB

  2. Kết nối MongoDb bị từ chối

  3. Các đơn vị sử dụng cho maxdistance và MongoDB?

  4. Mongo Câu hỏi truy vấn $ gt, $ lt

  5. Nhóm và đếm với điều kiện