TPC - The Transaction Processing Performance Council
TPC는 OLTP database의 성능 측정(benchmark)를 위해 만들어졌고, TPC-C는 이 중 복잡한 트랜잭션을 처리하는 상황을 시뮬레이션 할 수 있는 database의 table 구조
TPC-C table 구조
테이블의 이름에서 확인 할 수 있듯이 일반적인 e-commerce 서비스 table 구조와 유사한 형태를 가지고 있다.
위 테이블에 많은 데이터를 집어 넣으면서 성능을 측정 할 수 있는데 생성할 트랜잭션의 갯수 역시 정해져있다.
Warehouse(W)에 따른 생성되는 데이터의 갯수
창고(Warehouse) 하나가 생성되면 약 30,000개의 주문(Order)가 생기는 식으로 계산할 수 있다.
tpcc-mysql 을 이용해 MySQL에 Warehouse가 한 개인 데이터를 생성해보자.
mac을 이용해서 tpcc-mysql를 빌드했을 때 에러가 발생하여 docker-compose를 이용해 테스트를 진행했다.
tpcc-mysql docker image 만들기
$ git clone https://github.com/Percona-Lab/tpcc-mysql.git
$ cd tpcc-mysql
$ docker build . -t tpcc-mysql
$ docker images
...
tpcc-mysql latest
...
docker-compose를 이용해 mysql과 tpcc-mysql 실행하기
docker-compose.yml
version: "3"
services:
mysql:
image: mysql:5.7
environment:
MYSQL_DATABASE: tpcc
MYSQL_ROOT_PASSWORD: root
MYSQL_ROOT_HOST: '%'
ports:
- 3306:3306
volumes:
- mysql_volume:/var/lib/mysql
tpcc:
image: tpcc-mysql:latest
command: tail -f /dev/null
links:
- mysql
volumes:
mysql_volume:
mysql container가 재시작 된 이후에도 데이터를 보존하기 위해 docker volume을 사용했다.
$ docker-compose up -d
Creating network "tpcc-mysql_default" with the default driver
Creating tpcc-mysql_mysql_1 ... done
Creating tpcc-mysql_tpcc_1 ... done
$ docker ps
IMAGE COMMAND CREATED STATUS PORTS NAMES
eb2faaa6072f tpcc-mysql:latest "tail -f /dev/null" 13 seconds ago Up 12 seconds tpcc-mysql_tpcc_1
9ecafd85f8bb mysql:5.7 "docker-entrypoint.s…" 14 seconds ago Up 12 seconds 0.0.0.0:3306->3306/tcp, 33060/tcp tpcc-mysql_mysql_1
docker-compose를 통해 mysql과 tpcc-mysql 을 실행했다면 tpcc-mysql으로 들어가 benchmark 작업을 수행할 수 있다.
$ docker exec -it <tpcc-mysql Container ID> bash
$ root@eb2faaa6072f:/tpcc-mysql#
이제 Database와 Table을 만들어 보자.
# tpcc1 database 생성
$ mysqladmin create tpcc1 -hmysql -uroot -proot
mysqladmin: [Warning] Using a password on the command line interface can be insecure.
# tpcc1에 table 생성
$ mysql tpcc1 -hmysql -uroot -proot < create_table.sql
mysql: [Warning] Using a password on the command line interface can be insecure.
docker exec 를 통해 tpcc-mysql cotainer에 접속했듯이 mysql container에 접속하면 생성된 table을 확인 할 수 있다.
mysql> use tpcc1;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+-----------------+
| Tables_in_tpcc1 |
+-----------------+
| customer |
| district |
| history |
| item |
| new_orders |
| order_line |
| orders |
| stock |
| warehouse |
+-----------------+
table의 foreign key와 index에 관한 정보를 추가하고 싶다면 아래 명령어를 추가로 실행하면 된다.
아래 명령어는 데이터가 생성된 이후에 진행해도 무관하다.
$ mysql tpcc1 -hmysql -uroot -proot < add_fkey_idx.sql
데이터를 생성하기 위한 table이 설정이 완료되었고, benchmark를 위한 초기 데이터를 생성해보자.
warehouse의 개수는 1개(-w1)로 설정했다.
$ ./tpcc_load -hmysql -dtpcc1 -uroot -proot -w1
*************************************
*** TPCC-mysql Data Loader ***
*************************************
option h with value 'mysql'
option d with value 'tpcc1'
option u with value 'root'
option p with value 'root'
option w with value '1'
<Parameters>
[server]: mysql
[port]: 3306
[DBname]: tpcc1
[user]: root
[pass]: root
[warehouse]: 1
TPCC Data Load Started...
Loading Item
.................................................. 5000
...
...DATA LOADING COMPLETED SUCCESSFULLY.
제대로 데이터가 생성되었는지 확인하기 위해 mysql을 통해 확인할 수 있다.
mysql> select count(*) from warehouse;
+----------+
| count(*) |
+----------+
| 1 |
+----------+
1 row in set (0.00 sec)
mysql> select count(*) from orders;
+----------+
| count(*) |
+----------+
| 30000 |
+----------+
1 row in set (0.01 sec)
warehouse를 1개 생성했기 때문에 30K*W 개수만큼 생성되는 orders는 30,000개가 생성된걸 확인할 수 있다.
이제 생성된 데이터를 기반으로 benchmark 실행해보자.
$ ./tpcc_start -hmysql -P3306 -dtpcc1 -uroot -proot -w1 -c32 -r10 -l100
***************************************
*** ###easy### TPC-C Load Generator ***
***************************************
option h with value 'mysql'
option P with value '3306'
option d with value 'tpcc1'
option u with value 'root'
option p with value 'root'
option w with value '1'
option c with value '32'
option r with value '10'
option l with value '100'
<Parameters>
[server]: mysql
[port]: 3306
[DBname]: tpcc1
[user]: root
[pass]: root
[warehouse]: 1
[connection]: 32
[rampup]: 10 (sec.)
[measure]: 100 (sec.)
RAMP-UP TIME.(10 sec.)
MEASURING START.
10, trx: 1466, 95%: 45.707, 99%: 66.588, max_rt: 134.603, 1463|259.705, 147|48.093, 147|117.481, 146|234.267
20, trx: 1491, 95%: 44.921, 99%: 60.163, max_rt: 80.195, 1491|258.610, 149|25.793, 149|110.530, 151|144.989
30, trx: 1476, 95%: 45.394, 99%: 62.963, max_rt: 91.697, 1473|257.982, 147|29.405, 148|101.045, 147|134.593
40, trx: 1487, 95%: 42.424, 99%: 57.919, max_rt: 76.369, 1486|251.475, 149|38.944, 148|102.436, 149|165.392
50, trx: 1523, 95%: 42.488, 99%: 57.797, max_rt: 74.825, 1533|246.987, 152|38.309, 153|110.212, 151|174.092
60, trx: 1508, 95%: 43.661, 99%: 60.760, max_rt: 114.722, 1498|244.906, 151|52.633, 151|147.776, 152|150.247
70, trx: 1479, 95%: 45.996, 99%: 57.521, max_rt: 81.752, 1483|268.676, 148|45.097, 147|118.265, 147|168.063
-w : benchmark에 사용할 warehouse의 개수
-c : benchmark에 사용할 database connection의 개수
-r : bechmark 테스트 주기 (Ramp-Up Time)
-l : benchmark의 Runnig Time
측정 결과를 간단하게 해석해보면 아래와 같다.
처음 10초 동안 1466개의 New Order트랜잭션이 발생
New Order 트랜잭션 중 95%에 해당하는 트랜잭션의 소요시간이 45.707 초, 99%가 66.588초가 걸림
가장 오래 걸린 New Order 트랜잭션 시간은 134.603 초가 걸림
New Order 외의 트랜잭션에 대해서 throughput과 max response 시간은 각각
1463|259.705, 147|48.093, 147|117.481, 146|234.267 이 됨
TPC benchmark는 OLTP 데이터베이스의 성능을 측정하는게 주된 목표이지만
앞으로 MySQL에 대해 공부하면서 주로 사용할 것 같아 정리해봤다.
mysql 공식페이지에서는 이러한 benchmark를 사용자가 직접 커스텀할 수 있는 툴인 mysqlslap을 제공하고 있다.
https://dev.mysql.com/doc/refman/5.7/en/custom-benchmarks.html