【要約】nginx の smooth weighted round-robin を SNS 投稿ローテに転用したら連投が消えた [Zenn_Python] | Summary by TechDistill
> Source: Zenn_Python
Execute Primary Source
// Problem
個人開発者がSNS投稿botを運用する際、複数のアプリを重み付きで紹介しようとしたところ、特定のアプリが連続して投稿される問題に直面した。
- ・単純な重み付き実装では、重い要素が特定の期間に固まって出現する。
- ・SNS運用において、同一トピックの連投はアカウント停止のリスクを伴う。
- ・random.shuffleでは、運悪く連投が発生する可能性があり、冪等性も担保できない。
// Approach
投稿の偏りを防ぐため、nginxがロードバランサに採用しているsmooth weighted round-robinアルゴリズムをPythonで実装した。
- ・各要素のcurrent_weightに重みを加算し、最大値を持つ要素を選択する。
- ・選択された要素のcurrent_weightから、全要素の重みの合計を減算する。
- ・この処理を決定的な純関数として実装し、GitHub Actionsの多重発火時にも同じ結果を返すよう設計した。
- ・原稿の管理には「登板回数」を用いることで、重みに応じた適切な原稿消費を実現した。
// Result
アルゴリズムの導入により、重みの比率を維持したまま、要素の連続出現(最長連続1)を完全に排除できた。
- ・SNS投稿において、特定のアプリが連続して紹介されるリスクを解消した。
- ・決定的なアルゴリズムにより、cronの多重発火時でも重複判定が容易になった。
- ・実装は10行程度と軽量であり、移植の正当性もnginxの仕様に基づき検証済みである。
Senior Engineer Insight
> ロードバランサ向けのアルゴリズムを、SNS投稿という異なるドメインに適用した点が極めて実践的である。単なる「分散」だけでなく、GitHub Actionsの不安定な実行環境を考慮し、決定的な純関数として実装することで「冪等性」を確保している点は、運用負荷を下げさせる優れた判断だ。実装が極めて軽量であるため、A/Bテストの割り当てやプレイリスト制御など、低レイテンシと決定性が求められる箇所への転用も容易だろう。