-
JMeter를 이용한 JDBC 테스트MySQL_Section/운영 2014. 11. 13. 15:58
JMeter를 이용한 JDBC 테스트 + [programming] | 2013/07/26 17:13 DBMS의 성능 지표를 나타내는 여러 기준이 있지만 그 중 가장 대표적인 것 중 하나가 SysBench 입니다.
SysBench는 MySQL Sever Benchmarking으로 만들어 졌지만 이제는 다양한 database 성능 테스트를 지원하고, CPU, Threads, Mutex, Memory, File I/O 성능 테스트 까지 그 영역을 넓혀가고 있는 중입니다.
하지만 SysBench는 특정 쿼리를 통한 성능 테스트가 불가능 하며, GUI 미지원 및 결과 레포트의 부실함 등의 한계를 가지고 있어서 JMeter를 이용한 JDBC 벤치마크를 만들어 보도록 하겠습니다.
Sysbench OLTP Bechmarking
SysBench OLTP 테스트를 MySQL을 기준으로 설명 드리면, sbtest라는 Database 내에 sbtest라는 Table을 아래와 같은 구조로 생성하여 미리 지정된 형태의 Query를 통해 성능 테스트를 수행합니다.
mysql> desc sbtest;
+-------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| k | int(10) unsigned | NO | MUL | 0 | |
| c | char(120) | NO | | | |
| pad | char(60) | NO | | | |
+-------+------------------+------+-----+---------+----------------+
Transactional 모드 테스트는 위의 테이블에 대해서 아래의 쿼리를 랜덤으로 실행하게 됩니다.
- Point queries :
SELECT c FROM sbtest WHERE id=N
- Range queries :
SELECT c FROM sbtest WHERE id BETWEEN N AND M
- Range SUM() queries :
SELECT SUM(K) FROM sbtest WHERE id BETWEEN N and M
- Range ORDER BY queries :
SELECT c FROM sbtest WHERE id between N and M ORDER BY c
- Range DISTINCT queries :
SELECT DISTINCT c FROM sbtest WHERE id BETWEEN N and M ORDER BY c
- UPDATEs on index column :
UPDATE sbtest SET k=k+1 WHERE id=N
- UPDATEs on non-index column :
UPDATE sbtest SET c=N WHERE id=M
- DELETE queries :
DELETE FROM sbtest WHERE id=N
- INSERT queries :
INSERT INTO sbtest VALUES (...)
Non-Transactional 모드 테스트는 위의 쿼리들 중 Point, UPDATEs on index, UPDATEs on non-index, DELETE, INSERT queries 만 이용합니다.
그럼 위와 같은 테스트를 할 수 있게 JMeter를 설정해 보겠습니다.
JMeter JDBC Test 구성
JMeter와 PlugIn이 모두 설치되어 있다고 가정하고, SysBench와 동일한 테스트가 가능한 JMeter 테스트를 만들어 보겠습니다.
일단 Thread Group을 추가하겠습니다. Thread Group은 Test Plan의 시작 포인트로 모든 Controller와 Sampler는 이 Thread Group 아래에 있어야 합니다.
기본 Thread Group을 사용해도 되지만, 저는 PlugIn에 포함된 Ultimate Thread Group을 선택했습니다.
Add Row를 선택해 Threads Schedule을 추가하고 Start Threads Count와 Hold Load For, sec 등을 수정해 부하 테스트를 위한 connection 수와 측정 시간들을 조정합니다.
JDBC 테스트 이기 때문에 Thread Count는 Connection의 개수가 되며 Hold Load For,sec는 테스트 시간이 됩니다.
이제 이 Thread Group 아래에 위에서 언급한 JDBC Connection Configuration을 아래와 같이 추가합니다.
이 JDBC Connection Configuration은 우리가 Test할 DBMS의 정보 및 Connection Pool 정보를 담게 됩니다.
Variable Name은 이후 Test Query들이 어느 JDBC Connection을 이용할 지를 결정하는 기준 Name이 됩니다.
만약 여러 DBMS가 있다면 이 Variable Name을 이용하여 구분할 수 있습니다.
Connection Pool 및 Connection 정보를 설정합니다.
위의 예에서는 MySQL DBMS를 이용했기 때문에 com.mysql.jdbc.Driver로 설정하였습니다.
하지만 JMeter는 기본적으로 JDBC Driver를 포함하지 않기 때문에 각 DBMS에 해당하는 JDBC Driver를 JMeter의 jar PATH (apache-jmeter-2.9\lib 등)에 추가해 주어야 합니다.
다음은 SysBench와 같이 여러 Test Query들 중 Random하게 골라 테스트를 하기 위해 아래와 같이 Random Controller를 추가해 줍니다.
Random Controller는 하위의 여러 Sampler 중 하나를 Random하게 실행해 줍니다.
이 Random Controller 아래로 JDBC Request Sampler를 등록합니다.
Sampler는 JMeter에서 실제적인 일을 하는 녀석들입니다. 위에서 보는 바와 같이 JMeter는 여러 가지의 Test를 가능하도록 여러 Sampler를 제공하고 있으며 이 각각의 Sampler들이 Result를 발생 시키고, Listener를 통해 그 결과를 여러가지 형태로 볼 수 있습니다.
Random Controller 아래에 JDBC Request를 추가하여 아래와 같이 Test할 SQL을 생성합니다.
Name에 적당한 이름을 넣고, Variable Name에 앞서 설정한 JDBC Connection Configuration의 Variable Name을 입력합니다.
Query Type은 Prepared Select Statement로 선택하고, SysBench의 Point Queries와 같은 Query문을 넣어줍니다.
이 Query문이 실행 될 때 필요한 파라미터 변수를 Random으로 생성하기 위해 Parameter values에 ${__Random(1,20000000,id)} , Parameter types에 INTEGER 를 입력합니다.
1 ~ 20000000 의 숫자 중 랜덤으로 한 숫자를 선택해 id 변수에 할당하고, INTEGER 타입으로 지정한다는 내용입니다.
참고로 JMeter가 제공하는 여러 자체 함수가 있습니다.
해당 내용은 Options - Function Help Dialog 메뉴 또는 Ctrl+F1 단축키를 통해 확인 할 수 있습니다.
상세 정보는 JMeter 매뉴얼의 Functions and Variables를 참고합니다.
이런 방법으로 SysBench에서 사용하는 Query 들을 등록합니다.
이렇게 Test 할 JDBC Samler들을 등록하고,
마지막으로 Sampler들의 결과를 취합할 Listener를 등록합니다.
저는 JMeter PlugIn에서 제공되는 Transactions per Second와 Response Times Over Time를 이용해 TPS와 응답시간을 확인할 수 있도록 하겠습니다.
이렇게 구성된 최종 Test Plan의 모습은 아래와 같은 구조를 이루게 됩니다.
Test 방법
자체 Query를 테스트 한다면 JDBC Request를 통해 테스트하면 되지만 우리는 SysBench와 같은 테스트를 하기로 하였으므로 SysBench에서 사용하는 sbtest라는 테이블과 초기 적재 데이터가 필요합니다.
간단히 SysBench를 설치해서 작업하도록 하겠습니다.
먼저 (Linux 서버를 기준으로) SysBench를 설치하도록 합니다. Fedora 계정이라 가정하고 (다른 계열도 찾아보면 쉽게 설치 가능합니다) 아래와 같이 RPM을 추가합니다.
~]# rpm -Uvh --force http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
현재 정식 yum 업데이트에는 sysbench가 포함되어 있지 않기 때문에 epel 프로젝트를 yum repository에 추가하는 것입니다. (sysbench 외에 여러가지 유용한 테스트 프로젝트들이 존재하기 때문에 적용하고 필요한 프로젝트를 검색해 볼 것을 권장합니다)
yum repository가 추가되었으면 아래와 같이 간단히 yum을 통해 sysbench를 설치합니다.
~]# yum install sysbench
정상적으로 설치가 되면 이제 테스트 할 DBMS에 접속하여 sbtest라는 database를 생성해 줍니다.
저는 MySQL을 테스트할 것이기에 mysql console을 통해 아래와 같이 작업하겠습니다.
mysql> create database sbtest;
이제 다시 linux 콘솔로 나와서 기본 데이터를 적재하기 위해 sysbench 명령어를 통해 아래와 같이 초기화를 해 줍니다.
~]# sysbench --test=oltp --db-driver=mysql --mysql-host={mysql-host-url} --mysql-user={mysql-userid} --mysql-password='{mysql-user-password}' --oltp-table-size=1000000 --mysql-engine-trx=yes --oltp-reconnect-mode=transaction --mysql-table-engine=innodb prepare
MySQL OLTP 테스트를 위해 1000000 row의 innodb 테이블을 적재한다는 뜻입니다.
상세 옵션은 SysBench 매뉴얼을 참조합니다.
참고적으로 SysBench를 통한 OLTP 테스트 방법은 아래와 같이 하며 (16 thread로 1000000번 Transaction 모드로 테스트)
~]# sysbench --test=oltp --num-threads=16 --db-driver=mysql --mysql-host={mysql-host-url} --mysql-user={mysql-userid} --mysql-password='{mysql-user-password}' --oltp-table-size=1000000 --mysql-engine-trx=yes --oltp-reconnect-mode=transaction --mysql-table-engine=innodb --max-requests=1000000 run
테스트 이후 데이터 삭제는 아래와 같이 실행 합니다.
~]# sysbench --test=oltp --db-driver=mysql --mysql-host={mysql-host-url} --mysql-user={mysql-userid} --mysql-password='{mysql-user-password}' cleanup
JMeter로 테스트하기 위해 일단 Prepare까지만 실행하고, JDBC Connection Configuration에 접속할 DBMS 정보를 적용하여 테스트를 실행하면 됩니다.
위에서 설정한 대로 테스트를 하면 아래와 같은 결과 차트를 볼 수 있습니다.
'MySQL_Section > 운영' 카테고리의 다른 글
MySQL Partition 기능과 활용 (0) 2014.11.13 MySQL Index 관리편 (0) 2014.11.13 mysql-admin-cookbook 책에서 'Monitoring and Analyzing MySQL Installation' (0) 2014.11.13 MySQL을 NOSQL 로 사용하기 (0) 2014.11.13 Mysql max_connect_errors (0) 2014.11.13