使用Super Smack進行MySQL效能測試

來源:互聯網
上載者:User

原本打算用mysql內建的mysqlslap做壓力測試,可惜這工具不給力,可控制的地方不多,尤其不能夠產生隨機的測試語句。遂改用super smack。貌似它風評還不錯。

安裝


1.從網上下載tar.gz的安裝包。http://vegan.net/tony/supersmack/
我下載到的最新版本是1.3。
2.解壓後運行./configure; make; make install
   ./configure的時候有些參數值得注意:
    a) --with-mysql (支援mysql)
    b) --with-pgsql (支援postgresql)
    c) --with-mysql-lib=/mysql/lib    (設定mysql lib庫的路徑)
    d) --with-mysql-include=/mysql/include    (設定mysql include的路徑)
3.安裝過程中可能會碰見這個錯誤:

辦法是編譯之前修改檔案super-smack-1.3/src/query.cc
第193行:
    < int len = 0, num_recs = 0;
修改成:
    > long len = 0; int num_recs = 0;
第199,200行
    < int str_len = (*i).first.length();
    < if((unsigned)p + str_len + 3 *sizeof(int) < (unsigned)p_end )
修改成:
    > long str_len = (*i).first.length();
    > if((long)p + str_len + 3 *sizeof(int) < (long)p_end )
第219行
    < len = (unsigned)p - (unsigned)buf;
修改成:
    > len = (long)p - (long)buf;
(以上修改方法摘抄自網上的一篇blog,可惜link我已經找不到了,真不是我抄襲)

4.安裝完成後,可以用內建的設定檔測試一下:
super-smack -d mysql ./smacks/select-key.smack 2 5
2 表示啟動2個用戶端,5 則表示每個用戶端輪詢5次。
測試過程可能會碰到一些問題(比如我碰到過找不到/tmp/mysql.sock),這是因為select-key.smack中一些參數設定和實際不符。修改一下就好了。

 

結果分析


[root@vm189 mysqltest]# super-smack -d mysql ./select_key.smack  20 100
Query Barrel Report for client smacker1
connect: max=0ms  min=0ms avg= 0ms from 20 clients
Query_type      num_queries     max_time        min_time        q_per_s
select_index    2000    4910    147     6.59

很容易理解。結果包括一共執行了多少次查詢(num_queries),最大的一次查詢時間(max_time)是4910ms,耗時最少的一次查詢是147ms,每秒完成查詢(min_time)6.59次

定義自己的測試組態檔案

要做自訂的MySQL測試,當然就必須編輯自己的設定檔(.smack)。Super Smack之所以很靈活,就在於可以在它的設定檔中自訂很多的東西。當然,隨著而來的就是設定檔的相對複雜。理解它的設定檔的結構,是學會用Super Smack的關鍵所在。

下文將以select-key.smack為例,講解.smack設定檔的結構。
網上也有一些相關的link:http://imysql.cn/docs/High_Performance_MySQL/0596003064/hpmysql-CHP-3-SECT-3.html

client "admin"
{
 user "root";
 host "localhost";
 db "test";
 pass "";
 socket "/data0/mysql/mysql.sock"; // this only applies to MySQL and is
// ignored for PostgreSQL
}


這部分定義了Super Smack串連資料庫需要用到的一些資訊,比如使用者名稱,機器名,資料庫名,密碼等等。很容易理解,不解釋。

// ensure the table exists and meets the conditions
table "http_auth"
{
  client "admin"; // connect with this client
 // if the table is not found or does not pass the checks, create it
 // with the following, dropping the old one if needed
  create "create table http_auth
    (username char(25) not null primary key,
     pass char(25),
     uid integer not null,
     gid integer not null
    )";
  min_rows "90000"; // the table must have at least that many rows
  data_file "words.dat"; // if the table is empty, load the data from
//this file
  gen_data_file "gen-data -n 90000 -f %12-12s%n,%25-25s,%n,%d";
// if the file above does not exist, generate it with the above shell command
// you can replace this command with anything that prints comma-delimited
// data to stdout, just make sure you have the right number of columns
}

這裡定義了要進行測試的資料庫表的資訊。包括:
建立這個表所使用的sql語句。如果Super Smack探索資料庫中沒有這個表的話,會使用這條sql語句建立表。
注意,這裡設定了client "admin",表明是用前面定義的admin這個client來建立表。
min_rows這個參數是一個對錶的約束,要求表內的記錄必須達到的數量。例子中的值是90000,表示表中必須要有90000條資料。
“ data_file "words.dat";  ”是定義了一個資料檔案,這個檔案中的每一行都可以作為表中的一條記錄。如果表http_auth沒有達到90000條資料,那麼Super Smack會從words.dat中讀取資料然後插入到表http_auth中。
gen_data_file "gen-data -n 90000 -f %12-12s%n,%25-25s,%n,%d"; -- 自動產生測試資料,如果words.dat為空白的話,Super Smack使用這條語句產生測試資料然後寫入到words.dat中。

gen-data是安裝Super Smack後提供的一個產生隨機資料的小程式。下面解讀一下它的命令格式:
-n 90000表示產生90000條記錄;
-f後面跟的是記錄的格式;
%S表示產生字串,%12-12s表示產生的字串長度在12與12之間;
%D表示產生數字,%d產生隨機數;
%N %n表示可以從1開始遞增的數值,可用於表中的主鍵,比如第一條記錄的%n就會被1代替,以此類推。
上面的這句“gen-data -n 90000 -f %12-12s%n,%25-25s,%n,%d” 輸出的每行是大概這樣的:
josamibdnjdb3,eyhkbsombltouujdrbwcrrcgb,3,485560280
qwdqweqwdwev4,regergergftyyujeqwqwecdfr,4,239013239
rhbtjrbtywlf5,edeffkergpqqmcxvkrtmbhwer,5,233021393
預設gen-data的輸出都是列印了標準輸出上,可以用重新導向讓gen-data的輸出結果寫入到檔案中。

需要指出的是,這裡採用的例子select-key.smack是對一個表做查詢測試,所以要求table中必須首先有一定量的資料。如果想做插入的測試,完全可以將min_rows設定成0,這樣,Super Smack也就不需要調用gen_data_file產生資料。

//define a dictionary
dictionary "word"
{
  type "rand"; // words are retrieved in random order
  source_type "file"; // words come from a file
  source "words.dat"; // file location
  delim ","; // take the part of the line before ,
  file_size_equiv "45000"; // if the file is greater than this
//divive the real file size by this value obtaining N and take every Nth
//line skipping others. This is needed to be able to target a wide key
// range without using up too much memory with test keys

//define a query
query "select_by_username"
{
  query "select * from http_auth where username = '$word'";
// $word will be substitute with the read from the 'word' dictionary
  type "select_index";
// query stats will be grouped by type
  has_result_set "y";
// the query is expected to return a result set
  parsed "y";
// the query string should be first processed by super-smack to do
// dictionary substitution
}

dictionary和query組合在一起,定義了需要的測試查詢語句。
一條普通的查詢語句,比如:select * from http_auth where username = 'test'; 它其實是由一個模板和一個或者幾個參數構成的。select * from http_auth where username = '$word'就是這條語句的模板,而$word = test則是設定參數。
query部分定義了查詢語句的模板,而dictionary則產生隨機的各種參數。

query的結構很簡單,最重要的就是“ query "select * from http_auth where username = '$word'"; ”,這定義了查詢的模板;

dictionary的結構則非常的靈活,它可以有多種配置:
source_type "file"; -- 表示這個dictionary是一個檔案的形式;
source "words.dat"; -- 表示檔案名稱為words.dat;
delim ","; -- 表示words.dat中第一個","之前的部分是這個dictionary的內容;
type:rand -- 表示隨機的從中抽取值;
把它們綜合起來理解。
之前看過,words.dat的資料是這樣的:
josamibdnjdb3,eyhkbsombltouujdrbwcrrcgb,3,485560280
qwdqweqwdwev4,regergergftyyujeqwqwecdfr,4,239013239
rhbtjrbtywlf5,edeffkergpqqmcxvkrtmbhwer,5,233021393
那麼,這裡定義的dictionary其實是讀取word.dat,並將每一行的第一個字串(比如josamibdnjdb3)作為字典內的元素,再和query組合起來,就變成了實際的查詢語句:
select * from http_auth where username = 'qwdqweqwdwev4'
select * from http_auth where username = 'rhbtjrbtywlf5'
select * from http_auth where username = 'josamibdnjdb3'

type除了可以定義為rand,還可以定義為
    seq,表示Values are used sequentially;
    unique,Generate unique values using the same method as gen-data;
source_type除了可以定義為 file,還可以定義為
    list,表示a user-supplied list of words, comma-separated;
    template,表示the format to use when type is unique. For example, "jzawodn_%07d" generates values composed of jzawodn_ and a seven-digit number

舉例來說,可以這樣定義:
dictionary "gender" {
  type: rand
  source_type "list";
  source "male,female";
}

它表示這個gender的dictionary只有兩個值,要麼是male,要麼是female
dictionary "name"
{
  type "unique";
  source_type "template";
  source "%15s";
}

表示name這個dictionary是一個長度為15的字串,Super Smack將用gen-data命令產生這個字串。

很多時候,如果你的查詢範本需要多個參數的話,那麼你可能需要準備多個dictionary。比如要產生如 select * from tablename where age < 20 AND id = 1234這樣的查詢,就需要兩個dictionary,一個是age,一個是id。
當然,還有一種討巧的方案,只需要產生一個dictionary,定義它的每一行是這樣的:
Age < *** AND id = ***
而對應的query模板就是
select * from tablename where dictionary;

// define database client type
client "smacker1"
{
 user "test"; // connect as this user
 pass ""; // use this password
 host "localhost"; // connect to this host
 db "test"; // switch to this database
 socket "/data0/mysql/mysql.sock"; // this only applies to MySQL and is
// ignored for PostgreSQL
 query_barrel "2 select_by_username"; // on each round,
// run select_by_username query 2 times
}

main
 {
  smacker1.init(); // initialize the client
  smacker1.set_num_rounds($2); // second arg on the command line defines
// the number of rounds for each client
  smacker1.create_threads($1);
// first argument on the command line defines how many client instances
// to fork. Anything after this will be done once for each client until
// you collect the threads
  smacker1.connect();
// you must connect after you fork
  smacker1.unload_query_barrel(); // for each client fire the query barrel
// it will now do the number of rounds specified by set_num_rounds()
// on each round, query_barrel of the client is executed

  smacker1.collect_threads();
// the master thread waits for the children, each child reports the stats
// the stats are printed
  smacker1.disconnect();
// the children now disconnect and exit
 }

這裡又定義了一個client,它是執行查詢語句所用到的client(最早的client是建立表的client,這兩個client許可權應該不一樣。)
query_barrel "2 select_by_username"; -- 表示這個client在一次迴圈中執行select_by_username這個查詢兩次;
main中則定義了Super Smack具體的執行流程。很簡單,不解釋。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.