LoginSignup
12
5

More than 3 years have passed since last update.

【実験】App Engine(Golang)からCloud SQLに接続する際の同時接続数制約

Last updated at Posted at 2019-05-20

追記@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"
)
[CloudSQL接続]
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)
    // --------------------------------------------------------------

↑のコメントアウトした部分が今回の実験の肝。
詳細は後述。

[WebAPIサーバの設定と起動]
    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"))))
}
[userレコード構造体]
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

[app.yaml]
runtime: go111

includes:
  -  secret.yaml

secret.yaml

[secret.yaml]
env_variables:
  CONN: 【自分のGCPプロジェクトID】:asia-northeast1:sample-001
  PASS: 【Cloud SQLの対象DBのパスワード】

実験の肝

先述の通り、ソース中、コメントアウトした部分(DB接続時のコネクションの扱い方)が肝。

最大アイドルコネクション数の設定

アイドル状態にしておくコネクション数。現時点でデフォルトは「2」。
0以下」ならアイドリング状態にしない。
後述の「最大オープンコネクション数(が0でなく)」を超えた設定をしても最大オープンコネクション数と合わせられる想定。

[go/src/database/sql/sql.go]
// 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の場合は限度なくオープンしにいく。

[go/src/database/sql/sql.go]
// 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の設定再確認

Screenshot from 2019-05-23 09-17-39.png

実施

$ 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%

Screenshot from 2019-05-23 09-14-27.png

メモリ使用量

最大 857MB

Screenshot from 2019-05-23 09-16-31.png

クエリ実行数(?)

最大 1050件/秒

Screenshot from 2019-05-23 09-15-48.png

同時接続数

最大 632コネクション(?)

Screenshot from 2019-05-23 09-15-12.png

実施時のApp Engineの状態

インスタンス数

最大インスタンス数は、8

Screenshot from 2019-05-23 23-51-46.png

実際のインスタンス数

再度、秒間 1000 リクエスト実行中の際のインスタンス数をコンソールにて確認。
最大で 17 インスタンスが作成されている。

Screenshot from 2019-05-23 23-57-45.png

考察

コメントもらった通り、Cloud SQL上では最大 632コネクション貼られているものの、それは、App Engineインスタンス数が増えていたため、全インスタンスからのアクセストータルでそれだけのコネクション数になっただけである可能性が・・・。
実際、単純に 632 コネクションを App Engineのインスタンス数 8 で割ると、1App Engineインスタンスあたりは 80 コネクション程度になり、以下を確認するには至っていないことになる。

それぞれのApp EngineインスタンスからCloud SQLインスタンスに接続できる数は「100」までという制限がある。

次は、アドバイスにあるように SQL文を工夫してコネクションを保持した形で試してみよう。

12
5
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
5