LoginSignup
37
24

More than 5 years have passed since last update.

Goの同時関数呼び出しを1回で済ませられるライブラリ 「SingleFlight」 が便利

Last updated at Posted at 2017-09-09

Goの同時関数呼び出しを1回で済ませられるライブラリ 「SingleFlight」 が便利

tl;dr

  • 高頻度に叩かれがちな重めの取得系関数呼び出しはSingleFlight を使おう!

動機

  • Cacheが切れた途端Mysqlに大量のアクセスが流れ込み、LAが上がる現象をどう回避しようか考えていたときに、SingleFlight というライブラリを見つけたため使えるか計測してみた。

SingleFlightって何?

  • 複数人が同じ関数呼び出しを同時にした場合、最初の1人だけ関数を実行し、残りの人は、最初の人が実行した関数呼び出しが終了するまで待機し、最初の1人が関数呼び出しの結果を取得したら、待機してる残りの人に結果をシェアしてくれる。
  • Goからリソースへのアクセスが同時に行われても、1本だけでよくなるから嬉しい。効率的。
  • もちろんイミュータブルな関数じゃないと使えない。

計測環境

計測対象

  • 3本のMysqlQueryを叩き、合計が500ms位かかるGo API

計測ツール

計測コマンド

  • 秒間100リクエスト を1分間 (叩きすぎかな?)
echo "GET http://localhost:1323/hoge" | vegeta attack -duration=1m -rate=100 | vegeta report -reporter=plot > plot.html

計測パターン

  1. そのまま
  2. 10秒毎で切れるMemCache を挟む
  3. SingleFlight を挟む
  4. 10秒毎で切れるMemCache + SingleFlight を挟む

計測結果

  1. そのまま

    • ほぼ全部500。普通にやると耐えられない。 vegeta-plot.png
  2. 10秒毎で切れるMemCache を挟む

    • キャッシュが切れた途端、Mysqlが落ちてしまい、それ以降は全て500に。 vegeta-plot-cache10s.png
  3. SingleFlight を挟む

    • リクエスト毎にレイテンシに差が出てしまうが、正しく200で返せる vegeta-plot-singleflight.png
  4. 10秒毎で切れるMemCache + SingleFlight を挟む

    • キャッシュが切れてセットされるまでの間も、正しく200で返せる vegeta-plot-cache10s-singleflight.png

結論

  • 重めのMysqlを叩く + 高頻度リクエスト => SingleFlightは必須。
37
24
0

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
37
24