追記@2019/05/23
アドバイスもらったので追記。
https://qiita.com/sky0621/items/8792b54ebf6bd21bcf72#追記
お題
表題の通り。
Cloud SQLはマシンタイプ別に最大同時接続数が変わる。
例えば、db-g1-small
インスタンスなら「1000
」まで。(ちなみに、今回の実験では、このインスタンスを使用)
マシンタイプ | 最大同時接続数 |
---|---|
db-f1-micro | 250 |
db-g1-small | 1,000 |
その他のすべてのマシンタイプ | 4,000 |
【参考】
https://cloud.google.com/sql/docs/quotas?hl=ja#fixed-limits
そして、もう1点。
App EngineからCloud SQLへの接続時の制限に関して説明するページに以下の記載がある。
「スタンダード環境で動作する各 App Engine インスタンスは、Cloud SQL インスタンスに対する同時接続数が最大 100 個に制限されます。Java 7、Go 1.6、PHP 5.5 のアプリケーションでは、同時接続数が最大 60 個に制限されます。
」
念の為、英語サイトの方も確認。
https://cloud.google.com/appengine/docs/standard/go/cloud-sql/pricing-access-limits?hl=en#app_engine
「Each App Engine instance running in the standard environment cannot have more than 100 concurrent connections to a Cloud SQL instance. For Java 7, Go 1.6, or PHP 5.5 apps the limit is 60 concurrent connections.
」
それぞれのApp EngineインスタンスからCloud SQLインスタンスに接続できる数は「100
」までという制限がある。
「100
」を超えたらどうなるのか? そもそも超えることはできるのか? これらについて実験してみる。
ちなみに、実験結果のまとめは下記。
https://qiita.com/sky0621/items/8792b54ebf6bd21bcf72#まとめ
前提
- GCPは知っている。
- Google App Engineのことも名前とどういったものかくらいは知っている。
- MySQL等、リレーショナルデータベースについて、ざっくりとはわかっている。
以下は済んだ上での作業。
- GCPプロジェクトの作成
- Cloud SDKのインストールと初期化・認証
開発環境
# OS
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.2 LTS (Bionic Beaver)"
# Cloud SDK
$ gcloud version
Google Cloud SDK 246.0.0
# Golang
$ go version
go version go1.11.4 linux/amd64
# Vegeta
$ vegeta -version
Version: cli/v12.2.0
Commit: 65db074680f5a0860d495e5fd037074296a4c425
Runtime: go1.11.4 linux/amd64
Date: 2019-01-20T15:07:37Z+0000
実践
準備
Cloud SQL上に「db-g1-small
」タイプのインスタンスを作成後、「fs14db01
」という名前でデータベース作成。
※前回参照。
Goアプリのソース
main.go
package main
import (
"fmt"
"net/http"
"os"
"github.com/jinzhu/gorm"
"github.com/google/uuid"
_ "github.com/go-sql-driver/mysql"
"github.com/labstack/echo"
)
func main() {
db, err := gorm.Open("mysql",
fmt.Sprintf("root:%s@unix(/cloudsql/%s)/fs14db01?parseTime=True",
os.Getenv("PASS"), os.Getenv("CONN")))
if err != nil {
panic(err)
}
defer func() {
if err := db.Close(); err != nil {
panic(err)
}
}()
// --------------------------------------------------------------
// Pattern 1
//db.DB().SetMaxIdleConns(0)
//db.DB().SetMaxOpenConns(0)
// Pattern 2
//db.DB().SetMaxIdleConns(0)
//db.DB().SetMaxOpenConns(95)
// Pattern 3
//db.DB().SetMaxIdleConns(0)
//db.DB().SetMaxOpenConns(200)
// Pattern 4
//db.DB().SetMaxIdleConns(95)
//db.DB().SetMaxOpenConns(95)
// Pattern 5
//db.DB().SetMaxIdleConns(200)
//db.DB().SetMaxOpenConns(200)
// Pattern 5
//db.DB().SetMaxIdleConns(1000)
//db.DB().SetMaxOpenConns(1000)
// --------------------------------------------------------------
↑のコメントアウトした部分が今回の実験の肝。
詳細は後述。
e := echo.New()
e.POST("/user", func(c echo.Context) error {
id := uuid.New().String()
u := &User{
ID: id,
Name: fmt.Sprintf("user-%s", id),
Mail: fmt.Sprintf("mail-%s@example.com", id),
}
if err := db.Save(u).Error; err != nil {
return c.JSON(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
}
return c.JSON(http.StatusOK, "OK")
})
e.Logger.Fatal(e.Start(fmt.Sprintf(":%s", os.Getenv("PORT"))))
}
type User struct {
ID string `gorm:"column:id"`
Name string `gorm:"column:name"`
Mail string `gorm:"column:mail"`
}
func (u *User) TableName() string {
return "user"
}
app.yaml
runtime: go111
includes:
- secret.yaml
secret.yaml
env_variables:
CONN: 【自分のGCPプロジェクトID】:asia-northeast1:sample-001
PASS: 【Cloud SQLの対象DBのパスワード】
実験の肝
先述の通り、ソース中、コメントアウトした部分(DB接続時のコネクションの扱い方)が肝。
最大アイドルコネクション数の設定
アイドル状態にしておくコネクション数。現時点でデフォルトは「2
」。
「0
以下」ならアイドリング状態にしない。
後述の「最大オープンコネクション数(が0でなく)」を超えた設定をしても最大オープンコネクション数と合わせられる想定。
// SetMaxIdleConns sets the maximum number of connections in the idle
// connection pool.
//
// If MaxOpenConns is greater than 0 but less than the new MaxIdleConns,
// then the new MaxIdleConns will be reduced to match the MaxOpenConns limit.
//
// If n <= 0, no idle connections are retained.
//
// The default max idle connections is currently 2. This may change in
// a future release.
func (db *DB) SetMaxIdleConns(n int) {
最大オープンコネクション数の設定
オープンできるコネクション数の限界。デフォルトは「0
」で、0の場合は限度なくオープンしにいく。
// SetMaxOpenConns sets the maximum number of open connections to the database.
//
// If MaxIdleConns is greater than 0 and the new MaxOpenConns is less than
// MaxIdleConns, then MaxIdleConns will be reduced to match the new
// MaxOpenConns limit.
//
// If n <= 0, then there is no limit on the number of open connections.
// The default is 0 (unlimited).
func (db *DB) SetMaxOpenConns(n int) {
実験
「最大アイドルコネクション数」と「最大オープンコネクション数」を変えながら、App EngineからCloud SQLへの接続時の制限とされている「1インスタンスあたりの最大同時接続数=100
」を超えた場合の挙動を確認する。
「Vegeta」という負荷ツールを使って、毎秒 X リクエストを5秒間流してみる。
※「X」は実験内容に応じて変更
<コマンド例>
$ echo "POST https://idle0-open-unlimited-dot-【自分のGCPプロジェクトID】.appspot.com/user" | vegeta attack -output=/tmp/vegeta_result.bin -rate=200 -duration=5s
上記は「最大アイドルコネクション数」と「最大オープンコネクション数」ともに「0」の設定で実装したアプリに対して、毎秒 200 リクエストを5秒間実行するもの。
■アイドルせず無制限にコネクションオープン
実験内容
以下それぞれのレートで挙動を確認する。
- 毎秒 100 リクエスト
- 毎秒 200 リクエスト
結果予想
毎秒 100 リクエストは問題なく全てのリクエストで 200 OK レスポンスを返す。
それ以外のケースでは、1App Engineインスタンスがリクエストをさばくために同じインスタンスから際限なくCloud SQLにコネクション張りにいき、処理しきれなく失敗となるレスポンスが発生する。
実施
【毎秒 100 リクエストを5回分】
Latencies [mean, 50, 95, 99, max] 384.081067ms, 373.585ms, 509.772127ms, 566.791891ms, 595.885825ms
Latencies [mean, 50, 95, 99, max] 358.286961ms, 375.221102ms, 475.857641ms, 580.513767ms, 946.918016ms
Latencies [mean, 50, 95, 99, max] 348.681478ms, 300.569866ms, 607.253861ms, 670.309172ms, 711.820514ms
Latencies [mean, 50, 95, 99, max] 374.172648ms, 389.652528ms, 538.911238ms, 604.715239ms, 643.523716ms
Latencies [mean, 50, 95, 99, max] 433.331276ms, 436.36702ms, 532.807731ms, 566.448641ms, 579.696203ms
Success [ratio] 100.00%
Success [ratio] 98.00%
Success [ratio] 100.00%
Success [ratio] 97.80%
Success [ratio] 99.60%
【毎秒 200 リクエスト】
Latencies [mean, 50, 95, 99, max] 3.656447528s, 2.87129807s, 8.332759389s, 9.642830969s, 10.964205628s
Latencies [mean, 50, 95, 99, max] 3.285328297s, 2.518179725s, 7.513602241s, 8.775689476s, 9.69245987s
Latencies [mean, 50, 95, 99, max] 3.221727209s, 2.5302591s, 7.36735507s, 8.529768254s, 9.685437683s
Latencies [mean, 50, 95, 99, max] 3.191123034s, 2.453029911s, 7.195667353s, 8.48264967s, 8.992381951s
Latencies [mean, 50, 95, 99, max] 3.243005216s, 2.496180582s, 7.379312657s, 8.611970742s, 9.856214946s
Success [ratio] 100.00%
Success [ratio] 100.00%
Success [ratio] 100.00%
Success [ratio] 99.00%
Success [ratio] 99.00%
結果
レートに関わらず、エラーが発生する回があらわれた。
アイドリングせず、リクエストがあれば無制限にコネクションオープンする設定においては、明確に以下の制限がわかる挙動にならなかった。
それぞれのApp EngineインスタンスからCloud SQLインスタンスに接続できる数は「100
」までという制限がある。
■アイドルせずApp Engineの1インスタンスからCloud SQLインスタンスへの同時接続数は「95」
実験内容
以下それぞれのレートで挙動を確認する。
- 毎秒 100 リクエスト
- 毎秒 200 リクエスト
結果予想
全てのケースで全リクエスト 200 OK レスポンスを返す。
実施
【毎秒 100 リクエスト】
Latencies [mean, 50, 95, 99, max] 452.889849ms, 441.297314ms, 601.168658ms, 658.985005ms, 695.736952ms
Latencies [mean, 50, 95, 99, max] 544.325051ms, 524.937348ms, 736.472778ms, 762.562193ms, 797.121262ms
Latencies [mean, 50, 95, 99, max] 424.314663ms, 400.245986ms, 624.663188ms, 685.486331ms, 735.182867ms
Latencies [mean, 50, 95, 99, max] 359.927434ms, 369.749875ms, 437.679054ms, 459.184288ms, 479.638534ms
Latencies [mean, 50, 95, 99, max] 420.811133ms, 410.380115ms, 687.227128ms, 826.540714ms, 1.310744809s
Success [ratio] 100.00%
Success [ratio] 100.00%
Success [ratio] 100.00%
Success [ratio] 100.00%
Success [ratio] 98.00%
【毎秒 200 リクエスト】
Latencies [mean, 50, 95, 99, max] 2.884555846s, 2.132597469s, 6.722514625s, 8.060224999s, 9.17968338s
Latencies [mean, 50, 95, 99, max] 3.241793149s, 2.570532677s, 7.219441917s, 8.723126801s, 9.771961486s
Latencies [mean, 50, 95, 99, max] 3.250406007s, 2.494085705s, 7.375126147s, 8.994445098s, 9.536050535s
Latencies [mean, 50, 95, 99, max] 3.349980365s, 2.612510507s, 7.615872613s, 8.907686483s, 10.00627403s
Latencies [mean, 50, 95, 99, max] 3.167480322s, 2.393982007s, 7.191928282s, 8.429845004s, 9.732517788s
Success [ratio] 95.90%
Success [ratio] 100.00%
Success [ratio] 99.90%
Success [ratio] 100.00%
Success [ratio] 99.00%
結果
やはり、レートに関わらず、エラーが発生する回があらわれた。
エラーの内容は下記。
Error Set:
Post https://open-95-dot-【自分のGCPプロジェクトID】.appspot.com/user: http2: timeout awaiting response headers
■App Engineの1インスタンスからCloud SQLインスタンスへの同時接続数は「95」、アイドル中の接続数「95」
実験内容
以下それぞれのレートで挙動を確認する。
- 毎秒 100 リクエスト
- 毎秒 200 リクエスト
結果予想
全てのケースで全リクエスト 200 OK レスポンスを返す。
実施
【毎秒 100 リクエスト】
Latencies [mean, 50, 95, 99, max] 63.29288ms, 58.153708ms, 118.887245ms, 150.737303ms, 177.86988ms
Latencies [mean, 50, 95, 99, max] 48.615312ms, 36.542679ms, 98.190003ms, 190.009727ms, 220.432868ms
Latencies [mean, 50, 95, 99, max] 41.683938ms, 32.352082ms, 83.821587ms, 130.818981ms, 168.576253ms
Latencies [mean, 50, 95, 99, max] 44.639441ms, 37.782216ms, 90.53393ms, 178.503114ms, 247.647451ms
Latencies [mean, 50, 95, 99, max] 39.65634ms, 27.778945ms, 82.746423ms, 153.609157ms, 194.314567ms
Success [ratio] 100.00%
Success [ratio] 100.00%
Success [ratio] 100.00%
Success [ratio] 100.00%
Success [ratio] 100.00%
【毎秒 200 リクエスト】
Latencies [mean, 50, 95, 99, max] 67.411761ms, 50.444954ms, 154.428824ms, 235.421379ms, 461.221026ms
Latencies [mean, 50, 95, 99, max] 33.590508ms, 25.526145ms, 76.341847ms, 106.224266ms, 164.443519ms
Latencies [mean, 50, 95, 99, max] 51.818999ms, 39.502633ms, 123.317561ms, 226.575409ms, 698.368402ms
Latencies [mean, 50, 95, 99, max] 44.985059ms, 36.407095ms, 99.617469ms, 155.426199ms, 200.001371ms
Latencies [mean, 50, 95, 99, max] 36.939052ms, 27.502926ms, 80.993458ms, 171.622113ms, 221.517229ms
Success [ratio] 100.00%
Success [ratio] 100.00%
Success [ratio] 97.60%
Success [ratio] 100.00%
Success [ratio] 100.00%
【毎秒 1000 リクエスト】
Latencies [mean, 50, 95, 99, max] 3.961474048s, 3.502336695s, 8.950770485s, 10.394910039s, 11.772457859s
Latencies [mean, 50, 95, 99, max] 2.932212248s, 2.387595818s, 7.209837606s, 8.700746092s, 10.033527918s
Latencies [mean, 50, 95, 99, max] 3.064551746s, 2.409040168s, 7.537645463s, 8.837644957s, 10.498085764s
Latencies [mean, 50, 95, 99, max] 3.286309375s, 2.521588034s, 8.251770507s, 9.744014212s, 11.461399857s
Latencies [mean, 50, 95, 99, max] 2.781278591s, 2.147507557s, 6.995549716s, 8.492080548s, 10.129869204s
Success [ratio] 98.90%
Success [ratio] 100.00%
Success [ratio] 98.76%
Success [ratio] 100.00%
Success [ratio] 100.00%
結果
やはり、レートに関わらず、エラーが発生する回があらわれた。
「MaxIdleConns
」と「MaxOpenConns
」ともに以下ぎりぎりの数値にしてもエラーが発生する。
「1インスタンスあたりの最大同時接続数=100
」
Latencies [mean, 50, 95, 99, max] 61.774114ms, 45.738899ms, 158.331009ms, 260.890918ms, 452.438621ms
Latencies [mean, 50, 95, 99, max] 35.424859ms, 27.079778ms, 72.247126ms, 154.002554ms, 203.513374ms
Latencies [mean, 50, 95, 99, max] 44.677085ms, 33.469162ms, 99.395694ms, 168.410454ms, 274.188638ms
Latencies [mean, 50, 95, 99, max] 39.311035ms, 29.595308ms, 83.610205ms, 177.312437ms, 219.554742ms
Latencies [mean, 50, 95, 99, max] 55.206895ms, 45.538022ms, 110.174877ms, 156.045373ms, 199.244258ms
■App Engineの1インスタンスからCloud SQLインスタンスへの同時接続数は「200」、アイドル中の接続数「200」
実験内容
以下それぞれのレートで挙動を確認する。
- 毎秒 100 リクエスト
- 毎秒 200 リクエスト
結果予想
全てのケースで全リクエスト 200 OK レスポンスを返す。
実施
【毎秒 100 リクエスト】
Latencies [mean, 50, 95, 99, max] 61.774114ms, 45.738899ms, 158.331009ms, 260.890918ms, 452.438621ms
Latencies [mean, 50, 95, 99, max] 35.424859ms, 27.079778ms, 72.247126ms, 154.002554ms, 203.513374ms
Latencies [mean, 50, 95, 99, max] 44.677085ms, 33.469162ms, 99.395694ms, 168.410454ms, 274.188638ms
Latencies [mean, 50, 95, 99, max] 39.311035ms, 29.595308ms, 83.610205ms, 177.312437ms, 219.554742ms
Latencies [mean, 50, 95, 99, max] 55.206895ms, 45.538022ms, 110.174877ms, 156.045373ms, 199.244258ms
Success [ratio] 100.00%
Success [ratio] 100.00%
Success [ratio] 100.00%
Success [ratio] 100.00%
Success [ratio] 100.00%
【毎秒 200 リクエスト】
Latencies [mean, 50, 95, 99, max] 65.297997ms, 46.328684ms, 193.928049ms, 430.665045ms, 1.035112389s
Latencies [mean, 50, 95, 99, max] 47.575763ms, 39.133648ms, 93.807154ms, 175.933489ms, 226.582291ms
Latencies [mean, 50, 95, 99, max] 61.042032ms, 45.306004ms, 177.094469ms, 288.253016ms, 360.405968ms
Latencies [mean, 50, 95, 99, max] 86.173406ms, 55.221664ms, 246.068954ms, 362.140172ms, 794.767386ms
Latencies [mean, 50, 95, 99, max] 71.282898ms, 53.339071ms, 164.91989ms, 334.030611ms, 391.249248ms
Success [ratio] 100.00%
Success [ratio] 100.00%
Success [ratio] 100.00%
Success [ratio] 100.00%
Success [ratio] 100.00%
【毎秒 500 リクエスト】
Latencies [mean, 50, 95, 99, max] 175.614195ms, 163.973076ms, 357.234646ms, 556.376964ms, 1.061742841s
Latencies [mean, 50, 95, 99, max] 836.468549ms, 669.739234ms, 2.126049478s, 3.004736981s, 4.667805048s
Latencies [mean, 50, 95, 99, max] 621.899782ms, 473.544358ms, 1.565957858s, 2.353069857s, 3.175849897s
Latencies [mean, 50, 95, 99, max] 531.594674ms, 424.57262ms, 1.302940472s, 1.757911144s, 3.494456259s
Latencies [mean, 50, 95, 99, max] 116.755608ms, 100.680707ms, 254.908827ms, 351.484135ms, 2.023495735s
Success [ratio] 99.84%
Success [ratio] 100.00%
Success [ratio] 100.00%
Success [ratio] 100.00%
Success [ratio] 97.04%
■App Engineの1インスタンスからCloud SQLインスタンスへの同時接続数は「1000」、アイドル中の接続数「1000」
実験内容
以下それぞれのレートで挙動を確認する。
- 毎秒 500 リクエスト
- 毎秒 1000 リクエスト
結果予想
全てのケースで全リクエスト 200 OK レスポンスを返す。
実施
【毎秒 500 リクエスト】
Latencies [mean, 50, 95, 99, max] 568.785372ms, 440.275159ms, 1.332036036s, 2.033318787s, 2.992619632s
Latencies [mean, 50, 95, 99, max] 494.718679ms, 345.014322ms, 1.37466731s, 1.957682831s, 2.884500171s
Latencies [mean, 50, 95, 99, max] 585.637774ms, 435.852227ms, 1.505050567s, 2.182076798s, 3.13677678s
Latencies [mean, 50, 95, 99, max] 564.618249ms, 426.371331ms, 1.502413537s, 2.206958146s, 4.03235266s
Latencies [mean, 50, 95, 99, max] 382.541357ms, 325.446928ms, 877.323339ms, 1.282798842s, 2.280180238s
Success [ratio] 100.00%
Success [ratio] 100.00%
Success [ratio] 100.00%
Success [ratio] 100.00%
Success [ratio] 97.32%
【毎秒 1000 リクエスト】
Latencies [mean, 50, 95, 99, max] 2.966114857s, 2.254049409s, 7.525979114s, 8.963435191s, 10.119524818s
Latencies [mean, 50, 95, 99, max] 3.029569385s, 2.502902361s, 7.436747535s, 9.017578718s, 10.497356724s
Latencies [mean, 50, 95, 99, max] 3.210386112s, 2.682305189s, 7.752421804s, 9.184400957s, 10.409681587s
Latencies [mean, 50, 95, 99, max] 3.123610982s, 2.622561986s, 7.491094617s, 8.867739566s, 10.348725103s
Latencies [mean, 50, 95, 99, max] 3.27176631s, 2.829572453s, 7.693434499s, 9.049754142s, 10.556765042s
Success [ratio] 100.00%
Success [ratio] 98.62%
Success [ratio] 100.00%
Success [ratio] 100.00%
Success [ratio] 99.44%
まとめ
想定と違っていて、困惑。
それぞれのApp EngineインスタンスからCloud SQLインスタンスに接続できる数は「100
」までという制限がある。
とのことなので、「SetMaxIdleConns
」及び「SetMaxOpenConns
」で指定すべきは「100
未満」と想定していた。
が、実際は、「1000
」を指定していたとしても、それによってメモリを圧迫して異常終了するでもない。
どのような設定であっても一定の割合で以下のようにタイムアウトは発生する。
Error Set:
Post https://open-95-dot-【自分のGCPプロジェクトID】.appspot.com/user: http2: timeout awaiting response headers
傾向としては、負荷に対して十分な MaxIdleConns
を設定していた場合にレイテンシーの改善とエラー発生率の減少が見られる。
(ただ、それも毎秒 100 ないし 200 リクエストまでの傾向で、毎秒 500 リクエスト以上になってくると、それほどはっきりとは言えない。)
【毎秒 100 リクエストを5回分】
No | MaxIdleConns | MaxOpenConns | Latencies (mean) |
Success (%) |
---|---|---|---|---|
01a | 0 | 0 | 384.081067ms | 100 |
01b | 0 | 0 | 358.286961ms | 98 |
01c | 0 | 0 | 348.681478ms | 100 |
01d | 0 | 0 | 374.172648ms | 97.8 |
01e | 0 | 0 | 433.331276ms | 99.6 |
02a | 0 | 95 | 452.88984ms | 100 |
02b | 0 | 95 | 544.325051ms | 100 |
02c | 0 | 95 | 424.314663ms | 100 |
02d | 0 | 95 | 359.927434ms | 100 |
02e | 0 | 95 | 420.811133ms | 98 |
03a | 95 | 95 | 63.29288ms | 100 |
03b | 95 | 95 | 48.615312ms | 100 |
03c | 95 | 95 | 41.683938ms | 100 |
03d | 95 | 95 | 44.639441ms | 100 |
03e | 95 | 95 | 39.65634ms | 100 |
04a | 200 | 200 | 61.774114ms | 100 |
04b | 200 | 200 | 35.424859ms | 100 |
04c | 200 | 200 | 44.677085ms | 100 |
04d | 200 | 200 | 39.311035ms | 100 |
04e | 200 | 200 | 55.206895ms | 100 |
【毎秒 200 リクエストを5回分】
No | MaxIdleConns | MaxOpenConns | Latencies (mean) |
Success (%) |
---|---|---|---|---|
01a | 0 | 0 | 3.656447528s | 100 |
01b | 0 | 0 | 3.285328297s | 100 |
01c | 0 | 0 | 3.221727209s | 100 |
01d | 0 | 0 | 3.191123034s | 99 |
01e | 0 | 0 | 3.243005216s | 99 |
02a | 0 | 95 | 2.884555846s | 95.9 |
02b | 0 | 95 | 3.241793149s | 100 |
02c | 0 | 95 | 3.250406007s | 99.9 |
02d | 0 | 95 | 3.349980365s | 100 |
02e | 0 | 95 | 3.167480322s | 99 |
03a | 95 | 95 | 67.411761ms | 100 |
03b | 95 | 95 | 33.590508ms | 100 |
03c | 95 | 95 | 51.818999ms | 97.6 |
03d | 95 | 95 | 44.985059ms | 100 |
03e | 95 | 95 | 36.939052ms | 100 |
04a | 200 | 200 | 65.297997ms | 100 |
04b | 200 | 200 | 47.575763ms | 100 |
04c | 200 | 200 | 61.042032ms | 100 |
04d | 200 | 200 | 86.173406ms | 100 |
04e | 200 | 200 | 71.282898ms | 100 |
【毎秒 500 リクエストを5回分】
No | MaxIdleConns | MaxOpenConns | Latencies (mean) |
Success (%) |
---|---|---|---|---|
01a | 200 | 200 | 175.614195ms | 99.84 |
01b | 200 | 200 | 836.468549ms | 100 |
01c | 200 | 200 | 621.899782ms | 100 |
01d | 200 | 200 | 531.594674ms | 100 |
01e | 200 | 200 | 116.755608ms | 97.4 |
02a | 1000 | 1000 | 568.785372ms | 100 |
02b | 1000 | 1000 | 494.718679ms | 100 |
02c | 1000 | 1000 | 585.637774ms | 100 |
02d | 1000 | 1000 | 564.618249ms | 100 |
02e | 1000 | 1000 | 382.541357ms | 97.32 |
【毎秒 1000 リクエストを5回分】
No | MaxIdleConns | MaxOpenConns | Latencies (mean) |
Success (%) |
---|---|---|---|---|
01a | 95 | 95 | 3.961474048s | 98.9 |
01b | 95 | 95 | 2.932212248s | 100 |
01c | 95 | 95 | 3.064551746s | 98.76 |
01d | 95 | 95 | 3.286309375s | 100 |
01e | 95 | 95 | 2.781278591s | 100 |
02a | 1000 | 1000 | 2.966114857s | 100 |
02b | 1000 | 1000 | 3.029569385s | 98.62 |
02c | 1000 | 1000 | 3.210386112s | 100 |
02d | 1000 | 1000 | 3.123610982s | 100 |
02e | 1000 | 1000 | 3.27176631s | 99.44 |
う〜ん、わからない。
追記
あらためて、アイドルコネクション数0、最大同時接続数が無制限のアプリ設定で、秒間 5000 リクエストを5秒間実施。
Cloud SQLの設定再確認
実施
$ echo "POST https://open-unlimited-dot-【自分のGCPプロジェクトID】.appspot.com/user" | vegeta attack -output=/tmp/vegeta_result.bin -rate=1000 -duration=5s
$
終わるまで5秒以上かかったものの、終了。
結果
$ vegeta report /tmp/vegeta_result.bin
Requests [total, rate] 5000, 999.22
Duration [total, attack, wait] 54.804763323s, 5.003926215s, 49.800837108s
Latencies [mean, 50, 95, 99, max] 26.352328518s, 26.673000774s, 50.182139085s, 52.820348481s, 54.682983988s
Bytes In [total, mean] 25000, 5.00
Bytes Out [total, mean] 0, 0.00
Success [ratio] 100.00%
Status Codes [code:count] 200:5000
Error Set:
全リクエスト正常終了。
MySQL [fs14db01]> select count(*) from user;
+----------+
| count(*) |
+----------+
| 5000 |
+----------+
1 row in set (0.04 sec)
全 5000 件すべて入ってる。
App Engineのログも確認したが、エラーなし。
実施時のCloud SQLの状態
CPU使用率
最大 46%
メモリ使用量
最大 857MB
クエリ実行数(?)
最大 1050件/秒
同時接続数
最大 632コネクション(?)
実施時のApp Engineの状態
インスタンス数
最大インスタンス数は、8
実際のインスタンス数
再度、秒間 1000 リクエスト実行中の際のインスタンス数をコンソールにて確認。
最大で 17 インスタンスが作成されている。
考察
コメントもらった通り、Cloud SQL上では最大 632コネクション貼られているものの、それは、App Engineインスタンス数が増えていたため、全インスタンスからのアクセストータルでそれだけのコネクション数になっただけである可能性が・・・。
実際、単純に 632 コネクションを App Engineのインスタンス数 8 で割ると、1App Engineインスタンスあたりは 80 コネクション程度になり、以下を確認するには至っていないことになる。
それぞれのApp EngineインスタンスからCloud SQLインスタンスに接続できる数は「100
」までという制限がある。
次は、アドバイスにあるように SQL文を工夫してコネクションを保持した形で試してみよう。