WEBサービスで使う機械学習のモデルを実現するためにJAVAのヒープを使うっていう話もあったが、
メモリに頼ったやり方だとモデルが巨大化していった時にスケールしにくいし、ユーザ0のうちから金がかかるのは微妙。
なので、SQLite+ヒープのキャッシュで賄う方向性について模索中。
■ 環境構築
glassfishを使う場合、管理コンソールでの特別な設定は不要。
たぶんあれはプールしたいときに必要。でも、たしかどっかの記事でSQLiteではコネクションをPoolする意味ないみたいなのを読んだ気がする。
jarはここから最新のを落として、
xerial / sqlite-jdbc / Downloads — Bitbucket
以下の3箇所に配置。たぶん全部は必要ない。おいたらGlassfishのdomain再起動が必要。
・src/lib/以下
・略glassfish-4.1/glassfish/lib/
・略glassfish-4.1/glassfish/domains/domain1/lib/
古いjarバージョンだと、readonlyモードに切り替えられなくてハマった。
それと、複数の異なるバージョンを同じディレクトリに置かないほうがいい。
pom.xml
<dependency>
<groupId>sqlite-jdbc-3.8.10.1.jar</groupId>
<artifactId>sqlite-jdbc-3.8.10.1.jar</artifactId>
<version>3.8.10.1</version>
<scope>system</scope>
<systemPath>${basedir}/src/lib/sqlite-jdbc-3.8.10.1.jar</systemPath>
</dependency>
■ 実験
main.java
Class.forName("org.sqlite.JDBC");
SQLiteConfig config = new SQLiteConfig();
config.setReadOnly(true);
conn = DriverManager.getConnection("jdbc:SQLite:" + DB_PATH, config.toProperties());
System.out.println("readonly:" + conn.isReadOnly());
同時に読み込みできるかtest
ab -n 2 -c 2 http://localhost:8080/TEST/rest/test
readOnlyモードが無効だった時はコンソールに「[SQLITE_BUSY] The database file is locked (database is locked) 」がでていたが、うまくいくと2つ以上のアクセスを同時にさばくことができた。
ーー
次に1つのスレッドがINSERTする中で、複数のREAD ONLYな処理を捌けるのかを確かめてみる.
非ReadOnlyモードで1秒間に2回INSERTを行い続ける中で、別のスレッドで数十秒レベルのSELECTをReadOnlyモードで行い続けた。
その結果、SELECT文の時間が1.5倍くらいになったものの、ロックエラーはでることはなくなった。