Deploy Apache Ignite and Compare Its Performance with MySQL
This guide walks through installing Apache Ignite via Docker, configuring it alongside MySQL in a Spring Boot project, setting up data sources and MyBatis, and performing benchmark tests to illustrate Ignite’s superior in‑memory SQL performance compared to traditional MySQL setups.
Introduction
The article explains how to deploy, use, and benchmark Apache Ignite, a distributed in‑memory SQL database, and why it can be a valuable complement to traditional databases such as MySQL or Redis.
Why Choose Ignite?
Ignite implements the ANSI‑99 SQL standard, offers horizontal scalability, fault tolerance, and full support for distributed SQL joins. It can execute joins locally on each node without moving large amounts of data across the network, providing excellent performance for distributed workloads.
Case Overview
The example compares MySQL and Ignite performance within a single Spring Boot project. Different data sources are configured, and MyBatis is used to access each database. The setup also demonstrates how to add Ignite routing to an existing DB‑Router component.
Environment Setup
Docker Compose is used to start MySQL, Ignite, DBeaver, and ApacheBench. After pulling the images, Docker automatically creates the MySQL schema and launches an Ignite node.
Connection Configuration
Using DBeaver, you can connect to Ignite, verify the connection, create schemas and tables, and save the changes.
Project Structure
Application layer –
application-dev.ymldefines multiple data sources and loads them in
DataSourceConfig.
Infrastructure layer – separate DAO packages for MySQL and Ignite.
Trigger layer – provides HTTP endpoints for testing Ignite and MySQL.
Data Source Creation
1. Maven Dependencies
<code><dependency>
<groupId>org.apache.ignite</groupId>
<artifactId>ignite-core</artifactId>
<version>2.15.0</version>
</dependency>
<dependency>
<groupId>org.apache.ignite</groupId>
<artifactId>ignite-spring</artifactId>
<version>2.15.0</version>
</dependency></code>2. Ignite Configuration
<code>@Configuration
@MapperScan(basePackages = "cn.bugstack.xfg.dev.tech.infrastructure.ignite.dao", sqlSessionFactoryRef = "igniteSqlSessionFactory")
static class IgniteMyBatisConfig {
@Bean("igniteDataSource")
@ConfigurationProperties(prefix = "spring.ignite.datasource")
public DataSource igniteDataSource(Environment env) {
IgniteConfiguration cfg = new IgniteConfiguration();
DataStorageConfiguration storage = new DataStorageConfiguration();
DataRegionConfiguration region = new DataRegionConfiguration();
region.setPersistenceEnabled(false);
storage.setDefaultDataRegionConfiguration(region);
cfg.setDataStorageConfiguration(storage);
ConnectorConfiguration conn = new ConnectorConfiguration();
conn.setIdleTimeout(60000);
conn.setThreadPoolSize(100);
cfg.setConnectorConfiguration(conn);
return DataSourceBuilder.create()
.url(env.getProperty("spring.ignite.datasource.url"))
.driverClassName(env.getProperty("spring.ignite.datasource.driver-class-name"))
.build();
}
@Bean("igniteSqlSessionFactory")
public SqlSessionFactory igniteSqlSessionFactory(DataSource igniteDataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(igniteDataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath:/mybatis/mapper/ignite/*.xml"));
return bean.getObject();
}
}
</code>3. MySQL Configuration
<code>@Configuration
@MapperScan(basePackages = "cn.bugstack.xfg.dev.tech.infrastructure.mysql.dao", sqlSessionFactoryRef = "mysqlSqlSessionFactory")
static class MysqlMyBatisConfig {
@Bean("mysqlDataSource")
@ConfigurationProperties(prefix = "spring.mysql.datasource")
public DataSource mysqlDataSource(Environment env) {
return DataSourceBuilder.create()
.url(env.getProperty("spring.mysql.datasource.url"))
.driverClassName(env.getProperty("spring.mysql.datasource.driver-class-name"))
.build();
}
@Bean("mysqlSqlSessionFactory")
public SqlSessionFactory mysqlSqlSessionFactory(DataSource mysqlDataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(mysqlDataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath:/mybatis/mapper/mysql/*.xml"));
return bean.getObject();
}
}
</code>Performance Testing
Two HTTP controllers expose endpoints for load testing with
ab. The same set of commands is used for both Ignite and MySQL.
Ignite Load Test
Initialize ID:
ab -c 1 -n 1 http://127.0.0.1:8091/api/ignite/startInsert 50,000 rows:
ab -c 20 -n 50000 http://127.0.0.1:8091/api/ignite/insertRead 1,000 rows:
ab -c 20 -n 1000 http://127.0.0.1:8091/api/ignite/cacheDataQuery by OrderId (with index):
ab -c 20 -n 1000 http://127.0.0.1:8091/api/ignite/selectByOrderIdMySQL Load Test
Initialize ID:
ab -c 1 -n 1 http://127.0.0.1:8091/api/ignite/startInsert 50,000 rows:
ab -c 20 -n 50000 http://127.0.0.1:8091/api/ignite/insertRead 1,000 rows:
ab -c 20 -n 1000 http://127.0.0.1:8091/api/ignite/cacheDataQuery by OrderId (with index):
ab -c 20 -n 1000 http://127.0.0.1:8091/api/ignite/selectByOrderIdConclusion
Ignite shows a slight performance advantage over MySQL, confirming that a pure in‑memory database can be faster for workloads that benefit from memory computing while keeping the existing MySQL schema unchanged.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.