GH GambleHub

接続プールとレイテンシ

接続プールとレイテンシ

1)なぜプールが必要なのか

接続は高価です(TCP/TLSハンドシェイク、認証、ウォームアップ)。プールは以下を可能にします:
  • 既製の接続を再利用(keep-alive)→TTFB以下。
  • 同時性を制御し、リトリートの雪崩の代わりにバックプレッシャーを与えます。
  • 正しいサイズとタイムアウトによるp95/p99テールの削減。

主なリスク:プール内の待ち行列、ヘッド・オブ・ライン・ブロッキング、接続のためのコンテンツ、退却の嵐。

2)数学の基盤: プールのサイズを数える方法

Little's law: 'L=λ × W'を用いる。プールの場合、これは次のことを意味します:
  • 'λ'は平均リクエストストリーム(RPS)です。
  • 'W'はリクエストごとの平均接続ビジー(ネットワーク遅延やリモートサービス運用を含むサービス時間)です。
  • 最小プールサイズは'N_min ≈ λ × W'です。
  • バリエーションのマージンを追加し、p99:ヘッドルーム20-50%。
  • 例:300 RPS、平均ホールドタイム40 ms→'N_min=300 × 0。04 = 12`.50%のマージンで、18の接続が→です。

尾が大きい場合:クリティカルパスの場合は'W_p95'または'W_p99'を考慮してください-プールが成長します。

3)一般的な設計原則

1.短いデータパス:再利用(keep-alive、 HTTP/2/3 multiplexing)。
2.並列性の制限:バックエンドを揚げるよりも、すばやく(429/503)拒否することをお勧めします。
3.タイムアウト>リトリート:小さなタイムアウトとまれなジッタのリトリートを設定します。
4.クライアントキューはサーバキューより短い(高速フェイルファスト)。
5.Backpressure:プールがいっぱいのとき-すぐにNACK/error/collbeck 「later」。
6.ターゲットによるプールの分離:DB、キャッシュ、外部PSP-その限界。

4) HTTP/1。1対HTTP/2/3、 keep-alive

。 。1:一度に1つの接続要求(実質的に);ホストごとに複数の接続を持つプールが必要です。
HTTP/2: 1つのTCPでのストリーム多重化;接続が少なくなりますが、パケットが失われるとTCPでのHOLブロックが可能になります。
HTTP/3 (QUIC): UDPに対するストリーミングの独立性-HOLの問題が少なく、最初のバイト数が速くなります。

助けてくれる設定:
  • keep-aliveタイムアウト30-90(プロフィール別)、接続要求の制限(優雅なリサイクル)。
  • 作業者の開始時に予熱(事前接続)する。
  • 1 HTTP/2あたりの最大フローを制限します(例:100-200).
NGINX(アップストリームキープアライブ):
nginx upstream backend {
server app-1:8080;
server app-2:8080;
keepalive 512;
keepalive_requests 1000;
keepalive_timeout 60s;
}
proxy_http_version 1. 1;
proxy_set_header Connection "";
使節(HTTP/2プール):
yaml http2_protocol_options:
max_concurrent_streams: 200 common_http_protocol_options:
idle_timeout: 60s max_connection_duration: 3600s

5) DBプール: PgBouncer、 HikariCPの運転者

目標は、競争力のある取引を制限し、短い接続を保持することです。

5.1 PgBouncer (PostgreSQL)

モード:'session'/'transaction'/'statement'。APIの場合-より頻繁にトランザクション。
重要なパラメータは'pool_size'、 'min_pool_size'、 'reserve_pool_size'、 'server_idle_timeout'、 'query_wait_timeout'です。

ini
[databases]
appdb = host=pg-primary port=5432 dbname=appdb

[pgbouncer]
pool_mode = transaction max_client_conn = 5000 default_pool_size = 100 min_pool_size = 20 reserve_pool_size = 20 query_wait_timeout = 500ms server_idle_timeout = 60 server_reset_query = DISCARD ALL

5.2 HikariCP (Java)

小さくて速い接続、ハードタイムアウト。

properties dataSourceClassName=org. postgresql. ds. PGSimpleDataSource maximumPoolSize=30 minimumIdle=5 connectionTimeout=250 validationTimeout=200 idleTimeout=30000 maxLifetime=1800000 leakDetectionThreshold=5000
ルール:
  • 'maximumPoolSize ≈ RPS × W × headroom'。
  • 'connectionTimeout'は秒単位ではなくミリ秒単位です。
  • リーク検出を有効にします。

5.3 Go/Node/Python-例

HTTPに移動します。クライアント(再利用+タイムアウト):
go tr:= &http. Transport{
MaxIdleConns:    512,
MaxIdleConnsPerHost: 128,
IdleConnTimeout:   60 time. Second,
TLSHandshakeTimeout: 2 time. Second,
}
c:= &http. Client{
Transport: tr,
Timeout:  2 time. Second ,//general
}
ノード。js keep-aliveエージェント:
js const http = require('http');
const agent = new http. Agent({ keepAlive: true, maxSockets: 200, maxFreeSockets: 64, timeout: 60000 });
psycopg/SQLAlchemy (Python):
python engine = create_engine(
url, pool_size=30, max_overflow=10, pool_recycle=1800, pool_pre_ping=True, pool_timeout=0. 25
)

6)待ち行列とテールレイテンシー

尾は次のときに発生します:
  • プールは'λ × W'より小さい→接続キューが成長している。
  • バッファとリミットなしでムラ(バースト)をロードします。
  • 長いリクエストは接続を取り、HOLを作成します。
対策:
  • リクエストタイプ(高速/遅い)でプールを分離します。
  • クライアント側のタイムアウトを実装します。期限切れの場合-高速NACK。
  • ルート(Envoy、 HAProxy)の外れの検出および回路破壊。
  • 「重い」ルートのクォータ、レポート/エクスポート用の個別のプール。
Envoyの遮断器(例):
yaml circuit_breakers:
thresholds:
- priority: DEFAULT max_connections: 200 max_pending_requests: 100 max_requests: 1000 max_retries: 2

7)タイムアウトとリトリート(正しい順序)

1.タイムアウトを接続(DC内部で50〜250ミリ秒)

2.TLSハンドシェイクタイムアウト(500-1000ミリ秒DC)。
3.要求/読み取りタイムアウト(ルートSLOに近い)。
4.再試行:最大1時間、idempotentメソッドのみ;ジッタ+バックオフ。
5.リトレイ予算:RPSの割合としてのグローバル制限(例:≤ 10%)。

8)キープアライブ、ナーグル、プロトコル

小さなメッセージRPCのNagle (TCP_NODELAY)を無効にします。
可能な限りHTTP keep-aliveを有効にします。
TIME_WAITを見る-結果を理解している場合にのみ'再利用'/'リサイクル'を調整します。より良い-カーネルチューニングではなく、接続を再利用します。
TLS-セッション再開とALPNを使用します。

9) OS/カーネルチューニング(注意)

'ネット。コアです。somaxconn'、'ネット。ipv4。ip_local_port_range'、ネット。ipv4。 。 。
記述子:'nofile' ≥プロキシプロセスあたり64kです。
IRQバランス、GRO/LRO-トラフィックプロファイル。
優先順位-プロファイル;メトリックなしでチューニングすることはしばしば有害です。

10) Observability: 何を測定するか

プール使用率:ビジー/トータル、p50/p95接続保留中。
機内リクエストとそのホールドタイム(ルートスライス)。
リトレイエラー予算:リピートの割合。
接続チャーン毎秒作成/閉じる。
TCP/TLS: SYN RTT、握手、セッションの再利用。
Rock:アクティブな接続、待機、長いトランザクション、ロック。

Графики: 「RPS vs pool wait」、 「hold-time distribution」、 「reuse ratio」、 「circuit trips」。

11)ケースレシピ

11.1 APIゲートウェイ→バックエンド

'max_concurrent_streams=200'にHTTP/2します。
ゲートウェイノードあたりのサービスあたりの接続数は20〜40です。
タイムアウト:100ms、試行あたり300-500ms、共有1-2s、ジッタで1再試行。

11.2 PostgreSQL→PgBouncerによるサービス

'pool_mode=transaction'、 'default_pool_size' (RPS × W × 1。3).

'connectionTimeout ≤ 250ms'では、短いトランザクション(<100ms)。
重いレポート要求-個別のプール/レプリカ。

11.3 gRPC内部

スレッド制限が100〜200のターゲットホストごとに1チャネル(HTTP/2)。
SLOルートのRPCの締め切りは、idempotentのみを再試行します。
長いRPCトレースのサンプリングとホールドタイムのメトリック。

12)実装チェックリスト(0-30日)

0-7日

キールート/クライアントの「W」(ホールドタイム)を測定します。
'N_min=λ × W'を計算し、30〜50%のヘッドルームを追加します。
keep-aliveと短い接続タイムアウトを有効にします。

8-20日

個別のプール(高速/遅い/外部)。
タイプサーキットブレーカとリトレイ予算。
ダッシュボードを追加:プール待機P95、再利用比率、機内。

21-30日

負荷はバースト、カオステスト「バックエンドの落下」で実行されます。
尾の最適化:重いルートの分離、ローカルキャッシュ。
runbook 'axの文書式と制限。

13)アンチパターン

プールサイズはランダムで、ヘッドルームはありません。
高速障害の代わりに、大規模な接続待ちタイムアウト→ロングテール。
多くの人はジッタとidempotency→嵐なしで後退します。
すべてのリクエストタイプに1つの共有プール。
長いトランザクションは、接続(DB)→残りの飢餓を維持します。
無効なキープアライブまたは小さすぎるアイドル→チャーン制限とTTFBの成長。

14)成熟度の指標

プールはprodでp95を待ちます<合計p95ルートの10%。
再利用率(内部HTTPでは>90%;>外的な)のための80%。
DB txn時間p95 <100-200ミリ秒;長いトランザクションの割合<1%。
再試行レート<5%(および≤予算)、タイムアウトによるエラーは安定して予測可能です。
すべての重要な顧客のための文書化されたプール決済。

15)結論

効果的な接続プールはキューエンジニアリング+タイムアウト規律です。'W'を測定し、プール'λ × W'をマージンで計算し、keep-alive/HTTP2+をオンにし、スローパスを分離し、短いタイムアウトを保ち、ジッタで最小限のレトラを行います。「プール待ちvsレイテンシー」の観測性とサーキットブレーカを追加すると、バックエンドを過熱することなく、低いTTFB、制御されたp99テール、サージ抵抗を得ることができます。

Contact

お問い合わせ

ご質問やサポートが必要な場合はお気軽にご連絡ください。いつでもお手伝いします!

Telegram
@Gamble_GC
統合を開始

Email は 必須。Telegram または WhatsApp は 任意

お名前 任意
Email 任意
件名 任意
メッセージ 任意
Telegram 任意
@
Telegram を入力いただいた場合、Email に加えてそちらにもご連絡します。
WhatsApp 任意
形式:+国番号と電話番号(例:+81XXXXXXXXX)。

ボタンを押すことで、データ処理に同意したものとみなされます。