見出し画像

持続的な接続利用によるRedisスロットリング抑制の改善

弊社では現在キャッシュシステムにElastiCache Redis OSSを利用しています。キャッシュノードには様々な種類があり、t4gやc7gnといったファミリーがありますが、例えばt4gについてはファミリー内でcpuコア数やバースト帯域幅は同一です。small, mediumといったタイプによってはメモリ量とベースライン帯域幅が増減します。
Redisはメモリにデータを保存するので、メモリ量の違いはどれほどのストレージを必要とするかをほぼそのまま意味し、タイプ選択時は基本的にそれに基づきますが、ベースライン帯域幅も異なるためこの点も考慮する必要があります。

安定して稼働していますが、サービスの成長に伴ってベース帯域幅の増加が徐々に起こり、スペック値を超える状態が近頃発生するようになりました。これによる影響を実際に検知したのが、newrelicでのトランザクション監視時であり、Redisとの、
・コネクション確立
・データ取得
リクエストが、トランザクション通して数百msほどに大きく遅延するケースが低頻度で観測されるようになりました。

これの対策として、
・タイプアップグレード
・通信時データ量削減の追求
・その他ネットワークオーバーヘッド最小化
など検討されますが、先行してまず3つ目を実施しました。以下に詳細を述べます。その他についても順次、2つ目はリリース予定が立っており、1つ目も検討中のため、それらについても改めて記事にする予定です。

コネクションの再利用
いわゆる通信プールをアプリケーションサイドに導入し、アプリケーションリクエストごとに行われていたコネクション確立に伴うネットワーク負荷を低減しました。

具体的には、phpクライアントの実装としてfsockopenを用いてリクエスト開始時に接続を確立し、スクリプト終了と共に接続クローズする作りだったのを、pfsockopenを用いて接続をプロセスレベルで永続化させ、スクリプト終了時に接続は開いたままとする作りに変更しました。
永続化させることで、コネクションプールの管理が逆にオーバーヘッドになる場合もあるので、一概に優位性がある訳ではありませんが、上記状況の改善のため、アプリケーションサーバーのリソース使用状況を考慮しつつ十分に堅牢な実装のもとリリースしました。

その結果、状況の改善効果は明確に見られ、予想された、
・接続数の増加
・新規接続数がほぼゼロに
の変化も、以下メトリクスグラフのように見られました。

現在の接続数
新しい接続数

今回はキャッシュシステムの改善を紹介させて頂きました。引き続きサービスをより快適に安心して使って頂けるよう努めていきます。