/var/www/yatta47.log

/var/www/yatta47.log

やったのログ置場です。スクラップみたいな短編が多いかと。

ポーリングって本当にコストが高いの?を考えてみた

最近、システム設計について調べてたときに、ふと疑問に思うことがありました。

「ポーリングはコストがかかるからWebhookを使うべき」みたいな話、よく聞きますよね。でも、これって本当にすべてのケースで当てはまるんか?と思ったんです。

なんとなく「ポーリング=非効率」って思うところはありますが、実際にバックエンド間の連携を設計しているときに「あれ、これって別にポーリングでもいいのでは?」って思うケースが結構ありまして。

そこで、ちゃんと整理して考えてみることにしました。

 

ポーリングが「コスト高い」って言われる理由を調べてみた

まず、なんでポーリングがダメって言われるのか、改めて考えてみました。

整理してみたところ、確かに正当な理由があるかなと思います。

モバイルアプリやフロントエンドの場合

これはもう、間違いなく「NG」ですね。

  • バッテリー消費がやばい:定期的に通信するって、スマホのバッテリーをがんがん食うんですよね
  • データ通信量も心配:ユーザーのギガを勝手に消費しちゃうのは申し訳ない

モバイルの世界でプッシュ通知が重宝されるのって、こういう理由からくるんだろうなと思っています。

超高頻度・低レイテンシーが必要な場合

これも納得です。

  • 1秒間に何百回もポーリングするようなシステムだと、さすがにネットワーク帯域やサーバーのCPUが無駄になる
  • 状態がほとんど変化しないのに、変化チェックのためだけに大量リクエストを送り続けるのは、確かに非効率。

 

バックエンド間の場合だったら?

ここからが本題なんですけど、バックエンド間の通信って、上記の問題がほとんど当てはまらないんですよね。

実際に自分がサービス間連携を設計したときの体験から言うと:

ネットワークコストが圧倒的に低い

  • データセンター内のネットワークって、広帯域かつ低遅延なんですよね
  • バックエンドサービスが10秒に1回HTTPリクエストを送る程度のネットワーク負荷なんて、ほとんど無視できるレベル

正直、これまでの開発経験で、この程度の通信量がボトルネックになったことって記憶にあったかなぁというレベル。RedisやRDSなどのデータをためているところだとあったんですが、バックエンドサービス間だとあったかなぁ・・・という印相。こと、AWSなどクラウド使っている場合は内部通信も無料だったりするケースあるので、無視はしないけれどもそこまで気にしなかったケースが多いです。

リソースが潤沢

  • サーバーはバッテリーを気にしない(当たり前ですけど)
  • CPUやメモリもクライアントデバイスとは比較にならない

もちろん呼び出し側、呼ばれ先側の負荷状況などは見て、これによって負荷がかかっていると判断すればNGにするんですが、クライアントデバイスと比べるとやはり選択肢は多いですね。

アーキテクチャのシンプルさの価値が高い

これが一番重要かもしれません!!

ポーリングするクライアント側って:

  • 外部にAPIを公開する必要なし
  • 非同期コールバックを処理する複雑なロジックも不要
  • while (true) { poll(); sleep(10); } みたいなループで済む

一方、ポーリングせずにWebhookにて情報を非同期に受け取るためには:

  • エンドポイントをセキュリティ的に安全に公開する必要がある
  • 管理し続ける運用コストもかかる
  • 障害時の再送処理とか、結構面倒

これを天秤にかけると、シンプルなポーリングの方が圧倒的に楽で安くて堅牢なケースって、実は多いんじゃないかな?

実際に体験してみた感想

最近、マイクロサービス間でのデータ同期処理を実装検討していて、最初は「Webhookが正解やろ」って思ってWebhook方式で設計を考えていました。

でも実装してみると:

  • セキュリティ設定が結構大変
  • 障害時の再送ロジックが複雑
  • テストも面倒(Webhook受信のモックとか)

一方、ポーリング方式に変更したら:

  • 実装がシンプルすぎて拍子抜け
  • テストも書きやすい
  • 障害時は単純にリトライすればOK

と複雑性とかかる開発コストの違いを感じています。

データの整合性が数秒〜数分遅れても問題ないシステムだったら、ポーリング間隔は30秒に設定。これで十分実用的なこともあるかと思います。

 

まとめ

状況判断が大事だと思います。

結論として、「ポーリングはコストがかかる」っていうのは、思考停止で使うべき言葉じゃないなーって思います。

ポーリングがNGなケース:

  • モバイルアプリが相手
  • 超高頻度・低レイテンシーが必須
  • ユーザーの通信コストを気にする必要がある

ポーリングが合理的なケース:

  • バックエンド間の連携
  • リアルタイム性が必須でない
  • アーキテクチャのシンプルさを重視したい

個人的には、バックエンド間の連携で「数秒〜数分の遅延が許容できる」なら、ポーリングの方が開発・運用コストを考えると合理的なことが多いんじゃないかなって思ってます。

机上の理論だけじゃなくて、実際の運用コストや開発効率も含めて判断することが大事ですね!

「なんとなくポーリングは悪」って思い込んでるケース、ありませんか? 一度立ち止まって考えてみると、案外ポーリングの方がシンプルで良い場合もあるかもしれませんよー。

それではー!