sgykfjsm.github.com

Play!のDB設定について

自分が開発したわけでもないのだけれど、APIのパフォーマンスをどうにかしろ、チューニングしろと言われた。チューニング対象のAPIはPlay!を利用しており、DBのI/Oにパフォーマンスが強く依存するので、まずはDB周りのパラメータをしらべて改善していくことにした。

DBの接続周りを改善していくにあたって、Thread Poolへの理解は欠かせないのだけれど、Play!のドキュメントだとAkkaとかが出てきて、もう少し基本的な部分からおさらいしたいなーと思ったので、ソースから調べることにした。

DB.scalaはPlayのDB接続周りを管理している。class BoneCPPluginでconfigファイルからDBの設定を取得している。この辺に注目していけばよさそう。このあたりに書かれている設定に関して言えば、基本は言語やフレームワークに依存しない部分なはずなのでこれまでの経験とか勘が活かせるかなーと思った次第。

ということで、今回はこのソースに書かれている設定を整理する。

接続

ラベルのプレフィクスにはdb.dbName.がつく。

ラベル 設定値の型 概要 メモ
driver string DBドライバ名
autocommit Boolean autocommitを有効にするかどうか defaultはtrue
isolation string NONE / READ_COMMITTED / READ_UNCOMMITTED / REPEATABLE_READ / SERIALIZABLE 大文字
defaultCatalog string デフォルトのDBカタログ名 Postgresqlなど?DB2かも?
readOnly Boolean 読み取り専用アクセスとするか否か defaultはfalse
url string DBの接続文字列
user string DBの接続ユーザ
pass string DBの接続パスワード
password string DBの接続パスワード

Pool configuration

ここの設定項目はBoneCPの設定とほぼ同一だが、初期値の設定が異なっている。
BoneCPの接続数を計算する場合はmaxConnectionsPerPartition * partitionCountとなることを押さえておけばよさそう。

ラベルのプレフィクスにはdb.dbName.がつく。

ラベル 設定値の型 概要 メモ
partitionCount Int スレッドプール単体での同時接続数 defaultは1。CPUのコア数と揃えたほうが良い。1
maxConnectionsPerPartition Int partitionごとに作られる最大同時接続数 defaultは30。
minConnectionsPerPartition Int partitionごとに同時接続開始数 defaultは5
acquireIncrement Int 接続が切れそうになるとBoneCPが接続を新たに生成する数。partiticonごとに作用する。 defaultは1
acquireRetryAttempts Int 接続試行回数 defaultは10
acquireRetryDelay Int 接続に失敗して次の試行までの待ち時間 defaultは1000。単位はMillSeconds
connectionTimeout Int getConnetionを呼び出してからタイムアウトするまでの待ち時間 defaultは1000。単位はMillSeconds
idleMaxAge Int 接続が閉じられるまで使われていない接続を維持する時間。 defaultは1000 * 60 * 10。単位はMillSeconds。つまりdefaultはアイドル時間が10分。
maxConnectionAge Int 接続を強制的に閉じるための判断に使う時間。ここで指定された時間を超えて存在する接続はアイドルであるか否かを問わず閉じられる。プールに戻されるまでは使用中の接続には影響しない defaultは1000 * 60 * 60。単位はMillSeconds。つまりdefaultでは生成から60分を超えた接続は閉じられる。
disableJMX Boolean JMXを有効にしないかどうか defaultはtrue。つまり有効にしない。
statisticsEnabled Boolean 統計情報の出力を有効にするかどうか(?) defaultはfalse
idleConnectionTestPeriod Int DBにテストクエリを送出するまで接続のアイドルを維持する時間。 defaultは1000 * 60。単位はMillSeconds。つまりdefaultは1分。
disableConnectionTracking Int connection trackingを有効にしないかどうか defaultはtrue
queryExecuteTimeLimit Int クエリをロギングするかどうかの基準となる時間。この指定時間を超えたクエリはロギングされる。 defaultはゼロ。つまりどれだけ時間がかかってもロギングしない。単位はMillSeconds

その他の設定

初期値が設定されていないが、それはおそらくドライバ依存だからだと思う。

ラベルのプレフィクスにはdb.dbName.がつく。

ラベル 設定値の型 概要 メモ
initSQL String 接続が確立されるときに一度だけ実行されるSQL。これは接続ごとに実行される。
logStatements Boolean SQLをロギングするかどうか
connectionTestStatement String 接続テストのために実行されるクエリ
jndiName String JNDIネームスペースの指定

おまけ

DB接続文字列の正規表現

1
2
3
4
val PostgresFullUrl = "^postgres://([a-zA-Z0-9_]+):([^@]+)@([^/]+)/([^\\s]+)$".r
val MysqlFullUrl = "^mysql://([a-zA-Z0-9_]+):([^@]+)@([^/]+)/([^\\s]+)$".r
val MysqlCustomProperties = ".*\\?(.*)".r
val H2DefaultUrl = "^jdbc:h2:mem:.+".r

ここで使われている

MySQLの場合は以下が自動的に付与される

?useUnicode=yes&characterEncoding=UTF-8&connectionCollation=utf8_general_ci