mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-03 04:12:31 +01:00
framework/db: use HikariCP instead of dbcp2
Replaces dbcp2 connection pool library with more performant HikariCP. With this unit tests are failing but build is passing. Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
This commit is contained in:
parent
f21a00b2de
commit
696927455f
@ -32,7 +32,7 @@ db.cloud.name=cloud
|
||||
# CloudStack database tuning parameters
|
||||
db.cloud.maxActive=250
|
||||
db.cloud.maxIdle=30
|
||||
db.cloud.maxWait=10000
|
||||
db.cloud.maxWait=600000
|
||||
db.cloud.validationQuery=/* ping */ SELECT 1
|
||||
db.cloud.testOnBorrow=true
|
||||
db.cloud.testWhileIdle=true
|
||||
@ -64,7 +64,7 @@ db.usage.name=cloud_usage
|
||||
# usage database tuning parameters
|
||||
db.usage.maxActive=100
|
||||
db.usage.maxIdle=30
|
||||
db.usage.maxWait=10000
|
||||
db.usage.maxWait=600000
|
||||
db.usage.url.params=serverTimezone=UTC
|
||||
|
||||
# Simulator database settings
|
||||
@ -76,7 +76,7 @@ db.simulator.port=3306
|
||||
db.simulator.name=simulator
|
||||
db.simulator.maxActive=250
|
||||
db.simulator.maxIdle=30
|
||||
db.simulator.maxWait=10000
|
||||
db.simulator.maxWait=600000
|
||||
db.simulator.autoReconnect=true
|
||||
|
||||
|
||||
|
||||
@ -29,13 +29,17 @@
|
||||
</parent>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-dbcp2</artifactId>
|
||||
<groupId>org.eclipse.persistence</groupId>
|
||||
<artifactId>javax.persistence</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-pool2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.zaxxer</groupId>
|
||||
<artifactId>HikariCP</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jasypt</groupId>
|
||||
<artifactId>jasypt</artifactId>
|
||||
|
||||
@ -37,8 +37,8 @@
|
||||
<artifactId>javax.persistence</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-dbcp2</artifactId>
|
||||
<groupId>com.zaxxer</groupId>
|
||||
<artifactId>HikariCP</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
|
||||
@ -33,14 +33,8 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.apache.commons.dbcp2.ConnectionFactory;
|
||||
import org.apache.commons.dbcp2.DriverManagerConnectionFactory;
|
||||
import org.apache.commons.dbcp2.PoolableConnection;
|
||||
import org.apache.commons.dbcp2.PoolableConnectionFactory;
|
||||
import org.apache.commons.dbcp2.PoolingDataSource;
|
||||
import org.apache.commons.pool2.ObjectPool;
|
||||
import org.apache.commons.pool2.impl.GenericObjectPool;
|
||||
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
|
||||
import com.zaxxer.hikari.HikariConfig;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.utils.Pair;
|
||||
@ -1088,7 +1082,7 @@ public class TransactionLegacy implements Closeable {
|
||||
// Default Data Source for CloudStack
|
||||
s_ds = createDataSource(cloudConnectionUri, cloudUsername, cloudPassword, cloudMaxActive, cloudMaxIdle, cloudMaxWait,
|
||||
cloudTimeBtwEvictionRunsMillis, cloudMinEvcitableIdleTimeMillis, cloudTestWhileIdle, cloudTestOnBorrow,
|
||||
cloudValidationQuery, isolationLevel);
|
||||
cloudValidationQuery, isolationLevel, "cloud");
|
||||
|
||||
// Configure the usage db
|
||||
final int usageMaxActive = Integer.parseInt(dbProps.getProperty("db.usage.maxActive"));
|
||||
@ -1111,7 +1105,7 @@ public class TransactionLegacy implements Closeable {
|
||||
// Data Source for usage server
|
||||
s_usageDS = createDataSource(usageConnectionUri, usageUsername, usagePassword,
|
||||
usageMaxActive, usageMaxIdle, usageMaxWait, null, null, null, null,
|
||||
null, isolationLevel);
|
||||
null, isolationLevel, "usage");
|
||||
|
||||
try {
|
||||
// Configure the simulator db
|
||||
@ -1131,14 +1125,14 @@ public class TransactionLegacy implements Closeable {
|
||||
DriverLoader.loadDriver(simulatorDriver);
|
||||
|
||||
s_simulatorDS = createDataSource(simulatorConnectionUri, simulatorUsername, simulatorPassword,
|
||||
simulatorMaxActive, simulatorMaxIdle, simulatorMaxWait, null, null, null, null, cloudValidationQuery, isolationLevel);
|
||||
simulatorMaxActive, simulatorMaxIdle, simulatorMaxWait, null, null, null, null, cloudValidationQuery, isolationLevel, "simulator");
|
||||
} catch (Exception e) {
|
||||
s_logger.debug("Simulator DB properties are not available. Not initializing simulator DS");
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
s_ds = getDefaultDataSource("cloud");
|
||||
s_usageDS = getDefaultDataSource("cloud_usage");
|
||||
s_simulatorDS = getDefaultDataSource("cloud_simulator");
|
||||
s_simulatorDS = getDefaultDataSource("simulator");
|
||||
s_logger.warn(
|
||||
"Unable to load db configuration, using defaults with 5 connections. Falling back on assumed datasource on localhost:3306 using username:password=cloud:cloud. Please check your configuration",
|
||||
e);
|
||||
@ -1152,42 +1146,100 @@ public class TransactionLegacy implements Closeable {
|
||||
Integer maxActive, Integer maxIdle, Long maxWait,
|
||||
Long timeBtwnEvictionRuns, Long minEvictableIdleTime,
|
||||
Boolean testWhileIdle, Boolean testOnBorrow,
|
||||
String validationQuery, Integer isolationLevel) {
|
||||
ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(uri, username, password);
|
||||
PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory, null);
|
||||
GenericObjectPoolConfig config = createPoolConfig(maxActive, maxIdle, maxWait, timeBtwnEvictionRuns, minEvictableIdleTime, testWhileIdle, testOnBorrow);
|
||||
ObjectPool<PoolableConnection> connectionPool = new GenericObjectPool<>(poolableConnectionFactory, config);
|
||||
poolableConnectionFactory.setPool(connectionPool);
|
||||
if (isolationLevel != null) {
|
||||
poolableConnectionFactory.setDefaultTransactionIsolation(isolationLevel);
|
||||
}
|
||||
return new PoolingDataSource<>(connectionPool);
|
||||
}
|
||||
String validationQuery, Integer isolationLevel,
|
||||
String dsName) {
|
||||
HikariConfig config = new HikariConfig();
|
||||
config.setJdbcUrl(uri);
|
||||
config.setUsername(username);
|
||||
config.setPassword(password);
|
||||
|
||||
/**
|
||||
* Return a GenericObjectPoolConfig configuration usable on connection pool creation
|
||||
*/
|
||||
private static GenericObjectPoolConfig createPoolConfig(Integer maxActive, Integer maxIdle, Long maxWait,
|
||||
Long timeBtwnEvictionRuns, Long minEvictableIdleTime,
|
||||
Boolean testWhileIdle, Boolean testOnBorrow) {
|
||||
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
|
||||
config.setMaxTotal(maxActive);
|
||||
config.setMaxIdle(maxIdle);
|
||||
config.setMaxWaitMillis(maxWait);
|
||||
config.setPoolName(dsName);
|
||||
if (maxActive != null) {
|
||||
config.setMaximumPoolSize(maxActive);
|
||||
} else {
|
||||
config.setMaximumPoolSize(250); // 250 connections
|
||||
}
|
||||
if (maxIdle != null) {
|
||||
config.setIdleTimeout(maxIdle * 1000);
|
||||
} else {
|
||||
config.setIdleTimeout(30000); // 30 seconds
|
||||
}
|
||||
if (maxWait != null) {
|
||||
config.setMaxLifetime(maxWait);
|
||||
} else {
|
||||
config.setMaxLifetime(600000); // 10 minutes
|
||||
}
|
||||
|
||||
if (timeBtwnEvictionRuns != null) {
|
||||
config.setTimeBetweenEvictionRunsMillis(timeBtwnEvictionRuns);
|
||||
// Connection pool properties
|
||||
config.setMinimumIdle(5); // Minimum number of idle connections in the pool
|
||||
config.setConnectionTimeout(30000); // 30 seconds in milliseconds
|
||||
config.setKeepaliveTime(600000); // Keepalive time in milliseconds (10 minutes)
|
||||
config.setIdleTimeout(300000); // 5 minutes
|
||||
//config.setMinimumIdle(maxIdle);
|
||||
//config.setConnectionTestQuery("/* ping */ SELECT 1"); // Connection test query
|
||||
|
||||
String isolationLevelString = "TRANSACTION_READ_COMMITTED";
|
||||
if (isolationLevel == Connection.TRANSACTION_SERIALIZABLE) {
|
||||
isolationLevelString = "TRANSACTION_SERIALIZABLE";
|
||||
} else if (isolationLevel == Connection.TRANSACTION_READ_UNCOMMITTED) {
|
||||
isolationLevelString = "TRANSACTION_READ_UNCOMMITTED";
|
||||
} else if (isolationLevel == Connection.TRANSACTION_REPEATABLE_READ) {
|
||||
isolationLevelString = "TRANSACTION_REPEATABLE_READ";
|
||||
}
|
||||
if (minEvictableIdleTime != null) {
|
||||
config.setMinEvictableIdleTimeMillis(minEvictableIdleTime);
|
||||
}
|
||||
if (testWhileIdle != null) {
|
||||
config.setTestWhileIdle(testWhileIdle);
|
||||
}
|
||||
if (testOnBorrow != null) {
|
||||
config.setTestOnBorrow(testOnBorrow);
|
||||
}
|
||||
return config;
|
||||
config.setTransactionIsolation(isolationLevelString);
|
||||
|
||||
// Standard datasource config for MySQL
|
||||
config.addDataSourceProperty("cachePrepStmts", "true");
|
||||
config.addDataSourceProperty("prepStmtCacheSize", "250");
|
||||
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
|
||||
// Additional config for MySQL
|
||||
config.addDataSourceProperty("useServerPrepStmts", "true");
|
||||
config.addDataSourceProperty("useLocalSessionState", "true");
|
||||
config.addDataSourceProperty("rewriteBatchedStatements", "true");
|
||||
config.addDataSourceProperty("cacheResultSetMetadata", "true");
|
||||
config.addDataSourceProperty("cacheServerConfiguration", "true");
|
||||
config.addDataSourceProperty("elideSetAutoCommits", "true");
|
||||
config.addDataSourceProperty("maintainTimeStats", "false");
|
||||
|
||||
HikariDataSource dataSource = new HikariDataSource(config);
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
private static DataSource getDefaultDataSource(final String database) {
|
||||
HikariConfig config = new HikariConfig();
|
||||
config.setJdbcUrl("jdbc:mysql://localhost:3306/" + database + "?" + CONNECTION_PARAMS);
|
||||
config.setUsername("cloud");
|
||||
config.setPassword("cloud");
|
||||
config.setPoolName(database);
|
||||
|
||||
config.setMaximumPoolSize(250); // 250 connections
|
||||
config.setIdleTimeout(30000); // 30 seconds
|
||||
config.setMaxLifetime(600000); // 10 minutes
|
||||
|
||||
// Connection pool properties
|
||||
config.setConnectionTimeout(20000); // 20 seconds in milliseconds
|
||||
config.setMinimumIdle(5); // Minimum number of idle connections in the pool
|
||||
config.setKeepaliveTime(600000); // Keepalive time in milliseconds (10 minutes)
|
||||
//config.setConnectionTestQuery("/* ping */ SELECT 1"); // Connection test query
|
||||
config.setIdleTimeout(300000); // 5 minutes
|
||||
config.setTransactionIsolation("TRANSACTION_READ_COMMITTED");
|
||||
|
||||
// Standard datasource config for MySQL
|
||||
config.addDataSourceProperty("cachePrepStmts", "true");
|
||||
config.addDataSourceProperty("prepStmtCacheSize", "250");
|
||||
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
|
||||
// Additional config for MySQL
|
||||
config.addDataSourceProperty("useServerPrepStmts", "true");
|
||||
config.addDataSourceProperty("useLocalSessionState", "true");
|
||||
config.addDataSourceProperty("rewriteBatchedStatements", "true");
|
||||
config.addDataSourceProperty("cacheResultSetMetadata", "true");
|
||||
config.addDataSourceProperty("cacheServerConfiguration", "true");
|
||||
config.addDataSourceProperty("elideSetAutoCommits", "true");
|
||||
config.addDataSourceProperty("maintainTimeStats", "false");
|
||||
|
||||
HikariDataSource dataSource = new HikariDataSource(config);
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
private static String getDBHAParams(String dbName, Properties dbProps) {
|
||||
@ -1201,14 +1253,6 @@ public class TransactionLegacy implements Closeable {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
private static DataSource getDefaultDataSource(final String database) {
|
||||
final ConnectionFactory connectionFactory = new DriverManagerConnectionFactory("jdbc:mysql://localhost:3306/" + database + "?" + CONNECTION_PARAMS, "cloud", "cloud");
|
||||
final PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory, null);
|
||||
final GenericObjectPool connectionPool = new GenericObjectPool(poolableConnectionFactory);
|
||||
return new PoolingDataSource(connectionPool);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for unit testing primarily
|
||||
*
|
||||
|
||||
14
pom.xml
14
pom.xml
@ -100,7 +100,7 @@
|
||||
<cs.commons-validator.version>1.6</cs.commons-validator.version>
|
||||
<cs.configuration.version>1.10</cs.configuration.version>
|
||||
<cs.daemon.version>1.3.3</cs.daemon.version>
|
||||
<cs.dbcp.version>2.12.0</cs.dbcp.version>
|
||||
<cs.hikaricp.version>5.1.0</cs.hikaricp.version>
|
||||
<cs.discovery.version>0.5</cs.discovery.version>
|
||||
<cs.lang.version>2.6</cs.lang.version>
|
||||
<cs.pool.version>2.9.0</cs.pool.version>
|
||||
@ -361,15 +361,9 @@
|
||||
<version>${cs.daemon.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-dbcp2</artifactId>
|
||||
<version>${cs.dbcp.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>org.apache.commons</artifactId>
|
||||
<groupId>commons-pool2</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<groupId>com.zaxxer</groupId>
|
||||
<artifactId>HikariCP</artifactId>
|
||||
<version>${cs.hikaricp.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-discovery</groupId>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user