apache ignite系列(九):使用ddl和dml腳本初始化ignite並使用mybatis查詢緩存


博客又斷了一段時間,本篇將記錄一下基於ignite對jdbc支持的特性在實際使用過程中的使用。

使用ddl和dml腳本初始化ignite

由於spring-boot中支持通過spring.datasource.schema屬性指定初始化DDL腳本,spring.datasource.data指定初始化DML腳本。而ignite支持jdbc協議,測試了一下,發現一樣可以通過該配置初始化ignite。

spring.datasource.url=jdbc:ignite:thin://127.0.0.1/
spring.datasource.driver-class-name=org.apache.ignite.IgniteJdbcThinDriver
spring.datasource.schema=classpath:db/schema.sql
spring.datasource.data=classpath:db/data.sql

說明ignite數據源同樣可以作為一個DataSource實例。

DDL的規范

創建表

CREATE TABLE [IF NOT EXISTS] tableName (tableColumn [, tableColumn]...
[, PRIMARY KEY (columnName [,columnName]...)])
[WITH "paramName=paramValue [,paramName=paramValue]..."]

WITH語法中支持的選項以及含義如下(可參見xml配置中CacheConfiguration的相關配置):

參數 含義
TEMPLATE 緩存模式:PARTITIONED或者REPLICATED
BACKUPS 備份數量
ATOMICITY 原子模式:ATOMIC或者TRANSACTIONAL
CACHEGROUP 緩存組名
AFFINITYKEY 並置鍵列名
CACHE_NAME 緩存名(如果不設置的話默認會加SQL_前綴)
KEY_TYPE 鍵類型
VALUE_TYPE 值類型
DATA_REGION 內存區名

創建索引

CREATE [SPATIAL] INDEX [[IF NOT EXISTS] indexName] ON tableName
    (columnName [ASC|DESC] [,...]) [(index_option [...])]

示例:

schema.sql

--student學生信息表
CREATE TABLE IF NOT EXISTS PUBLIC.STUDENT (
 STUDID INTEGER,
 NAME VARCHAR,
 EMAIL VARCHAR,
 dob Date,
 PRIMARY KEY (STUDID))
WITH "template=replicated,atomicity=ATOMIC,cache_name=student";

CREATE INDEX IF NOT EXISTS STUDENT_NE_INDEX ON PUBLIC.STUDENT (NAME, EMAIL);

-- grade成績表
CREATE TABLE IF NOT EXISTS PUBLIC.GRADE (
 STUDID INTEGER,
 grade DOUBLE,
 PRIMARY KEY (STUDID))
WITH "template=replicated,atomicity=ATOMIC,cache_name=grade";

DML規范

ignite中dml與標准sql中的基本一致示例如下:

INSERT INTO student (studid, name, email, dob) VALUES (1, 'student_1', 'student_1gmail.com', '2017-09-28');

完整dml初始化腳本:

-- student
INSERT INTO student (studid, name, email, dob) VALUES (1, 'student_1', 'student_1gmail.com', '2017-09-28');
INSERT INTO student (studid, name, email, dob) VALUES (2, 'student_2', 'student_2gmail.com', '2017-09-28');
...

--grade
INSERT INTO grade (studid, grade) VALUES (1,  3);
INSERT INTO grade (studid, grade) VALUES (2,  64);
...

注:如果使用了KEY_TYPE選項配置自定義KEY類型,那么要么在自定義類型中得有對應的構造方法,要么使用java內置類型的時候,insert語句必須帶上_key字段的值。

例如:
ddl語句中with選項為

WITH "template=replicated,atomicity=ATOMIC,cache_name=student,key_type=java.lang.Long";

那么dml語句就得像下面這么寫

INSERT INTO student (_key, studid, name, email, dob) VALUES (1, '1', 'student_1', 'student_1gmail.com', '2017-09-28');

初始化完成后可通過監控程序看到如下監控情況 :

ddl+dml

可以發現緩存和數據均已初始化成功。

使用Mybatis查詢ignite緩存

由於ignite可以作為DataSource的實例,所以猜想應該也可以通過Mybatis去查詢ignite,這樣可以替代原來需要SqlFieldsQuery查詢並對結果進行逐行解析的方式。經驗證后發現ignite能完美支持myabtis,所以在查詢ignite的方式上有了一個更便捷的方式。

與普通使用mybatis的方式一樣,定義IgniteMapper.xmlIgniteMapper.java

IgniteMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="org.cord.ignite.data.mapper.IgniteMapper">

    <resultMap type="org.cord.ignite.data.domain.Student" id="StudentResult">
        <result property="studId" column="studid"/>
        <result property="name" column="name"/>
        <result property="email" column="email"/>
        <result property="dob" column="dob"/>
    </resultMap>

    <select id="findStudentsById" parameterType="java.lang.String" resultMap="StudentResult">
        SELECT * FROM student WHERE studid = #{studentId}
    </select>

    <select id="findGradeByName" parameterType="java.lang.String" resultType="java.lang.Double">
        SELECT g.grade FROM student s,grade g WHERE s.STUDID=g.STUDID and s.name= #{name}
    </select>

</mapper>

IgniteMapper.java

public interface IgniteMapper {

    /**
     * 根據studentId查詢學生信息
     * @param studentId
     * @return Student
     */
    Student findStudentsById(String studentId);

    /**
     * 根據學生姓名查詢學生分數
     * @param name
     * @return 學生分數
     */
    Double findGradeByName(String name);
}

查詢:

  	...
  	@Autowired
    private IgniteMapper igniteMapper;
    ...
    Student student = igniteMapper.findStudentsById(studentId);
    ...
    double grade = igniteMapper.findGradeByName(name);

注:由於ignite中可以自定義sql函數,測試過,在mybatis中ignite的自定義sql函數同樣支持。

性能

由於ignite中jdbc的方式屬於輕客戶端,所以性能要比api的方式差,而在通過mybatis查詢的方式其性能表現通過測試得出的結果如下:

在相同的sql相同數據的情況下,100並發查詢:

mybatis查詢

/findStudentsById 耗時 [13]ms.
/findStudentsById 耗時 [9]ms.
/findStudentsById 耗時 [3]ms.
/findStudentsById 耗時 [10]ms.
/findStudentsById 耗時 [11]ms.
/findStudentsById 耗時 [11]ms.
/findStudentsById 耗時 [13]ms.
/findStudentsById 耗時 [8]ms.
/findStudentsById 耗時 [8]ms.
/findStudentsById 耗時 [14]ms.
/findStudentsById 耗時 [17]ms.
/findStudentsById 耗時 [11]ms.
/findStudentsById 耗時 [8]ms.
/findStudentsById 耗時 [13]ms.
/findStudentsById 耗時 [11]ms.
/findStudentsById 耗時 [10]ms.
/findStudentsById 耗時 [9]ms.
/findStudentsById 耗時 [10]ms.
/findStudentsById 耗時 [12]ms.
/findStudentsById 耗時 [9]ms.
/findStudentsById 耗時 [3]ms.
/findStudentsById 耗時 [3]ms.
...
/findStudentsById 耗時 [1]ms.
/findStudentsById 耗時 [2]ms.
/findStudentsById 耗時 [2]ms.
/findStudentsById 耗時 [2]ms.
/findStudentsById 耗時 [2]ms.
/findStudentsById 耗時 [2]ms.
/findStudentsById 耗時 [2]ms.
/findStudentsById 耗時 [2]ms.
/findStudentsById 耗時 [1]ms.
/findStudentsById 耗時 [1]ms.
/findStudentsById 耗時 [1]ms.
/findStudentsById 耗時 [0]ms.

吞吐量為537/sec, 性能有波動情況,穩定后在2ms左右。

api查詢

/cpFindStudentsById 耗時 [0]ms.
/cpFindStudentsById 耗時 [0]ms.
/cpFindStudentsById 耗時 [0]ms.
/cpFindStudentsById 耗時 [0]ms.
/cpFindStudentsById 耗時 [0]ms.
/cpFindStudentsById 耗時 [0]ms.
/cpFindStudentsById 耗時 [0]ms.
/cpFindStudentsById 耗時 [0]ms.
/cpFindStudentsById 耗時 [0]ms.
/cpFindStudentsById 耗時 [0]ms.
/cpFindStudentsById 耗時 [0]ms.
/cpFindStudentsById 耗時 [1]ms.
/cpFindStudentsById 耗時 [0]ms.
/cpFindStudentsById 耗時 [0]ms.
/cpFindStudentsById 耗時 [1]ms.
/cpFindStudentsById 耗時 [0]ms.
/cpFindStudentsById 耗時 [0]ms.
/cpFindStudentsById 耗時 [0]ms.
/cpFindStudentsById 耗時 [0]ms.

吞吐量為1256/sec,性能比較穩定,穩定后在1ms以內。

完整代碼請參考https://github.com/cording/ignite-example

結論

​ 對於不是要求極限性能的場景,mybatis查詢方式完全能滿足,這使得對於很多現有基於myabtis的項目代碼,能相對平滑的使用ignite作為加速層,而又不用做過多改動。

​ 還有,寫博客確實有點費時間....................


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM