「mysql-shun_on_failuresの罠」ってタイトルですが罠でも何でもない話です。
preforkなwebアプリケーション -> ProxySQL -> MySQL
みたいな構成のシステムがあってProxySQL <-> MySQLでネットワーク不調かなんかでconnectionが一時的に貼れなくなった時にmysql-shun_on_failures
の値が小さいと困るかもしれない話です
mysql-shun_on_failures
はドキュメントを読むと1秒以内に同一のサーバーに対して許容される接続エラーの数と書いてあります。webアプリケーションがネットワーク不調時に複数コネクションを要求すると全ての接続はエラーとなります。その時にmysql-shun_on_failures
が小さいと一瞬で上回ってしまいmysql-shun_recovery_time_sec
の間新規接続は行われなくなります。
これで何が困るかというとmysql-shun_recovery_time_sec
がデフォルトだと10秒となりwebアプリケーションは全て10秒近く待たされます。仮に1秒でネットワーク復旧したとするとmysql-shun_recovery_time_sec
の設定が余計な値となって復旧してもconnectionが貼られないという現象が起きてしまいます。
じゃあどうすれば良さそうか
mysql-shun_recovery_time_sec
を下げるかmysql-shun_on_failures
の値を大きくすることで発生確率を減らすみたいな対応が良いのかなと思いました。(公式にも無効にしたいなら大きな数字にしてねと書いてある)
何も知らないと意外とハマりそうな話だったので書いてみました
何でこうなってるの?
MySQLなどのミドルウェアのmax_connections到達時にmysql-shun_recovery_time_sec
とmysql-shun_on_failures
が正しく設定されていれば余計なconnect(2)が実行されず余計な負荷をかけないような仕組みになってるのかなと思いました。この時ProxySQLがコネクションプールを持っていればそちらをアプリに割り当てるのでプール以上の接続が失敗するがプールされたコネクションを獲得したクライアントは正常に処理が行えるという縮退運転的な仕組みとなってるみたいです。