Difference between revisions of "Mysqlslap: cara melakukan pengukuran"
Onnowpurbo (talk | contribs) |
Onnowpurbo (talk | contribs) |
||
(24 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
− | + | mysqlslap dapat meng-emulasi sejumlah besar koneksi klien meng-hit server database pada saat yang sama. Parameter pengujian dapat beban sepenuhnya dikonfigurasi dan hasil dari tes berjalan yang berbeda dapat digunakan untuk menyempurnakan desain database atau sumber daya perangkat keras. | |
− | mysqlslap | + | Dalam tutorial ini kita akan belajar bagaimana menggunakan mysqlslap untuk menguji beban database MySQL dengan beberapa query dasar dan melihat bagaimana benchmarking dapat membantu kita dalam menyempurnakan query tersebut. Setelah beberapa demonstrasi dasar, kita akan menjalankan melalui skenario pengujian yang cukup realistis di mana kita membuat copy dari database yang sudah ada untuk pengujian, mengumpulkan pertanyaan dari log, dan menjalankan tes dari script. |
− | + | Jika anda tertarik untuk pembandingan server database tertentu, anda harus menguji pada server dengan spesifikasi yang sama dan dengan salinan dari database anda yang terinstal. | |
− | + | Jika anda ingin menjalankan melalui tutorial ini untuk tujuan belajar dan melaksanakan setiap perintah di dalamnya, kami sarankan setidaknya 2 GB Droplet. Karena perintah dalam tutorial ini dimaksudkan untuk memaksa server, anda mungkin menemukan mereka akan time out pada server yang lebih kecil. | |
− | |||
− | + | Sampel output dalam tutorial ini diproduksi dalam berbagai cara untuk mengoptimalkan contoh untuk mengajar. | |
− | |||
− | |||
− | |||
− | |||
==Langkah Pertama - Install MySQL di sistem yang akan di test== | ==Langkah Pertama - Install MySQL di sistem yang akan di test== | ||
Line 19: | Line 14: | ||
apt-get update | apt-get update | ||
− | apt-get install mysql-server mysql-client | + | apt-get install -y mysql-server mysql-client |
Biasanya akan di tanya root password. | Biasanya akan di tanya root password. | ||
Line 315: | Line 310: | ||
4 rows in set (0.00 sec) | 4 rows in set (0.00 sec) | ||
− | ===CONTOH: Benchmarking dengan Custom Queries== | + | ===CONTOH: Benchmarking dengan Custom Queries=== |
Auto-generated SQL baik untuk meng-evaluasi sumber daya fisik pada server. | Auto-generated SQL baik untuk meng-evaluasi sumber daya fisik pada server. | ||
Line 330: | Line 325: | ||
Jika berjalan dengan baik, maka akan keluar kira-kira, | Jika berjalan dengan baik, maka akan keluar kira-kira, | ||
− | Benchmark | + | Benchmark |
− | + | Average number of seconds to run all queries: 10.401 seconds | |
− | + | Minimum number of seconds to run all queries: 9.613 seconds | |
− | + | Maximum number of seconds to run all queries: 13.575 seconds | |
− | + | Number of clients running queries: 50 | |
− | + | Average number of queries per client: 1 | |
(Catatan: Jika query membuat hang atau lebih dari 10 menit tanpa output, | (Catatan: Jika query membuat hang atau lebih dari 10 menit tanpa output, | ||
coba kurangi --concurrency and/or --iterations, atau coba di server yang lebih besar) | coba kurangi --concurrency and/or --iterations, atau coba di server yang lebih besar) | ||
− | + | Selanjutnya, kita akan menggunakan multiple SQL statements di --query parameter. | |
+ | Terminasi setiap query menggunakan titik koma (semicolon). | ||
+ | Kita memberitahukan kode terminasi melalui opsi --delimiter : | ||
− | sudo mysqlslap --user= | + | sudo mysqlslap --user=root --password=123456 --host=localhost --concurrency=20 --iterations=10 --create-schema=employees \ |
--query="SELECT * FROM employees;SELECT * FROM titles;SELECT * FROM dept_emp;SELECT * FROM dept_manager; \ | --query="SELECT * FROM employees;SELECT * FROM titles;SELECT * FROM dept_emp;SELECT * FROM dept_manager; \ | ||
SELECT * FROM departments;" --delimiter=";" --verbose | SELECT * FROM departments;" --delimiter=";" --verbose | ||
− | + | Walaupun menggunakan iterasi yang sama, kinerja perintah multiple SELECT akan jauh lebih lambat (averaging 11.6 seconds vs. 10.4 seconds): | |
− | Benchmark | + | Benchmark |
− | + | Average number of seconds to run all queries: 11.640 seconds | |
− | + | Minimum number of seconds to run all queries: 11.395 seconds | |
− | + | Maximum number of seconds to run all queries: 13.239 seconds | |
− | + | Number of clients running queries: 20 | |
− | + | Average number of queries per client: 5 | |
− | |||
− | + | Production SQL statement bisa menjadi sangat rumit. | |
+ | Akan lebih mudah untuk menambahkan complicated SQL statement ke script yang akan di cobakan untuk test. | ||
+ | Kita cukup memberitahukan mysqlslap untuk membaca script tersebut. | ||
− | + | Untuk memberikan contoh, mari kita membuat script file untuk perintah SQL sebagai berikut | |
+ | sudo echo "SELECT * FROM employees;SELECT * FROM titles;SELECT * FROM dept_emp;SELECT * FROM dept_manager;SELECT * FROM departments;" > ~/select_query.sql | ||
sudo cp ~/select_query.sql /mysqlslap_tutorial/ | sudo cp ~/select_query.sql /mysqlslap_tutorial/ | ||
− | + | File select_query.sql mempunyai lima SELECT statements. | |
− | + | mysqlslap dapat mem-paralel query. | |
+ | Kita dapat men-set jumlah query untuk setiap test client. | ||
+ | mysqlslap menset ini melalui opsi --number-of-queries option. | ||
+ | Jadi jika kita mempunyai 50 connection and 1000 query, setiap client akan menjalankan 20 query. | ||
− | + | Kita juga akan menggunakan switch --debug-info, yang akan memberikan indikasi sumber daya komputasi yang digunakan. | |
− | + | sudo mysqlslap --user=root --password=123456 --host=localhost --concurrency=20 --number-of-queries=1000 --create-schema=employees \ | |
− | |||
− | sudo mysqlslap --user= | ||
--query="/mysqlslap_tutorial/select_query.sql" --delimiter=";" --verbose --iterations=2 --debug-info | --query="/mysqlslap_tutorial/select_query.sql" --delimiter=";" --verbose --iterations=2 --debug-info | ||
− | + | Setelah perintah ini selesai, kita akan melihat hasil yang menarik: | |
− | Benchmark | + | Benchmark |
− | + | Average number of seconds to run all queries: 117.846 seconds | |
− | + | Minimum number of seconds to run all queries: 115.245 seconds | |
− | + | Maximum number of seconds to run all queries: 120.448 seconds | |
− | + | Number of clients running queries: 20 | |
− | + | Average number of queries per client: 50 | |
+ | |||
+ | User time 128.85, System time 73.92 | ||
+ | Maximum resident set size 827056, Integral resident set size 0 | ||
+ | Non-physical pagefaults 11192754, Physical pagefaults 0, Swaps 0 | ||
+ | Blocks in 0 out 0, Messages in 0 out 0, Signals 0 | ||
+ | Voluntary context switches 314596, Involuntary context switches 6382 | ||
+ | Disini waktu yang dibutuhkan untuk melakukan query MySQL adalah 117.8 seconds, mendekati 2 menit. | ||
+ | Ini jelas akan mempengaruhi RAM dan CPU di mesin virtual, | ||
+ | ini juga karena banyak query dar client yang di ulang dua kali. | ||
− | + | Kita juga melihat banyak non-physical page faults. Page fault terhadi ketika data tidak ada di memory dan system harus mengambilnya ke swap file di disk. | |
− | + | Kita juga melihat informasi yang berkaitan dengan CPU, terlihat cukup banyak context switch. | |
− | |||
− | |||
− | |||
− | + | ==CONTOH: Skenario Benchmarking yang praktis dan Capturing Live Queries== | |
− | + | Sejauh ini dalam contoh kita, kita telah menjalankan query terhadap database asli employees. Itu sesuatu yang oleh Database Administrator (DBA) tentu tidak ingin anda lakukan. Dan ada alasan yang jelas untuk itu. Anda tidak ingin menambahkan beban database produksi anda dan anda tidak ingin menjalankan query tes yang mungkin menghapus, memperbarui, atau memasukkan data ke tabel produksi anda. | |
− | |||
− | + | Kami akan menunjukkan cara untuk membuat backup dari database produksi dan menyalinnya ke lingkungan pengujian. Dalam contoh ini itu pada server yang sama, tetapi idealnya anda menyalinnya ke server terpisah dengan kapasitas hardware yang sama. | |
− | + | Lebih penting lagi, kami akan menunjukkan cara untuk merekam live queries dari database produksi dan menambahkannya ke skrip pengujian. Artinya, anda akan mendapatkan pertanyaan dari database produksi, tetapi menjalankan tes terhadap database test. | |
− | + | Langkah-langkah umum adalah sebagai berikut, dan anda dapat menggunakannya untuk tes mysqlslap: | |
− | + | # Copy production database ke test environment. | |
+ | # Konfigurasi MySQL untuk record dan capture semua connection requests dan queries di production database. | ||
+ | # Simulasikan penggunaan yang akan kita coba untuk test. Contoh, kita kita menjalankan shopping cart, kita perlu membeli sesuatu agar mentrigger database query yang sesuati dari aplikasi kita. | ||
+ | # Matikan query logging. | ||
+ | # Lihat query log dan buat catatan dari quary yang akan kita test. | ||
+ | # Buat sebuah test file untuk setiap query yang akan kita test. | ||
+ | # Run test. | ||
+ | # Gunakan output untuk meng-improve performance database. | ||
− | + | Untuk memulai, mari kita backup employees database. Kita akan meletakannya di directory yang berbeda : | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
sudo mkdir /mysqlslap_tutorial/mysqlbackup | sudo mkdir /mysqlslap_tutorial/mysqlbackup | ||
cd /mysqlslap_tutorial/mysqlbackup | cd /mysqlslap_tutorial/mysqlbackup | ||
+ | sudo mysqldump --user=root --password=123456 --host localhost employees > ~/employees_backup.sql | ||
+ | sudo cp ~/employees_backup.sql /mysqlslap_tutorial/mysqlbackup/ | ||
− | + | Jika anda menggunakan server yang berbeda, anda perlu mengcopy employees_backup.sql ke server tersebut. | |
+ | Masuk ke MySQL monitor dan lakukan | ||
− | + | mysql -u root -p123456 | |
+ | |||
+ | CREATE DATABASE employees_backup; | ||
+ | quit; | ||
− | + | Import employees_backup.sql ke MySQL. | |
− | + | sudo mysql -u root -p123456 employees_backup < /mysqlslap_tutorial/mysqlbackup/employees_backup.sql | |
− | + | Di production MySQL database server, enable MySQL general query log dan berikan file name untuk itu. | |
+ | General query log akan menangkap semua connection, disconnection, dan aktifitas query pada MySQL database yang berjalan. | ||
− | + | mysql -u root -p123456 | |
− | + | SET GLOBAL general_log=1, general_log_file='capture_queries.log'; | |
+ | quit; | ||
− | |||
− | + | Sekarang lakukan query yang akan kita test pada MySQL server production. | |
+ | Pada contoh ini, kita akan menjalankan query dari command line. | ||
+ | Akan tetapi, kita dapat saja men-generate query dari aplikasi kita daripada menjalankannya secara langsung. | ||
+ | Jika kita mempunyai proses yang lambat atau halaman web yang akan di test, kita sebaiknya run proses tersebut atau akses ke web tersebut sekarang. | ||
+ | Contoh, jika kita menjalankan shopping cart, kita ingin menjalankan / menyelesaikan proses itu sekarang, ini akan men-trigger query yang sesuai di database server. | ||
− | + | Berikut ini adalah query yang akan kita run di MySQL server production pada database employees : | |
− | + | mysql -u root -p123456 | |
− | |||
− | + | USE employees; | |
+ | SELECT e.first_name, e.last_name, d.dept_name, t.title, t.from_date, t.to_date FROM employees e INNER JOIN dept_emp de ON e.emp_no=de.emp_no INNER JOIN departments d ON de.dept_no=d.dept_no INNER JOIN titles t ON e.emp_no=t.emp_no ORDER BY e.first_name, e.last_name, d.dept_name, t.from_date; | ||
− | + | Output: | |
− | + | 489903 rows in set (4.02 sec) | |
− | + | Selesai menjalankan query, matikan general logging: | |
− | + | SET GLOBAL general_log=0; | |
+ | quit; | ||
− | |||
− | + | Pastikan log dimatikan setelah selesai test. | |
+ | Jika log tetap nyala, akan menyebabkan proses testing menjadi lebih berat. | ||
+ | Cek file log yang berada di directory /var/lib/mysql : | ||
sudo ls -l /var/lib/mysql/capt* | sudo ls -l /var/lib/mysql/capt* | ||
− | -rw-rw---- | + | -rw-rw---- 1 mysql mysql 949 Jun 8 06:09 /var/lib/mysql/capture_queries.log |
− | + | Copy file tersebut ke MySQL test directory. | |
+ | Jika kita menggunakan server yang berbeda untuk testing, copy ke server tersebut. | ||
− | sudo cp /var/lib/mysql/capture_queries.log /mysqlslap_tutorial/ | + | sudo cp /var/lib/mysql/capture_queries.log /mysqlslap_tutorial/ |
− | + | Cek isi terakhir file log, | |
sudo tail /mysqlslap_tutorial/capture_queries.log | sudo tail /mysqlslap_tutorial/capture_queries.log | ||
− | + | Output: | |
− | + | 41 Query show databases | |
− | + | 41 Query show tables | |
− | + | 41 Field List departments | |
− | + | 41 Field List dept_emp | |
− | + | 41 Field List dept_manager | |
− | + | 41 Field List employees | |
− | + | 41 Field List salaries | |
− | + | 41 Field List titles | |
− | + | 41 Query SELECT e.first_name, e.last_name, d.dept_name, t.title, t.from_date, t.to_date FROM employees e INNER JOIN dept_emp de ON e.emp_no=de.emp_no INNER JOIN departments d ON de.dept_no=d.dept_no INNER JOIN titles t ON e.emp_no=t.emp_no ORDER BY e.first_name, e.last_name, d.dept_name, t.from_date | |
− | + | 150608 6:09:42 41 Query SET GLOBAL general_log=0 | |
− | |||
− | + | Log akan memperlihatkan perintah SQL dan timestamp. | |
+ | Perintah SQL SELECT yang ada di akhir file yang kita tertarik. | ||
+ | Perintah ini yang ingin kita tangkap dan akan di buat replikasi untuk test-nya. | ||
+ | Dalam contoh ini, kita sudah mengetahui perintah SQL SELECT tersebut yang kita gunakan. | ||
+ | Tapi di production server yang sebenarnya, kita tidak akan mengetahui dan cara ini sangat bermanfaat untuk mengetahui query bermasalah yang dijalankan pada server production. | ||
− | + | Perlu di catat, jika kita run / trigger query yang berbeda saat melakukan logging, file log akan sangat berbeda isinya. | |
+ | Pada skenario yang real, file log akan berisi banyak catatan / entry dari berbagai sambungan. | ||
+ | Tugas kita adalah mencari query yang membuat masalah. | ||
+ | Kita dapat saja mencatat semua query yang ada, me-list-nya dan menjalankan-nya di database yang akan di test. | ||
− | + | Untuk setiap query yang akan di test, kita copy ke file dengan akhiran .sql. | |
− | + | Contoh: | |
− | sudo vi /mysqlslap_tutorial/capture_queries.sql | + | sudo vi /mysqlslap_tutorial/capture_queries.sql |
− | + | Isi dengan MySQL query yang akan kita gunakan untuk test, tanpa line break tanpa semicolon di akhi | |
− | SELECT e.first_name, e.last_name, d.dept_name, t.title, t.from_date, t.to_date FROM employees e INNER JOIN dept_emp de ON e.emp_no=de.emp_no INNER JOIN departments d ON de.dept_no=d.dept_no INNER JOIN titles t ON e.emp_no=t.emp_no ORDER BY e.first_name, e.last_name, d.dept_name, t.from_date | + | SELECT e.first_name, e.last_name, d.dept_name, t.title, t.from_date, t.to_date FROM employees e INNER JOIN dept_emp de ON e.emp_no=de.emp_no INNER JOIN departments d ON de.dept_no=d.dept_no INNER JOIN titles t ON e.emp_no=t.emp_no ORDER BY e.first_name, e.last_name, d.dept_name, t.from_date |
− | + | Selanjutnya, pastikan hasil query tidak di cached. | |
+ | Kembali ke MySQL monitor, jalankan perintah berikut: | ||
− | + | mysql -u root -p123456 | |
− | + | RESET QUERY CACHE; | |
+ | quit | ||
− | + | Sekarang coba menjalankan mysqlslap dengan script file. | |
+ | Pastikan kita menggunakan script file yang benar di parameter --query . | ||
+ | Kita akan menggunakan hanya 10 concurrent connections dan mengulang dua kali. | ||
+ | Run di server test: | ||
− | + | sudo mysqlslap --user=root --password=123456 --host=localhost --concurrency=2 --iterations=2 \ | |
+ | --create-schema=employees_backup --query="/mysqlslap_tutorial/capture_queries.sql" --verbose | ||
− | + | Output: | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | Benchmark | |
+ | Average number of seconds to run all queries: 68.692 seconds | ||
+ | Minimum number of seconds to run all queries: 59.301 seconds | ||
+ | Maximum number of seconds to run all queries: 78.084 seconds | ||
+ | Number of clients running queries: 10 | ||
+ | Average number of queries per client: 1 | ||
+ | |||
+ | ===Bagaimana kita dapat memperbaiki benchmark?=== | ||
+ | |||
+ | Kita akan perlu familiar dengan query MySQL untuk menilai apa yang sedang dilakukan saat query. | ||
− | + | Melihat query yang dilakukan, kita dapat melihat bahwa query melalukan sejumlah join pada multiple table. Query memperlihatkan employee job histories dan untuk melakukan itu, query harus join beberapa table by empno field. Query juga menggunakan deptno field untuk join, akan tetapi karena hanya sedikit departement record, kita akan mengabaikan ini. Karena banyak empno entries di database, sangat logical untuk berasumsi bahwa dengan membuat index dari empno field akan meng-improve query. | |
− | + | Dengan banyak praktek, setelah kita menemukan query yang menyebabkan server menjadi lambat (ini dengan pertolongan mysqlslap), kita dapat melakukan assessment tentang query berbasis pada pengetahuan MySQL dan database yang kita miliki. | |
− | + | Selanjutnya, kita akan berusaha untuk memperbaiki database atau query yang akan di jalankan padanya. | |
− | + | Pada kasus ini, mari kita tambahkan index seperti dijelaskan di atas. | |
+ | Kita akan membuat tiga index pada empno. | ||
+ | Satu index akan dibuat pada empno field di employees table. | ||
+ | Satu index akan dibuat pada empno field di deptemp table, | ||
+ | dan index terakhir pada emp_no field pada title table. | ||
− | |||
− | + | mysql -u root -p123456 | |
USE employees_backup; | USE employees_backup; | ||
Line 531: | Line 567: | ||
CREATE INDEX dept_emp_empno ON dept_emp(emp_no); | CREATE INDEX dept_emp_empno ON dept_emp(emp_no); | ||
CREATE INDEX titles_empno ON titles(emp_no); | CREATE INDEX titles_empno ON titles(emp_no); | ||
+ | quit; | ||
− | + | Kembali ke terminal, jalankan mysqlslap dengan paramter yang sama, kita akan melihat benchmark yang berbeda. | |
− | sudo mysqlslap --user=sysadmin --password --host=localhost --concurrency= | + | sudo mysqlslap --user=sysadmin --password --host=localhost --concurrency=2 --iterations=2 --create-schema=employees_backup \ |
--query="/mysqlslap_tutorial/capture_queries.sql" --verbose | --query="/mysqlslap_tutorial/capture_queries.sql" --verbose | ||
− | Benchmark | + | Output: |
− | + | ||
− | + | Benchmark | |
− | + | Average number of seconds to run all queries: 55.869 seconds | |
− | + | Minimum number of seconds to run all queries: 55.706 seconds | |
− | + | Maximum number of seconds to run all queries: 56.033 seconds | |
+ | Number of clients running queries: 10 | ||
+ | Average number of queries per client: 1 | ||
+ | |||
+ | Kita akan melihat bahwa terjadi perbaikan di average, minimum, dan maximum time untuk menjalankan query. Dari yang tadinya rata2 68 seconds, query sekarang di jalankan dalam 55 seconds. Ini perbaikan 13 seconds untuk beban yang sama. | ||
+ | |||
+ | Karena perubahan database menghasilkan hasil yang baik di lingkungan test, kita dapat menggunakannya di production database server. | ||
+ | Perlu di ingat bahwa perubahan database selalu ada keuntungan dan kerugian. | ||
+ | |||
+ | Kita dapat mengulangi proses dari perintah test dan improvement di semua query yang kita lihat di log. | ||
+ | |||
+ | ==Troubleshooting - mysqlslap tidak menghasilkan Output== | ||
− | + | Jika perintah test tidak menghasilkan outout, ini adalah indikasi bahwa sumber daya / resource pada server sudah habis. | |
+ | Simptom seperti tidak ada Benchmark output, server mungkin hang atau error seperti | ||
− | + | mysqlslap: Error when storing result: 2013 Lost connection to MySQL server during query. | |
− | + | Kita dapat mencoba test dengan parameter --concurrency atau --iterations yang lebih kecil. | |
− | + | Alternatif lain, kita dapat meng-upgrade test server. | |
− | + | Ini adalah cara yang baik untuk mengetahui limit dari kapasitas database server yang kita miliki. | |
− | + | ==Penutup== | |
− | + | mysqlslap adalah tool yang simple, light-weight dan sangat mudah digunakan yang terintegrasi dalam engine MySQL database. | |
− | |||
− | mysqlslap | + | Pada tutorial ini, kita dapat melihat bagaimana menggunakan mysqlslap dengan berbagai opsi-nya pada database contoh / sample. |
+ | Kita dapat men-download berbagai sample database pada MySQL site dan mem-praktekan-nya. | ||
− | + | Jangan pernah menjalankan / run test di production database server. | |
The last use case in this tutorial involved only one query. While we improved the performance of that query somewhat by adding extra indexes to all three tables, the process may not be so simple in real life. Adding extra indexes can sometimes degrade system performance and DBAs often need to weigh the benefits of adding an extra index against the performance cost it may incur. | The last use case in this tutorial involved only one query. While we improved the performance of that query somewhat by adding extra indexes to all three tables, the process may not be so simple in real life. Adding extra indexes can sometimes degrade system performance and DBAs often need to weigh the benefits of adding an extra index against the performance cost it may incur. | ||
− | Real life testing | + | Skenario Real life testing biasanya lebih kompleks, tapi ini harusnya cukup memberikan tool yang dibutuhkan untuk memulai test dan memperbaiki performance database. |
==Referensi== | ==Referensi== | ||
* https://www.digitalocean.com/community/tutorials/how-to-measure-mysql-query-performance-with-mysqlslap | * https://www.digitalocean.com/community/tutorials/how-to-measure-mysql-query-performance-with-mysqlslap |
Latest revision as of 07:23, 8 June 2015
mysqlslap dapat meng-emulasi sejumlah besar koneksi klien meng-hit server database pada saat yang sama. Parameter pengujian dapat beban sepenuhnya dikonfigurasi dan hasil dari tes berjalan yang berbeda dapat digunakan untuk menyempurnakan desain database atau sumber daya perangkat keras.
Dalam tutorial ini kita akan belajar bagaimana menggunakan mysqlslap untuk menguji beban database MySQL dengan beberapa query dasar dan melihat bagaimana benchmarking dapat membantu kita dalam menyempurnakan query tersebut. Setelah beberapa demonstrasi dasar, kita akan menjalankan melalui skenario pengujian yang cukup realistis di mana kita membuat copy dari database yang sudah ada untuk pengujian, mengumpulkan pertanyaan dari log, dan menjalankan tes dari script.
Jika anda tertarik untuk pembandingan server database tertentu, anda harus menguji pada server dengan spesifikasi yang sama dan dengan salinan dari database anda yang terinstal.
Jika anda ingin menjalankan melalui tutorial ini untuk tujuan belajar dan melaksanakan setiap perintah di dalamnya, kami sarankan setidaknya 2 GB Droplet. Karena perintah dalam tutorial ini dimaksudkan untuk memaksa server, anda mungkin menemukan mereka akan time out pada server yang lebih kecil.
Sampel output dalam tutorial ini diproduksi dalam berbagai cara untuk mengoptimalkan contoh untuk mengajar.
Langkah Pertama - Install MySQL di sistem yang akan di test
Instalasi MySQL di Ubuntu relatif sederhana hanya menggunakan perintah,
apt-get update apt-get install -y mysql-server mysql-client
Biasanya akan di tanya root password. Jika kita masih belajar dapat memasukan root password
123456
Agar lebih aman lakukan secure installation
mysql_secure_installation
Jawab
Enter current password for root (enter for none): OK, successfully used password, moving on... Change the root password? [Y/n] n ... skipping. Remove anonymous users? [Y/n] ... Success! Disallow root login remotely? [Y/n] Y ... Success! Remove test database and access to it? [Y/n] Y ... Success! Reload privilege tables now? [Y/n] Y ... Success!
Untuk menjalankan MySQL Server cukup menggunakan perintah
/etc/init.d/mysql restart
Langkah Kedua - Install Sample Database
Kita perlu mengambil contoh database untuk test.
apt-get install bzip2 mkdir -p /mysqlslap_tutorial cd /mysqlslap_tutorial sudo wget https://launchpad.net/test-db/employees-db-1/1.0.6/+download/employees_db-full-1.0.6.tar.bz2 sudo bzip2 -dfv employees_db-full-1.0.6.tar.bz2 sudo tar -xf employees_db-full-1.0.6.tar
Kita menggunakan database employees dengan 3 juta entry jadi cukup mendekati kondisi di lapangan.
cd /mysqlslap_tutorial/employees_db ls -lh
total 161M -rw-r--r-- 1 501 staff 752 Mar 30 2009 Changelog -rw-r--r-- 1 501 staff 6,4K Okt 9 2008 employees_partitioned2.sql -rw-r--r-- 1 501 staff 7,5K Peb 6 2009 employees_partitioned3.sql -rw-r--r-- 1 501 staff 5,6K Peb 6 2009 employees_partitioned.sql -rw-r--r-- 1 501 staff 3,8K Nov 28 2008 employees.sql -rw-r--r-- 1 501 staff 241 Jul 30 2008 load_departments.dump -rw-r--r-- 1 501 staff 14M Mar 30 2009 load_dept_emp.dump -rw-r--r-- 1 501 staff 1,1K Jul 30 2008 load_dept_manager.dump -rw-r--r-- 1 501 staff 17M Jul 30 2008 load_employees.dump -rw-r--r-- 1 501 staff 111M Jul 30 2008 load_salaries.dump -rw-r--r-- 1 501 staff 21M Jul 30 2008 load_titles.dump -rw-r--r-- 1 501 staff 3,8K Mar 30 2009 objects.sql -rw-r--r-- 1 501 staff 2,2K Jul 30 2008 README -rw-r--r-- 1 501 staff 4,4K Mar 30 2009 test_employees_md5.sql -rw-r--r-- 1 501 staff 4,4K Mar 30 2009 test_employees_sha.sql
Masukan database tersebut ke mysql
cd /mysqlslap_tutorial/employees_db sudo mysql -u root -p123456 -t < employees.sql
Akan muncul
+-----------------------------+ | INFO | +-----------------------------+ | CREATING DATABASE STRUCTURE | +-----------------------------+ +------------------------+ | INFO | +------------------------+ | storage engine: InnoDB | +------------------------+ +---------------------+ | INFO | +---------------------+ | LOADING departments | +---------------------+ +-------------------+ | INFO | +-------------------+ | LOADING employees | +-------------------+ +------------------+ | INFO | +------------------+ | LOADING dept_emp | +------------------+ +----------------------+ | INFO | +----------------------+ | LOADING dept_manager | +----------------------+ +----------------+ | INFO | +----------------+ | LOADING titles | +----------------+ +------------------+ | INFO | +------------------+ | LOADING salaries | +------------------+
Login ke MySQL dan cek tabel / data yang ada
mysql -u root -p123456
Lakukan
show databases;
Output
+--------------------+ | Database | +--------------------+ | information_schema | | employees | | mysql | | performance_schema | +--------------------+ 4 rows in set (0.00 sec)
use employees; show tables;
Output:
+---------------------+ | Tables_in_employees | +---------------------+ | departments | | dept_emp | | dept_manager | | employees | | salaries | | titles | +---------------------+ 6 rows in set (0.00 sec)
describe titles;
Output:
+-----------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-----------+-------------+------+-----+---------+-------+ | emp_no | int(11) | NO | PRI | NULL | | | title | varchar(50) | NO | PRI | NULL | | | from_date | date | NO | PRI | NULL | | | to_date | date | YES | | NULL | | +-----------+-------------+------+-----+---------+-------+ 4 rows in set (0.00 sec)
select count(*) from titles;
Output:
+----------+ | count(*) | +----------+ | 443308 | +----------+ 1 row in set (0.14 sec)
select count(*) from employees;
Output:
+----------+ | count(*) | +----------+ | 300024 | +----------+ 1 row in set (0.11 sec)
Cek data-data lainnya, untuk keluar ketik
quit;
Langkah ketiga - Menggunakan mysqlslap
Opsi / Fitur mysqlslap bisa di peroleh dari
mysqlslap --help
Beberapa yang penting
--user MySQL username to connect to the database server --password Password for the user account. It's best to leave it blank in command line --host MySQL database server name --port Port number for connecting to MySQL if the default is not used --concurrency The number of simultaneous client connections mysqlslap will emulate --iterations The number of times the test query will be run --create-schema The database where the query will be run --query The query to execute. This can either be a SQL query string or a path to a SQL script file --create The query to create a table. Again, this can be a query string or a path to a SQL file --delimiter The delimiter used to separate multiple SQL statements --engine The MySQL database engine to use (e.g., InnoDB) --auto-generate-sql Lets MySQL perform load testing with its own auto-generated SQL command
CONTOH: Benchmark menggunakan Auto-generated SQL dan Data
sudo mysqlslap --user=root --password=123456 --host=localhost --auto-generate-sql --verbose
Output:
Benchmark Average number of seconds to run all queries: 0.009 seconds Minimum number of seconds to run all queries: 0.009 seconds Maximum number of seconds to run all queries: 0.009 seconds Number of clients running queries: 1 Average number of queries per client: 0
Coba 50 concurrent connections, gunakan auto-generated query run 10 kali:
sudo mysqlslap --user=root --password=123456 --host=localhost --concurrency=50 --iterations=10 --auto-generate-sql --verbose
Benchmark Average number of seconds to run all queries: 0.137 seconds Minimum number of seconds to run all queries: 0.117 seconds Maximum number of seconds to run all queries: 0.159 seconds Number of clients running queries: 50 Average number of queries per client: 0
Coba menggqunakan auto-generated SQL query untuk membuat tabel dengan 5 numeric kolom dan 20 character setiap kolom.
Kita akan mensimulasi 50 client connection dan test diulangi 100 kali,
sudo mysqlslap --user=root --password=123456 --host=localhost --concurrency=50 --iterations=100 --number-int-cols=5 --number-char-cols=20 \ --auto-generate-sql --verbose
Jika kita berada di terminal MySQL monitor, padea saat test ini berjalan kita dapat melihat,
show databases;
Output:
+--------------------+ | Database | +--------------------+ | information_schema | | employees | | mysql | | mysqlslap | | performance_schema | +--------------------+ 5 rows in set (0.01 sec)
Hasil benchmark
Benchmark Average number of seconds to run all queries: 0.400 seconds Minimum number of seconds to run all queries: 0.349 seconds Maximum number of seconds to run all queries: 0.713 seconds Number of clients running queries: 50 Average number of queries per client: 0
pada saat test ini selesai, mysqlslap akan membuang database test-nya
show databases;
+--------------------+ | Database | +--------------------+ | information_schema | | employees | | mysql | | performance_schema | +--------------------+ 4 rows in set (0.00 sec)
CONTOH: Benchmarking dengan Custom Queries
Auto-generated SQL baik untuk meng-evaluasi sumber daya fisik pada server. Ini akan sangat baik untuk mengetahui level beban yang dapat di terima server.
Jika kita ingin melakukan troubleshoot performance untuk aplikasi spesifik yang tergantung database, dan kita ingin melakukan real query test. Query ini kemungkinan akan datang dari web atau server aplikasi.
Kita akan menggunakan database employees di --create-scheme untuk melakukan query ke table "dept_emp",
sudo mysqlslap --user=root --password=123456 --host=localhost --concurrency=50 --iterations=10 --create-schema=employees \ --query="SELECT * FROM dept_emp;" --verbose
Jika berjalan dengan baik, maka akan keluar kira-kira,
Benchmark Average number of seconds to run all queries: 10.401 seconds Minimum number of seconds to run all queries: 9.613 seconds Maximum number of seconds to run all queries: 13.575 seconds Number of clients running queries: 50 Average number of queries per client: 1
(Catatan: Jika query membuat hang atau lebih dari 10 menit tanpa output, coba kurangi --concurrency and/or --iterations, atau coba di server yang lebih besar)
Selanjutnya, kita akan menggunakan multiple SQL statements di --query parameter. Terminasi setiap query menggunakan titik koma (semicolon). Kita memberitahukan kode terminasi melalui opsi --delimiter :
sudo mysqlslap --user=root --password=123456 --host=localhost --concurrency=20 --iterations=10 --create-schema=employees \ --query="SELECT * FROM employees;SELECT * FROM titles;SELECT * FROM dept_emp;SELECT * FROM dept_manager; \ SELECT * FROM departments;" --delimiter=";" --verbose
Walaupun menggunakan iterasi yang sama, kinerja perintah multiple SELECT akan jauh lebih lambat (averaging 11.6 seconds vs. 10.4 seconds):
Benchmark Average number of seconds to run all queries: 11.640 seconds Minimum number of seconds to run all queries: 11.395 seconds Maximum number of seconds to run all queries: 13.239 seconds Number of clients running queries: 20 Average number of queries per client: 5
Production SQL statement bisa menjadi sangat rumit.
Akan lebih mudah untuk menambahkan complicated SQL statement ke script yang akan di cobakan untuk test.
Kita cukup memberitahukan mysqlslap untuk membaca script tersebut.
Untuk memberikan contoh, mari kita membuat script file untuk perintah SQL sebagai berikut
sudo echo "SELECT * FROM employees;SELECT * FROM titles;SELECT * FROM dept_emp;SELECT * FROM dept_manager;SELECT * FROM departments;" > ~/select_query.sql sudo cp ~/select_query.sql /mysqlslap_tutorial/
File select_query.sql mempunyai lima SELECT statements.
mysqlslap dapat mem-paralel query. Kita dapat men-set jumlah query untuk setiap test client. mysqlslap menset ini melalui opsi --number-of-queries option. Jadi jika kita mempunyai 50 connection and 1000 query, setiap client akan menjalankan 20 query.
Kita juga akan menggunakan switch --debug-info, yang akan memberikan indikasi sumber daya komputasi yang digunakan.
sudo mysqlslap --user=root --password=123456 --host=localhost --concurrency=20 --number-of-queries=1000 --create-schema=employees \ --query="/mysqlslap_tutorial/select_query.sql" --delimiter=";" --verbose --iterations=2 --debug-info
Setelah perintah ini selesai, kita akan melihat hasil yang menarik:
Benchmark Average number of seconds to run all queries: 117.846 seconds Minimum number of seconds to run all queries: 115.245 seconds Maximum number of seconds to run all queries: 120.448 seconds Number of clients running queries: 20 Average number of queries per client: 50 User time 128.85, System time 73.92 Maximum resident set size 827056, Integral resident set size 0 Non-physical pagefaults 11192754, Physical pagefaults 0, Swaps 0 Blocks in 0 out 0, Messages in 0 out 0, Signals 0 Voluntary context switches 314596, Involuntary context switches 6382
Disini waktu yang dibutuhkan untuk melakukan query MySQL adalah 117.8 seconds, mendekati 2 menit. Ini jelas akan mempengaruhi RAM dan CPU di mesin virtual, ini juga karena banyak query dar client yang di ulang dua kali.
Kita juga melihat banyak non-physical page faults. Page fault terhadi ketika data tidak ada di memory dan system harus mengambilnya ke swap file di disk. Kita juga melihat informasi yang berkaitan dengan CPU, terlihat cukup banyak context switch.
CONTOH: Skenario Benchmarking yang praktis dan Capturing Live Queries
Sejauh ini dalam contoh kita, kita telah menjalankan query terhadap database asli employees. Itu sesuatu yang oleh Database Administrator (DBA) tentu tidak ingin anda lakukan. Dan ada alasan yang jelas untuk itu. Anda tidak ingin menambahkan beban database produksi anda dan anda tidak ingin menjalankan query tes yang mungkin menghapus, memperbarui, atau memasukkan data ke tabel produksi anda.
Kami akan menunjukkan cara untuk membuat backup dari database produksi dan menyalinnya ke lingkungan pengujian. Dalam contoh ini itu pada server yang sama, tetapi idealnya anda menyalinnya ke server terpisah dengan kapasitas hardware yang sama.
Lebih penting lagi, kami akan menunjukkan cara untuk merekam live queries dari database produksi dan menambahkannya ke skrip pengujian. Artinya, anda akan mendapatkan pertanyaan dari database produksi, tetapi menjalankan tes terhadap database test.
Langkah-langkah umum adalah sebagai berikut, dan anda dapat menggunakannya untuk tes mysqlslap:
- Copy production database ke test environment.
- Konfigurasi MySQL untuk record dan capture semua connection requests dan queries di production database.
- Simulasikan penggunaan yang akan kita coba untuk test. Contoh, kita kita menjalankan shopping cart, kita perlu membeli sesuatu agar mentrigger database query yang sesuati dari aplikasi kita.
- Matikan query logging.
- Lihat query log dan buat catatan dari quary yang akan kita test.
- Buat sebuah test file untuk setiap query yang akan kita test.
- Run test.
- Gunakan output untuk meng-improve performance database.
Untuk memulai, mari kita backup employees database. Kita akan meletakannya di directory yang berbeda :
sudo mkdir /mysqlslap_tutorial/mysqlbackup cd /mysqlslap_tutorial/mysqlbackup sudo mysqldump --user=root --password=123456 --host localhost employees > ~/employees_backup.sql sudo cp ~/employees_backup.sql /mysqlslap_tutorial/mysqlbackup/
Jika anda menggunakan server yang berbeda, anda perlu mengcopy employees_backup.sql ke server tersebut. Masuk ke MySQL monitor dan lakukan
mysql -u root -p123456
CREATE DATABASE employees_backup; quit;
Import employees_backup.sql ke MySQL.
sudo mysql -u root -p123456 employees_backup < /mysqlslap_tutorial/mysqlbackup/employees_backup.sql
Di production MySQL database server, enable MySQL general query log dan berikan file name untuk itu. General query log akan menangkap semua connection, disconnection, dan aktifitas query pada MySQL database yang berjalan.
mysql -u root -p123456
SET GLOBAL general_log=1, general_log_file='capture_queries.log'; quit;
Sekarang lakukan query yang akan kita test pada MySQL server production.
Pada contoh ini, kita akan menjalankan query dari command line.
Akan tetapi, kita dapat saja men-generate query dari aplikasi kita daripada menjalankannya secara langsung.
Jika kita mempunyai proses yang lambat atau halaman web yang akan di test, kita sebaiknya run proses tersebut atau akses ke web tersebut sekarang.
Contoh, jika kita menjalankan shopping cart, kita ingin menjalankan / menyelesaikan proses itu sekarang, ini akan men-trigger query yang sesuai di database server.
Berikut ini adalah query yang akan kita run di MySQL server production pada database employees :
mysql -u root -p123456
USE employees; SELECT e.first_name, e.last_name, d.dept_name, t.title, t.from_date, t.to_date FROM employees e INNER JOIN dept_emp de ON e.emp_no=de.emp_no INNER JOIN departments d ON de.dept_no=d.dept_no INNER JOIN titles t ON e.emp_no=t.emp_no ORDER BY e.first_name, e.last_name, d.dept_name, t.from_date;
Output:
489903 rows in set (4.02 sec)
Selesai menjalankan query, matikan general logging:
SET GLOBAL general_log=0; quit;
Pastikan log dimatikan setelah selesai test.
Jika log tetap nyala, akan menyebabkan proses testing menjadi lebih berat.
Cek file log yang berada di directory /var/lib/mysql :
sudo ls -l /var/lib/mysql/capt*
-rw-rw---- 1 mysql mysql 949 Jun 8 06:09 /var/lib/mysql/capture_queries.log
Copy file tersebut ke MySQL test directory. Jika kita menggunakan server yang berbeda untuk testing, copy ke server tersebut.
sudo cp /var/lib/mysql/capture_queries.log /mysqlslap_tutorial/
Cek isi terakhir file log,
sudo tail /mysqlslap_tutorial/capture_queries.log
Output:
41 Query show databases 41 Query show tables 41 Field List departments 41 Field List dept_emp 41 Field List dept_manager 41 Field List employees 41 Field List salaries 41 Field List titles 41 Query SELECT e.first_name, e.last_name, d.dept_name, t.title, t.from_date, t.to_date FROM employees e INNER JOIN dept_emp de ON e.emp_no=de.emp_no INNER JOIN departments d ON de.dept_no=d.dept_no INNER JOIN titles t ON e.emp_no=t.emp_no ORDER BY e.first_name, e.last_name, d.dept_name, t.from_date 150608 6:09:42 41 Query SET GLOBAL general_log=0
Log akan memperlihatkan perintah SQL dan timestamp.
Perintah SQL SELECT yang ada di akhir file yang kita tertarik.
Perintah ini yang ingin kita tangkap dan akan di buat replikasi untuk test-nya.
Dalam contoh ini, kita sudah mengetahui perintah SQL SELECT tersebut yang kita gunakan.
Tapi di production server yang sebenarnya, kita tidak akan mengetahui dan cara ini sangat bermanfaat untuk mengetahui query bermasalah yang dijalankan pada server production.
Perlu di catat, jika kita run / trigger query yang berbeda saat melakukan logging, file log akan sangat berbeda isinya. Pada skenario yang real, file log akan berisi banyak catatan / entry dari berbagai sambungan. Tugas kita adalah mencari query yang membuat masalah. Kita dapat saja mencatat semua query yang ada, me-list-nya dan menjalankan-nya di database yang akan di test.
Untuk setiap query yang akan di test, kita copy ke file dengan akhiran .sql.
Contoh:
sudo vi /mysqlslap_tutorial/capture_queries.sql
Isi dengan MySQL query yang akan kita gunakan untuk test, tanpa line break tanpa semicolon di akhi
SELECT e.first_name, e.last_name, d.dept_name, t.title, t.from_date, t.to_date FROM employees e INNER JOIN dept_emp de ON e.emp_no=de.emp_no INNER JOIN departments d ON de.dept_no=d.dept_no INNER JOIN titles t ON e.emp_no=t.emp_no ORDER BY e.first_name, e.last_name, d.dept_name, t.from_date
Selanjutnya, pastikan hasil query tidak di cached. Kembali ke MySQL monitor, jalankan perintah berikut:
mysql -u root -p123456
RESET QUERY CACHE; quit
Sekarang coba menjalankan mysqlslap dengan script file. Pastikan kita menggunakan script file yang benar di parameter --query . Kita akan menggunakan hanya 10 concurrent connections dan mengulang dua kali. Run di server test:
sudo mysqlslap --user=root --password=123456 --host=localhost --concurrency=2 --iterations=2 \ --create-schema=employees_backup --query="/mysqlslap_tutorial/capture_queries.sql" --verbose
Output:
Benchmark Average number of seconds to run all queries: 68.692 seconds Minimum number of seconds to run all queries: 59.301 seconds Maximum number of seconds to run all queries: 78.084 seconds Number of clients running queries: 10 Average number of queries per client: 1
Bagaimana kita dapat memperbaiki benchmark?
Kita akan perlu familiar dengan query MySQL untuk menilai apa yang sedang dilakukan saat query.
Melihat query yang dilakukan, kita dapat melihat bahwa query melalukan sejumlah join pada multiple table. Query memperlihatkan employee job histories dan untuk melakukan itu, query harus join beberapa table by empno field. Query juga menggunakan deptno field untuk join, akan tetapi karena hanya sedikit departement record, kita akan mengabaikan ini. Karena banyak empno entries di database, sangat logical untuk berasumsi bahwa dengan membuat index dari empno field akan meng-improve query.
Dengan banyak praktek, setelah kita menemukan query yang menyebabkan server menjadi lambat (ini dengan pertolongan mysqlslap), kita dapat melakukan assessment tentang query berbasis pada pengetahuan MySQL dan database yang kita miliki.
Selanjutnya, kita akan berusaha untuk memperbaiki database atau query yang akan di jalankan padanya.
Pada kasus ini, mari kita tambahkan index seperti dijelaskan di atas. Kita akan membuat tiga index pada empno. Satu index akan dibuat pada empno field di employees table. Satu index akan dibuat pada empno field di deptemp table, dan index terakhir pada emp_no field pada title table.
mysql -u root -p123456
USE employees_backup; CREATE INDEX employees_empno ON employees(emp_no); CREATE INDEX dept_emp_empno ON dept_emp(emp_no); CREATE INDEX titles_empno ON titles(emp_no); quit;
Kembali ke terminal, jalankan mysqlslap dengan paramter yang sama, kita akan melihat benchmark yang berbeda.
sudo mysqlslap --user=sysadmin --password --host=localhost --concurrency=2 --iterations=2 --create-schema=employees_backup \ --query="/mysqlslap_tutorial/capture_queries.sql" --verbose
Output:
Benchmark Average number of seconds to run all queries: 55.869 seconds Minimum number of seconds to run all queries: 55.706 seconds Maximum number of seconds to run all queries: 56.033 seconds Number of clients running queries: 10 Average number of queries per client: 1
Kita akan melihat bahwa terjadi perbaikan di average, minimum, dan maximum time untuk menjalankan query. Dari yang tadinya rata2 68 seconds, query sekarang di jalankan dalam 55 seconds. Ini perbaikan 13 seconds untuk beban yang sama.
Karena perubahan database menghasilkan hasil yang baik di lingkungan test, kita dapat menggunakannya di production database server. Perlu di ingat bahwa perubahan database selalu ada keuntungan dan kerugian.
Kita dapat mengulangi proses dari perintah test dan improvement di semua query yang kita lihat di log.
Troubleshooting - mysqlslap tidak menghasilkan Output
Jika perintah test tidak menghasilkan outout, ini adalah indikasi bahwa sumber daya / resource pada server sudah habis. Simptom seperti tidak ada Benchmark output, server mungkin hang atau error seperti
mysqlslap: Error when storing result: 2013 Lost connection to MySQL server during query.
Kita dapat mencoba test dengan parameter --concurrency atau --iterations yang lebih kecil. Alternatif lain, kita dapat meng-upgrade test server.
Ini adalah cara yang baik untuk mengetahui limit dari kapasitas database server yang kita miliki.
Penutup
mysqlslap adalah tool yang simple, light-weight dan sangat mudah digunakan yang terintegrasi dalam engine MySQL database.
Pada tutorial ini, kita dapat melihat bagaimana menggunakan mysqlslap dengan berbagai opsi-nya pada database contoh / sample. Kita dapat men-download berbagai sample database pada MySQL site dan mem-praktekan-nya.
Jangan pernah menjalankan / run test di production database server.
The last use case in this tutorial involved only one query. While we improved the performance of that query somewhat by adding extra indexes to all three tables, the process may not be so simple in real life. Adding extra indexes can sometimes degrade system performance and DBAs often need to weigh the benefits of adding an extra index against the performance cost it may incur.
Skenario Real life testing biasanya lebih kompleks, tapi ini harusnya cukup memberikan tool yang dibutuhkan untuk memulai test dan memperbaiki performance database.