那有了Redis这样优秀的NoSql数据库,为啥还会用到Apache Ignite呢?
不知道你是否有想过一个事情,就是Redis这样的内存数据库,如果能支持SQL语句,是不是就更牛了。这样一来本身存在MySQL数据库里的数据,就可以原封不动的封到内存中使用。既保留了原有的业务逻辑,又使用上了内存读取高性能。
所以,它来了。Apache Ignite是一个兼容ANSI-99、水平可扩展以及容错的分布式SQL数据库,作为一个SQL数据库,Ignite支持所有的DML指令,包括SELECT、UPDATE、INSERT和DELETE,它还实现了一个与分布式系统有关的DDL指令的子集。Ignite的一个突出特性是完全支持分布式的SQL关联,Ignite支持并置和非并置的数据关联。并置时,关联是在每个节点的可用数据集上执行的,而不需要在网络中移动大量的数据,这种方式在分布式数据库中提供了最好的扩展性和性能。
本文涉及的工程:
docs/dev-ops 提供了 mysql、ignite 安装脚本,和数据初始化操作。
官网 docs 可以阅读安装和使用
这是一个 Ignite 的中文站点
安装最新版,直接可以连接 Ignite 数据库
本案例中为了对比MySQL和Ignite的性能差异,以及如何同时使用两套数据库,这里小傅哥会在一个工程中分别配置出不同的数据库对应数据源的创建和MyBatis的配置用。如果说你做过小傅哥的 DB-Router 组件开发,那么也可以在组件中添加对Ignite内存数据库的路由配置。这样的使用会更加方便,也可以自动的通过注解来切换数据源的使用。
具体可以参考源码
在安装执行 docker-compose.yml 脚本之前,你需要先在本地安装 docker之后 IntelliJ IDEA 打开 docker-compose.yml 文件,如图操作即可安装。
首先确保你已经安装过 DBeaver ,之后就可以连接和创建表了。
<!-- https://mvnrepository.com/artifact/org.apache.ignite/ignite-core -->
<dependency>
<groupId>org.apache.ignite</groupId>
<artifactId>ignite-core</artifactId>
<version>2.15.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.ignite/ignite-spring -->
<dependency>
<groupId>org.apache.ignite</groupId>
<artifactId>ignite-spring</artifactId>
<version>2.15.0</version>
</dependency>
源码:cn.bugstack.xfg.dev.tech.config.DataSourceConfig#IgniteMyBatisConfig
@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 environment) {
IgniteConfiguration igniteConfig = new IgniteConfiguration();
DataStorageConfiguration dataStorageConfig = new DataStorageConfiguration();
DataRegionConfiguration defaultDataRegionConfig = new DataRegionConfiguration();
defaultDataRegionConfig.setPersistenceEnabled(false);
dataStorageConfig.setDefaultDataRegionConfiguration(defaultDataRegionConfig);
igniteConfig.setDataStorageConfiguration(dataStorageConfig);
ConnectorConfiguration configuration = new ConnectorConfiguration();
configuration.setIdleTimeout(6000);
configuration.setThreadPoolSize(100);
configuration.setIdleTimeout(60000);
igniteConfig.setConnectorConfiguration(configuration);
return DataSourceBuilder.create()
.url(environment.getProperty("spring.ignite.datasource.url"))
.driverClassName(environment.getProperty("spring.ignite.datasource.driver-class-name"))
.build();
}
@Bean("igniteSqlSessionFactory")
public SqlSessionFactory igniteSqlSessionFactory(DataSource igniteDataSource) throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(igniteDataSource);
factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/mybatis/mapper/ignite/*.xml"));
return factoryBean.getObject();
}
}
源码:cn.bugstack.xfg.dev.tech.config.DataSourceConfig#MysqlMyBatisConfig
@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 environment) {
return DataSourceBuilder.create()
.url(environment.getProperty("spring.mysql.datasource.url"))
.driverClassName(environment.getProperty("spring.mysql.datasource.driver-class-name"))
.build();
}
@Bean("mysqlSqlSessionFactory")
public SqlSessionFactory mysqlSqlSessionFactory(DataSource mysqlDataSource) throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(mysqlDataSource);
factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/mybatis/mapper/mysql/*.xml"));
return factoryBean.getObject();
}
}
小傅哥提供了 IgniteController、MySQLController 两个 HTTP 访问类,分别提供了两个数据库的压测操作。
ab -c 1 -n 1 http://127.0.0.1:8091/api/ignite/start
ab -c 20 -n 50000 http://127.0.0.1:8091/api/ignite/insert
ab -c 20 -n 1000 http://127.0.0.1:8091/api/ignite/cacheData
ab -c 20 -n 1000 http://127.0.0.1:8091/api/ignite/selectByOrderId
- 记得给 OrderId 加索引ab -c 1 -n 1 http://127.0.0.1:8091/api/ignite/start
ab -c 20 -n 50000 http://127.0.0.1:8091/api/ignite/insert
ab -c 20 -n 1000 http://127.0.0.1:8091/api/ignite/cacheData
ab -c 20 -n 1000 http://127.0.0.1:8091/api/ignite/selectByOrderId
- 记得给 OrderId 加索引综上,Ignite 略胜一筹,确实纯内存的数据库会更快一些。也适合在一些需要内存计算的场景中,并且不改变MySQL表结构的情况下,做一些优化的是使用。
- END -