作者:小傅哥,博客:https://bugstack.cn
本文的宗旨在于通過簡(jiǎn)單干凈實(shí)踐的方式,向讀者介紹一款基于內(nèi)存的分布式SQL數(shù)據(jù)庫Apache Ignite的部署、使用和性能測(cè)試。
那有了Redis這樣優(yōu)秀的NoSql數(shù)據(jù)庫,為啥還會(huì)用到Apache Ignite呢?
不知道你是否有想過一個(gè)事情,就是Redis這樣的內(nèi)存數(shù)據(jù)庫,如果能支持SQL語句,是不是就更牛了。這樣一來本身存在MySQL數(shù)據(jù)庫里的數(shù)據(jù),就可以原封不動(dòng)的封到內(nèi)存中使用。既保留了原有的業(yè)務(wù)邏輯,又使用上了內(nèi)存讀取高性能。
所以,它來了。Apache Ignite是一個(gè)兼容ANSI-99、水平可擴(kuò)展以及容錯(cuò)的分布式SQL數(shù)據(jù)庫,作為一個(gè)SQL數(shù)據(jù)庫,Ignite支持所有的DML指令,包括SELECT、UPDATE、INSERT和DELETE,它還實(shí)現(xiàn)了一個(gè)與分布式系統(tǒng)有關(guān)的DDL指令的子集。Ignite的一個(gè)突出特性是完全支持分布式的SQL關(guān)聯(lián),Ignite支持并置和非并置的數(shù)據(jù)關(guān)聯(lián)。并置時(shí),關(guān)聯(lián)是在每個(gè)節(jié)點(diǎn)的可用數(shù)據(jù)集上執(zhí)行的,而不需要在網(wǎng)絡(luò)中移動(dòng)大量的數(shù)據(jù),這種方式在分布式數(shù)據(jù)庫中提供了最好的擴(kuò)展性和性能。
本文涉及的工程:
-
- xfg-dev-tech-ignite:https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-ignite-
docs/dev-ops 提供了 mysql、ignite 安裝腳本,和數(shù)據(jù)初始化操作。
-
- 官網(wǎng)站點(diǎn):https://ignite.apache.org/ -
官網(wǎng) docs 可以閱讀安裝和使用
-
- 中文文檔:https://ignite-service.cn/doc/2.7.0/sql/ -
這是一個(gè) Ignite 的中文站點(diǎn)
-
- 管理工具:DBeaver -
安裝最新版,直接可以連接 Ignite 數(shù)據(jù)庫
一、案例說明
本案例中為了對(duì)比MySQL和Ignite的性能差異,以及如何同時(shí)使用兩套數(shù)據(jù)庫,這里小傅哥會(huì)在一個(gè)工程中分別配置出不同的數(shù)據(jù)庫對(duì)應(yīng)數(shù)據(jù)源的創(chuàng)建和MyBatis的配置用。如果說你做過小傅哥的 DB-Router 組件開發(fā),那么也可以在組件中添加對(duì)Ignite內(nèi)存數(shù)據(jù)庫的路由配置。這樣的使用會(huì)更加方便,也可以自動(dòng)的通過注解來切換數(shù)據(jù)源的使用。
-
- SpringBoot應(yīng)用的yml配置,本身默認(rèn)是配置一個(gè)數(shù)據(jù)源的。但我們這里需要把Ignite也配置出數(shù)據(jù)源并讓它可以結(jié)合MyBatis進(jìn)行使用。所以需要做一點(diǎn)編碼的擴(kuò)展使用。
具體可以參考源碼
- 與此同時(shí)還需要考慮對(duì) Dao、Mapper 分不同的路徑進(jìn)行加載使用。因?yàn)楸旧韥碚f,他們就是一套東西的不同數(shù)據(jù)源使用方式。
二、環(huán)境安裝
在安裝執(zhí)行 docker-compose.yml 腳本之前,你需要先在本地安裝 docker之后 IntelliJ IDEA 打開 docker-compose.yml 文件,如圖操作即可安裝。
- 在 docker-compose.yml 中會(huì)先安裝 MySQL 并執(zhí)行 sql 文件夾里的 SQL 語句初始化數(shù)據(jù)庫表。之后會(huì)安裝 Ignite 環(huán)境,安裝后需要用到 DBeaver 連接使用。同時(shí) compose 中還安裝了一個(gè) ApacheBench 壓測(cè)工具。
三、連接配置
首先確保你已經(jīng)安裝過 ?DBeaver ,之后就可以連接和創(chuàng)建表了。
1. 選擇 Ignite
2. 驗(yàn)證鏈接
3. 創(chuàng)建庫表
4. 創(chuàng)建完成
- 之后你所有做的修改,包括你自己手動(dòng)創(chuàng)建表、字段、索引,都需要點(diǎn)保存。否則它是紅色的,不生效。
四、功能配置
1. 工程結(jié)構(gòu)
- app層;application-dev.yml 配置多套數(shù)據(jù)源,并在 DataSourceConfig 中實(shí)現(xiàn)多套數(shù)據(jù)源的加載。infrastructure層;用于提供數(shù)據(jù)的 dao 層,這里分開2套分別提供。trigger;觸發(fā)器層,提供了調(diào)用 Ignite、MySQL 的測(cè)試驗(yàn)證接口。
2. 數(shù)據(jù)源創(chuàng)建
<!--?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>
- 注意引入 ignite 的 pom 配置
2.1 Ignite
源碼: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();
????}
}
- 創(chuàng)建 Ignite 的數(shù)據(jù)源,以及對(duì)應(yīng)的 igniteSqlSessionFactory 工廠。這樣就把 MyBatis 給關(guān)聯(lián)起來了。
2.2 MySQL
源碼: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();
????}
}
- 同樣,創(chuàng)建 MySQL 的數(shù)據(jù)源以及 MyBatis 的關(guān)聯(lián)操作。
五、性能測(cè)試
小傅哥提供了 IgniteController、MySQLController 兩個(gè) HTTP 訪問類,分別提供了兩個(gè)數(shù)據(jù)庫的壓測(cè)操作。
- 這里提供了 Ignite、MySQL 的 HTTP 訪問接口,分別進(jìn)行壓測(cè)。
1. Ignite 壓測(cè)
-
- 初始化ID值:
ab -c 1 -n 1 http://127.0.0.1:8091/api/ignite/start
-
- 寫入數(shù)據(jù):
ab -c 20 -n 50000 http://127.0.0.1:8091/api/ignite/insert
-
- 隨機(jī)加載內(nèi)存1000條數(shù)據(jù):
ab -c 20 -n 1000 http://127.0.0.1:8091/api/ignite/cacheData
-
- 根據(jù)加載到內(nèi)存的數(shù)據(jù)查詢Ignite:
ab -c 20 -n 1000 http://127.0.0.1:8091/api/ignite/selectByOrderId
- - 記得給 OrderId 加索引
2. MySQL 壓測(cè)
-
- 初始化ID值:
ab -c 1 -n 1 http://127.0.0.1:8091/api/ignite/start
-
- 寫入數(shù)據(jù):
ab -c 20 -n 50000 http://127.0.0.1:8091/api/ignite/insert
-
- 隨機(jī)加載內(nèi)存1000條數(shù)據(jù):
ab -c 20 -n 1000 http://127.0.0.1:8091/api/ignite/cacheData
-
- 根據(jù)加載到內(nèi)存的數(shù)據(jù)查詢MySQL:
ab -c 20 -n 1000 http://127.0.0.1:8091/api/ignite/selectByOrderId
- - 記得給 OrderId 加索引
綜上,Ignite 略勝一籌,確實(shí)純內(nèi)存的數(shù)據(jù)庫會(huì)更快一些。也適合在一些需要內(nèi)存計(jì)算的場(chǎng)景中,并且不改變MySQL表結(jié)構(gòu)的情況下,做一些優(yōu)化的是使用。
- 180天小卡拉米專屬學(xué)習(xí)路線又完結(jié)一個(gè)新項(xiàng)目,小而美、小而精!從MVC到DDD,架構(gòu)的本質(zhì)API網(wǎng)關(guān)架構(gòu)設(shè)計(jì),從單體服務(wù)到微服務(wù)的架構(gòu)演進(jìn)Java 面經(jīng)手冊(cè)