이번 포스트에서는 SingleStore, MySQL, PostgreSQL 을 대상으로 8개의 Python Process 들이 동시에 하나의 Row 에 대해 각각 1만회, 총 8만회의 Update 를 수행하는 작업의 성능을 비교 테스트하겠습니다. Shell Script 에서 각각의 Python 프로그램을 Background 로 실행하며 autocommit 모드를 True 로 명시적으로 설정하여 1건 Update 후 바로 commit 하도록 했습니다.
* 테스트 장비 사양 : 8vCPU, 16GB Memory 1대
■ 업데이트용 테이블 u 생성 및 1건 Insert
mysql> create table u (id int primary key, val int);
Query OK, 0 rows affected (0.02 sec)
mysql> insert into u values (1, 1);
Query OK, 1 row affected (0.00 sec)
■ myupdate.py 프로그램 및 myupdate.sh
$ cat myupdate.py
import MySQLdb
import time
def fn_update():
for i in range(10000):
cursor.execute("UPDATE u SET val = val + 1 where id = 1")
if __name__=="__main__":
start_time = time.time()
conn = MySQLdb.connect(host='localhost', user='root', password='Mysql09876*', db='ingest')
conn.autocommit(True)
cursor = conn.cursor()
fn_update()
conn.close()
print(time.time() - start_time)
$ cat myupdate.sh
python3 myupdate.py &
python3 myupdate.py &
python3 myupdate.py &
python3 myupdate.py &
python3 myupdate.py &
python3 myupdate.py &
python3 myupdate.py &
python3 myupdate.py &
■ 실행 결과
MySQL 대상으로 8개의 프로세스가 동시에 백그라운드로 실행할 때 각각 148초 정도 소요되었습니다.
$ sh myupdate.sh
$ 148.5076823234558
148.51317238807678
148.51667642593384
148.51954174041748
148.5218162536621
148.52344393730164
148.52379512786865
148.52113556861877
$ mysql -uroot -pMysql09876* -P3307 -Dingest -e "select * from u"
mysql: [Warning] Using a password on the command line interface can be insecure.
+----+-------+
| id | val |
+----+-------+
| 1 | 80001 |
+----+-------+
MySQL 대상으로 16개의 프로세스가 동시에 백그라운드로 실행할 때 각각 297초 정도 소요되었습니다.
$ sh myupdate.sh
$ 297.50871562957764
297.51753330230713
297.5204656124115
297.52227687835693
297.52448177337646
297.52618765830994
297.5329132080078
297.53367853164673
297.53931760787964
297.54141545295715
297.54106974601746
297.5584542751312
297.560261964798
297.5623199939728
297.56875681877136
297.57068133354187
$ mysql -uroot -pMysql09876* -P3307 -Dingest -e "select * from u"
mysql: [Warning] Using a password on the command line interface can be insecure.
+----+--------+
| id | val |
+----+--------+
| 1 | 160001 |
+----+--------+
■ 업데이트용 테이블 u 생성 및 1건 Insert
ingest=> create table u (id int primary key, val int);
CREATE TABLE
ingest=> insert into u values (1, 1);
INSERT 0 1
■ pgupdate.py 프로그램 및 pgupdate.sh
$ cat pgupdate.py
import psycopg2
import time
def fn_update():
for i in range(10000):
cursor.execute("UPDATE u SET val = val + 1 where id = 1")
if __name__=="__main__":
start_time = time.time()
conn = psycopg2.connect('dbname=ingest user=opc')
conn.set_session(autocommit=True)
cursor = conn.cursor()
fn_update()
conn.close()
print(time.time() - start_time)
$ cat pgupdate.sh
python3 pgupdate.py &
python3 pgupdate.py &
python3 pgupdate.py &
python3 pgupdate.py &
python3 pgupdate.py &
python3 pgupdate.py &
python3 pgupdate.py &
python3 pgupdate.py &
■ 실행 결과
PostgreSQL 대상으로 8개의 프로세스가 동시에 백그라운드로 실행할 때 각각 43초 정도 소요되었습니다.
$ sh pgupdate.sh
$ 43.521015644073486
43.744847774505615
43.807780742645264
44.00548481941223
44.02583050727844
44.065367698669434
44.083571910858154
44.11265254020691
$ psql -d ingest -c 'select * from u'
id | val
----+-------
1 | 80001
(1 row)
PostgreSQL 대상으로 16개의 프로세스가 동시에 백그라운드로 실행할 때 각각 95초 정도 소요되었습니다.
$ sh pgupdate.sh
$ 94.7848551273346
94.8909387588501
94.93381547927856
95.04999613761902
95.21167612075806
95.38436532020569
95.48537230491638
95.45584607124329
95.65791749954224
95.72669291496277
95.69963765144348
95.70361089706421
95.81393074989319
95.76147603988647
95.74110293388367
95.78679704666138
$ psql -d ingest -c 'select * from u'
id | val
----+--------
1 | 160001
(1 row)
■ 업데이트용 테이블 u 생성 및 1건 Insert
singlestore> create rowstore table u (id int primary key, val int);
Query OK, 0 rows affected (0.02 sec)
singlestore> insert into u values (1, 1);
Query OK, 1 row affected (0.11 sec)
■ s2update.py 프로그램 및 s2update.sh
$ cat s2update.py
import singlestoredb as s2
import time
def fn_update():
for i in range(10000):
cursor.execute("UPDATE u SET val = val + 1 where id = 1")
if __name__=="__main__":
start_time = time.time()
conn = s2.connect('root:1234@localhost/ingest')
conn.autocommit(True)
cursor = conn.cursor()
fn_update()
conn.close()
print(time.time() - start_time)
$ cat s2update.sh
python3 s2update.py &
python3 s2update.py &
python3 s2update.py &
python3 s2update.py &
python3 s2update.py &
python3 s2update.py &
python3 s2update.py &
python3 s2update.py &
■ 실행 결과
SingleStore 로우스토어 테이블 대상, 8개 프로세스 동시 백그라운드 실행 시 3초 정도 소요되었습니다.
$ sh s2update.sh
$ 3.0341742038726807
3.041639566421509
3.042114019393921
3.0499024391174316
3.050976514816284
3.0598905086517334
3.064934492111206
3.0669329166412354
$ singlestore -p1234 -e "select * from ingest.u"
singlestore-client: [Warning] Using a password on the command line interface can be insecure.
+----+-------+
| id | val |
+----+-------+
| 1 | 80001 |
+----+-------+
SingleStore 로우스토어 테이블 대상, 16개 프로세스 동시 백그라운드 실행 시 5.6초 정도 소요되었습니다.
$ sh s2update.sh
$ 5.519845724105835
5.57387113571167
5.380051612854004
5.560138940811157
5.502791404724121
5.433483839035034
5.572704315185547
5.546921014785767
5.518806457519531
5.497887134552002
5.417201042175293
5.495232343673706
5.482322931289673
5.541844606399536
5.573808193206787
5.606230735778809
$ singlestore -p1234 -e "select * from ingest.u"
singlestore-client: [Warning] Using a password on the command line interface can be insecure.
+----+--------+
| id | val |
+----+--------+
| 1 | 160001 |
+----+--------+
컬럼스토어 테이블에서도 테스트하기 위해 아래 명령어를 수행합니다.
singlestore> drop table u;
Query OK, 0 rows affected (0.01 sec)
singlestore> create table u (id int primary key, val int);
Query OK, 0 rows affected (0.02 sec)
singlestore> insert into u values (1, 1);
Query OK, 1 row affected (0.02 sec)
singlestore> show tables extended;
+------------------+------------+-------------+--------------+
| Tables_in_ingest | Table_type | distributed | Storage_type |
+------------------+------------+-------------+--------------+
| u | BASE TABLE | 1 | COLUMNSTORE |
+------------------+------------+-------------+--------------+
1 row in set (0.00 sec)
singlestore> exit
Bye
SingleStore 컬럼스토어 테이블 대상, 8개 프로세스 동시 업데이트는 9초가 소요되었습니다.
$ sh s2update.sh
$ 9.342201232910156
9.340841054916382
9.332205295562744
9.360701084136963
9.362358570098877
9.365511178970337
9.375698804855347
9.331790685653687
$ singlestore -p1234 -e "select * from ingest.u"
singlestore-client: [Warning] Using a password on the command line interface can be insecure.
+----+-------+
| id | val |
+----+-------+
| 1 | 80001 |
+----+-------+
SingleStore 컬럼스토어 테이블 대상, 16개 프로세스 동시 업데이트는 21초가 소요되었습니다.
$ sh s2update.sh
$ 20.590859413146973
20.779563426971436
21.11180305480957
21.127861738204956
21.236594438552856
21.127793788909912
21.140755891799927
21.179585933685303
21.15651512145996
21.252389192581177
21.202993154525757
21.17750883102417
21.23723840713501
21.138930559158325
21.155629873275757
21.231318950653076
$ singlestore -p1234 -e "select * from ingest.u"
singlestore-client: [Warning] Using a password on the command line interface can be insecure.
+----+--------+
| id | val |
+----+--------+
| 1 | 160001 |
+----+--------+
동일 row 에 대한 동시 업데이트 테스트 결과는 다음 표로 마무리하겠습니다.
동시 프로세스 수 | SingleStore Rowstore | SingleStore ColumnStore | MySQL | PostgreSQL |
---|---|---|---|---|
8 | 3.0 | 9.3 | 148.5 | 44.1 |
16 | 5.6 | 21.2 | 297.5 | 95.7 |