My configuration is:
Compute
- AWS ECS cluster with a Django based API (Using ORM). 1vCPU and 4GB of memory per container.
Database
- RDS MariaDB
db.t3.medium
instance (2 vCPU, 4GB of memory) gp3
type storage (3000 IOPS provisioned, 125Mib/s base throughput)- Tables information:
table_name_1
:48
columns of mostlyVARCHAR(50~250)
with49977
rowstable_name_2
:5
columns ofINT
andDATETIME
with49977
rowstable_name_3
:40
columns ofINT
,VARCHAR
,DOUBLE
with656904
rowstable_name_4
:32
columns ofINT
,VARCHAR
,DOUBLE
with727477
rows
- RDS MariaDB
Test case:
140 WEB clients are active at same time and continuously sending GET
requests for 1 minute at two API URLs (70 clients per URL) with same query parameters per URL:
- First URL is executing only
SELECT
SQL queries. Most complicated one is:
Query details:SELECT `table_name_2`.`id`, `table_name_2`.`table_name_1_id`, `table_name_2`.`param_1`, `table_name_1`.`id`, `table_name_1`.`param_1`, `table_name_1`.`param_2` FROM `table_name_2` INNER JOIN `table_name_1` ON ( `table_name_2`.`table_name_1_id` = `table_name_1`.`id` ) INNER JOIN `table_name_3` ON ( `table_name_1`.`id` = `table_name_3`.`table_name_1_id` ) WHERE ( `table_name_1`.`param_1` >= 100 AND `table_name_1`.``param_1` <= 200 AND `table_name_1`.`param_2` >= 100 AND `table_name_1`.`param_2` <= 200 AND `table_name_3`.`param_3` >= 10000 AND `table_name_2`.`param_4` >= 10000 ) GROUP BY `table_name_2`.`id` ORDER BY NULL
- total number of resulted rows for
SELECT
is234
- number of rows after first
JOIN
is49977
- number of rows after second
JOIN
and beforeGROUP_BY
is998
- total number of resulted rows for
- Second URL is executing
SELECT
andUPDATE
SQL queries. Where slowUPDATE
is:
Query details:UPDATE `table_name_4` SET `parameter_1` = CASE WHEN (`table_name_4`.`id` = 810982) THEN 0 WHEN (`table_name_4`.`id` = 810983) THEN 0 WHEN (`table_name_4`.`id` = 811066) THEN 0 WHEN (`table_name_4`.`id` = 811075) THEN 0 WHEN (`table_name_4`.`id` = 811076) THEN 0 WHEN (`table_name_4`.`id` = 811077) THEN 0 WHEN (`table_name_4`.`id` = 811078) THEN 0 WHEN (`table_name_4`.`id` = 811079) THEN 0 WHEN (`table_name_4`.`id` = 811103) THEN 0 WHEN (`table_name_4`.`id` = 811159) THEN 0 ELSE NULL END, `parameter_2` = CASE WHEN (`table_name_4`.`id` = 810982) THEN 0 WHEN (`table_name_4`.`id` = 810983) THEN 0 WHEN (`table_name_4`.`id` = 811066) THEN 0 WHEN (`table_name_4`.`id` = 811075) THEN 0 WHEN (`table_name_4`.`id` = 811076) THEN 0 WHEN (`table_name_4`.`id` = 811077) THEN 0 WHEN (`table_name_4`.`id` = 811078) THEN 0 WHEN (`table_name_4`.`id` = 811079) THEN 0 WHEN (`table_name_4`.`id` = 811103) THEN 0 WHEN (`table_name_4`.`id` = 811159) THEN 0 ELSE NULL END, `parameter_3` = CASE WHEN ...
- updating
10
rows - Execution time is
10~15ms
when executing manually - total number of cases is
10
- updating
Here is a graph of service response time:
We have 140
active clients and 12s
average response time (for 2
containers)
So real average throughput is 140 / 12 = ~12 requests/s
In case of 6
containers average response time is about 6s
Here are two peaks on the DB performance graph:
Two tests with different configuration:
6
running ECS containers2
running ECS containers
Here is an additional graph for same time range:
Questions:
- Average active sessions number is bigger for
2
containers. What is means that query per container running time is slower for2
containers (waiting queries of2
containers accumulates faster than6
containers is executing new queries with less wait time). Why may it happen? DB is waiting for some kind ofDjango
query complete confirmation, butDjango
response is slower in case of2
containers (because of server load)? - In case of
2
containerswait/io/table/sql/handler
wait event is extremely slow (this event is related toUPDATE
query below), but in case of6
containerswait/synch/rwlock/innodb/btr_search_latch
(related toSELECT
) needs much more time thanUPDATE
query. Why are latency reasons changing depending on application computing performance? - Any other suggestions what I should check based on this graph.
- How this graph should be correctly interpreted (if it possible without knowing other system logs)?
Improving of weird SQL queries above is not an object of discussion
long_query_time
and turn on the slowlog. With the queries in hand, things might be clearer. This would give the timeframes.SHOW CREATE TABLE
would provide more info.WHERE
clause on the Update. And whether it had aJOIN
.slowquery
log is empty. Even if I setlong_query_time = 0.5
. But when I see RDS Performance monitor it shows me:Avg latency (ms): 10606.27
forUPDATE
query and667.72
forSELECT
query ② → If I correctly understand your question, then yes. Let’s say 140 simultaneous invocations ofcurl
command per second (70 per URL). Number of connections in peak is about ~1000 (3000max_connections
is allowed). Yes, it is high, but I don't expect fast response for current test. ⓷ → addedTables information
andQuery details
. I hope it will help