Performance Test with Sysbench
Target
The performance of ShardingSphere-JDBC, ShardingSphere-Proxy and MySQL would be compared here. INSERT & UPDATE & DELETE which regarded as a set of associated operation and SELECT which focus on sharding optimization are used to evaluate performance for the basic scenarios (single route, readwrite-splitting & encrypt & sharding, full route). While another set of associated operation, INSERT & SELECT & DELETE, is used to evaluate performance for readwrite-splitting. To achieve the result better, these tests are performed with jmeter which based on a certain amount of data with 20 concurrent threads for 30 minutes, and one MySQL has been deployed on one machine, while the scenario of MySQL used for comparison is deployed on one machine with one instance.
Test Scenarios
Single Route
On the basis of one thousand data volume, four databases that are deployed on the same machine and each contains 1024 tables with id
used for database sharding and k
used for table sharding are designed for this scenario, single route select sql statement is chosen here. While as a comparison, MySQL runs with INSERT & UPDATE & DELETE statement and single route select sql statement on the basis of one thousand data volume.
Readwrite-splitting
One primary database and one replica database, which are deployed on different machines, are designed for this scenario based on ten thousand data volume. While as a comparison, MySQL runs with INSERT & SELECT & DELETE sql statement on the basis of ten thousand data volume.
Readwrite-splitting & Encrypt & Sharding
On the basis of one thousand data volume, four databases that are deployed on different machines and each contains 1024 tables with id
used for database sharding, k
used for table sharding, c
encrypted with aes and pad
encrypted with md5 are designed for this scenario, single route select sql statement is chosen here. While as a comparison, MySQL runs with INSERT & UPDATE & DELETE statement and single route select sql statement on the basis of one thousand data volume.
Full Route
On the basis of one thousand data volume, four databases that are deployed on different machines and each contains one table are designed for this scenario, field id
is used for database sharding and k
is used for table sharding, full route select sql statement is chosen here. While as a comparison, MySQL runs with INSERT & UPDATE & DELETE statement and full route select sql statement on the basis of one thousand data volume.
Testing Environment
Table Structure of Database
The structure of table here refer to sbtest
in sysbench
CREATE TABLE `tbl` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`k` int(11) NOT NULL DEFAULT 0,
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
);
Test Scenarios Configuration
The same configurations are used for ShardingSphere-JDBC and ShardingSphere-Proxy, while MySQL with one database connected is designed for comparision. The details for these scenarios are shown as follows.
Single Route Configuration
schemaName: sharding_db
dataSources:
ds_0:
url: jdbc:mysql://***.***.***.***:****/ds?serverTimezone=UTC&useSSL=false
username: test
password:
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 200
ds_1:
url: jdbc:mysql://***.***.***.***:****/ds?serverTimezone=UTC&useSSL=false
username: test
password:
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 200
ds_2:
url: jdbc:mysql://***.***.***.***:****/ds?serverTimezone=UTC&useSSL=false
username: test
password:
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 200
ds_3:
url: jdbc:mysql://***.***.***.***:****/ds?serverTimezone=UTC&useSSL=false
username: test
password:
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 200
rules:
- !SHARDING
tables:
tbl:
actualDataNodes: ds_${0..3}.tbl${0..1023}
tableStrategy:
standard:
shardingColumn: k
shardingAlgorithmName: tbl_table_inline
keyGenerateStrategy:
column: id
keyGeneratorName: snowflake
defaultDatabaseStrategy:
inline:
shardingColumn: id
shardingAlgorithmName: default_db_inline
defaultTableStrategy:
none:
shardingAlgorithms:
tbl_table_inline:
type: INLINE
props:
algorithm-expression: tbl${k % 1024}
default_db_inline:
type: INLINE
props:
algorithm-expression: ds_${id % 4}
keyGenerators:
snowflake:
type: SNOWFLAKE
props:
worker-id: 123
Readwrite-splitting Configuration
schemaName: sharding_db
dataSources:
primary_ds:
url: jdbc:mysql://***.***.***.***:****/ds?serverTimezone=UTC&useSSL=false
username: test
password:
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 200
replica_ds_0:
url: jdbc:mysql://***.***.***.***:****/ds?serverTimezone=UTC&useSSL=false
username: test
password:
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 200
rules:
- !READWRITE_SPLITTING
dataSources:
pr_ds:
writeDataSourceName: primary_ds
readDataSourceNames:
- replica_ds_0
Readwrite-splitting & Encrypt & Sharding Configuration
schemaName: sharding_db
dataSources:
primary_ds_0:
url: jdbc:mysql://***.***.***.***:****/ds?serverTimezone=UTC&useSSL=false
username: test
password:
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 200
replica_ds_0:
url: jdbc:mysql://***.***.***.***:****/ds?serverTimezone=UTC&useSSL=false
username: test
password:
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 200
primary_ds_1:
url: jdbc:mysql://***.***.***.***:****/ds?serverTimezone=UTC&useSSL=false
username: test
password:
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 200
replica_ds_1:
url: jdbc:mysql://***.***.***.***:****/ds?serverTimezone=UTC&useSSL=false
username: test
password:
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 200
primary_ds_2:
url: jdbc:mysql://***.***.***.***:****/ds?serverTimezone=UTC&useSSL=false
username: test
password:
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 200
replica_ds_2:
url: jdbc:mysql://***.***.***.***:****/ds?serverTimezone=UTC&useSSL=false
username: test
password:
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 200
primary_ds_3:
url: jdbc:mysql://***.***.***.***:****/ds?serverTimezone=UTC&useSSL=false
username: test
password:
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 200
replica_ds_3:
url: jdbc:mysql://***.***.***.***:****/ds?serverTimezone=UTC&useSSL=false
username: test
password:
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 200
rules:
- !SHARDING
tables:
tbl:
actualDataNodes: pr_ds_${0..3}.tbl${0..1023}
databaseStrategy:
standard:
shardingColumn: id
shardingAlgorithmName: tbl_database_inline
tableStrategy:
standard:
shardingColumn: k
shardingAlgorithmName: tbl_table_inline
keyGenerateStrategy:
column: id
keyGeneratorName: snowflake
bindingTables:
- tbl
defaultDataSourceName: primary_ds_1
defaultTableStrategy:
none:
shardingAlgorithms:
tbl_database_inline:
type: INLINE
props:
algorithm-expression: pr_ds_${id % 4}
tbl_table_inline:
type: INLINE
props:
algorithm-expression: tbl${k % 1024}
keyGenerators:
snowflake:
type: SNOWFLAKE
props:
worker-id: 123
- !READWRITE_SPLITTING
dataSources:
pr_ds_0:
writeDataSourceName: primary_ds_0
readDataSourceNames:
- replica_ds_0
loadBalancerName: round_robin
pr_ds_1:
writeDataSourceName: primary_ds_1
readDataSourceNames:
- replica_ds_1
loadBalancerName: round_robin
pr_ds_2:
writeDataSourceName: primary_ds_2
readDataSourceNames:
- replica_ds_2
loadBalancerName: round_robin
pr_ds_3:
writeDataSourceName: primary_ds_3
readDataSourceNames:
- replica_ds_3
loadBalancerName: round_robin
loadBalancers:
round_robin:
type: ROUND_ROBIN
- !ENCRYPT:
encryptors:
aes_encryptor:
type: AES
props:
aes-key-value: 123456abc
md5_encryptor:
type: MD5
tables:
sbtest:
columns:
c:
plainColumn: c_plain
cipherColumn: c_cipher
encryptorName: aes_encryptor
pad:
cipherColumn: pad_cipher
encryptorName: md5_encryptor
Full Route Configuration
schemaName: sharding_db
dataSources:
ds_0:
url: jdbc:mysql://***.***.***.***:****/ds?serverTimezone=UTC&useSSL=false
username: test
password:
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 200
ds_1:
url: jdbc:mysql://***.***.***.***:****/ds?serverTimezone=UTC&useSSL=false
username: test
password:
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 200
ds_2:
url: jdbc:mysql://***.***.***.***:****/ds?serverTimezone=UTC&useSSL=false
username: test
password:
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 200
ds_3:
url: jdbc:mysql://***.***.***.***:****/ds?serverTimezone=UTC&useSSL=false
username: test
password:
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 200
rules:
- !SHARDING
tables:
tbl:
actualDataNodes: ds_${0..3}.tbl1
tableStrategy:
standard:
shardingColumn: k
shardingAlgorithmName: tbl_table_inline
keyGenerateStrategy:
column: id
keyGeneratorName: snowflake
defaultDatabaseStrategy:
standard:
shardingColumn: id
shardingAlgorithmName: default_database_inline
defaultTableStrategy:
none:
shardingAlgorithms:
default_database_inline:
type: INLINE
props:
algorithm-expression: ds_${id % 4}
tbl_table_inline:
type: INLINE
props:
algorithm-expression: tbl1
keyGenerators:
snowflake:
type: SNOWFLAKE
props:
worker-id: 123
Test Result Verification
SQL Statement
INSERT+UPDATE+DELETE sql statements:
INSERT INTO tbl(k, c, pad) VALUES(1, '###-###-###', '###-###');
UPDATE tbl SET c='####-####-####', pad='####-####' WHERE id=?;
DELETE FROM tbl WHERE id=?
SELECT sql statement for full route:
SELECT max(id) FROM tbl WHERE id%4=1
SELECT sql statement for single route:
SELECT id, k FROM tbl ignore index(`PRIMARY`) WHERE id=1 AND k=1
INSERT+SELECT+DELETE sql statements:
INSERT INTO tbl1(k, c, pad) VALUES(1, '###-###-###', '###-###');
SELECT count(id) FROM tbl1;
SELECT max(id) FROM tbl1 ignore index(`PRIMARY`);
DELETE FROM tbl1 WHERE id=?
Jmeter Class
Consider the implementation of shardingsphere-benchmark Notes: the notes in shardingsphere-benchmark/README.md should be taken attention to
Compile & Build
git clone https://github.com/apache/shardingsphere-benchmark.git
cd shardingsphere-benchmark/shardingsphere-benchmark
mvn clean install
Perform Test
cp target/shardingsphere-benchmark-1.0-SNAPSHOT-jar-with-dependencies.jar apache-jmeter-4.0/lib/ext
jmeter –n –t test_plan/test.jmx
test.jmx example:https://github.com/apache/shardingsphere-benchmark/tree/master/report/script/test_plan/test.jmx
Process Result Data
Make sure the location of result.jtl file is correct.
sh shardingsphere-benchmark/report/script/gen_report.sh
Display of Historical Performance Test Data
In progress, please wait.