インフラ・DevOps
GitHub Freno: 協調的で高可用なスロットラーサービス
GitHub Freno: cooperative, highly available throttler service (github.com)
要約
GitHub Frenoは、リソースへの書き込みを協調的にスロットルするためのサービスです。特にMySQLクラスターのレプリケーションラグを監視し、閾値を超えた場合に書き込みを抑制します。Raftコンセンサスプロトコルにより高可用性を実現し、HTTPインターフェースを通じてアプリケーションからの書き込み許可要求に応答します。大規模なバルクオペレーションやスキーマ移行などの際に、データベースへの負荷を軽減するために利用されます。
全文翻訳
freno 協調的で高可用なスロットラーサービス: クライアントはリソースへの書き込みをスロットルするためにfrenoを使用します。現在の実装では、MySQLクラスターのレプリケーションステータスに基づいて、(複数の) MySQLクラスターへの書き込みをスロットルできます。レプリケーションラグが事前に定義された閾値を超えると、frenoは協調的なクライアントをスロットルします。frenoはサーバーインベントリの変更に動的に適応し、さらにユーザーが特定のアプリケーションのスロットルを強制するように制御できます。frenoは高可用であり、リーダーシップの決定やメンバーノード間のユーザーイベントの受け渡しにraftコンセンサスプロトコルを使用します。
協調的なfrenoは、バックエンドストア(現時点ではMySQLのみ)からデータを収集し、「バックエンドストアに書き込んでも良いか?」という質問に答えるロジックを持っています。クライアント(アプリケーション、スクリプト、ジョブ)はfrenoに問い合わせることが期待されます。frenoはクライアントとバックエンドストアの間のプロキシではありません。単にストアを監視し、「書き込んでも大丈夫」または「書き込みを停止すべき」と伝えます。クライアントはfrenoに問い合わせ、その推奨事項を尊重することが期待されます。
ストアとアプリ
frenoはデータストアごとにデータを収集します。例えば、MySQLクラスターをプローブする際に、クラスターごとにレプリケーションラグを独立して収集します。バックエンドストアのメトリクスは自動的に収集され、絶対的な真実を表します。frenoはアプリとして識別されるクライアントにサービスを提供します。frenoは協調的なので、アプリが自身を識別することを信頼します。アプリは管理可能であり、frenoは特定のアプリを強制的にスロットルするように指示できます。これは、他の高優先度アプリを完了まで実行できるようにするためです。frenoはスロットルするアプリに関する指示を受け付けるだけで、独自のスケジューリング/優先順位付けロジックを持っていません。
MySQL
frenoは、MySQLのスロットルに対して、単一で自己適応的なソリューションを提供するために元々設計されました。これは、レプリケーションラグを低く保ちながら書き込みを制御します。frenoは、MySQLクラスターの事前定義されたリストで設定されます。これには、認証情報、ラグ(またはその他の)検査クエリ、および期待される閾値が含まれる場合があります。各クラスターについて、frenoはどのサーバーをプローブしてデータを収集する必要があるかを知る必要があります。各クラスターについて、このリストを提供できます。
- 静的、ハードコードされたホスト名[:ポート]のリスト
- 動的。ホストは出入りする可能性があり、スロットルはこれらの変更に適応する可能性があります。サポートされている動的オプション:
haproxy経由: frenoにhaproxyのURLとバックエンド/プール名を提供すると、frenoは定期的にそのプール内の有効なサーバーのリストを解析し、それをプローブするように動的に適応します。frenoとMySQLスロットルについてさらに読む
ユースケース
frenoはバルクオペレーションに役立ちます。大量のロード/アーカイブタスク、スキーマ移行、一括更新などです。このような操作は通常、数千から数百万の行を処理し、MySQLレプリケーションラグなどの望ましくない影響を引き起こす可能性があります。これらのタスクを小さなサブタスク(例: 一度に100行)に分割し、各サブタスクを適用する前にfrenoに問い合わせることで、データベースやそれを使用するアプリケーションに悪影響を与えることなく同じ結果を達成できます。frenoは、レプリカの妥当性を推測するために実際のラグを決定するためにも使用できます。これは、マスターリードの書き込み後読み取りの痛みを軽減するのに役立ちます。ここを参照してください。
HTTP
frenoはHTTP経由でリクエストを処理します。「このアプリはこのストアに書き込んでも良いか?」というチェックリクエストが最も重要です。frenoはHEADリクエストを高く評価し(GETも受け付けますが、オーバーヘッドが大きいです)、ステータスコードで応答します。
- 200 (OK): アプリケーションはデータストアに書き込んでも良い
- 404 (Not Found): メトリック名が見つかりません。
- 417 (Expectation Failed): 要求しているアプリケーションは明示的に書き込みを禁止されています。
- 429 (Too Many Requests): 書き込まないでください。ストアの状態が期待される閾値を満たしていないことを示す通常の状態です。
- 500 (Internal Server Error): 内部エラー。書き込まないでください。
HTTPリクエストと応答についてさらに読む
クライアント
クライアントは一般的にHEAD経由で/check/...リクエストを発行します。クライアントは毎秒多くのリクエストを発行することが期待されます。frenoはリソースが軽量です。毎秒数百回frenoにヒットしても問題ないはずです。もちろん、ハードウェアとリソースによります。1秒あたり数百回frenoにヒットすることは、見ている粒度の範囲内で行うのが理にかなっています。クライアントが1000msのレプリケーションラグでスロットルする場合、毎秒200回frenoをチェックするのはやりすぎかもしれません。しかし、クライアントをナイーブでキャッシングなしにしたい場合は、これで問題ないはずです。クライアントについてさらに読む
Raft
frenoはraftを使用して高可用性を提供します。frenoノードはリーダーシップを競合し、リーダーのみがメトリクスを収集し、クライアントにサービスを提供する必要があります。raftと高可用性についてさらに読む
設定
サンプル設定ファイルを参照してください。また、以下も見つけてください。
- 一般/raft設定の詳細
- MySQL固有の設定の詳細
デプロイメント
推奨されるfrenoデプロイメントセットアップの提案については、デプロイメントドキュメントを参照してください。
リソース
環境でfrenoを設定するためのさまざまなリソースが見つかるかもしれません。freno-clientは、Ruby Gemとして利用可能な、オープンソースのfreno用Rubyクライアントです。
名前の由来
「Freno」はスペイン語で「ブレーキ」を意味します。車のブレーキのようなものです。基本的に、私たちは単に「throttler」または「throttled」と呼びたかったのですが、これらの名前は両方とも複数の他のリポジトリで使用されていたため、別の名前を探しました。辞書で「freno」という単語を調べたところ、次の文が見つかりました。「Echa el freno, magdaleno!」これは80年代を思い出させ、それが決定打となりました。
プロジェクトステータス
このプロジェクトは活発に開発中です。
貢献
このリポジトリは貢献を受け付けています。行動規範も参照してください。
ライセンス
このプロジェクトはMITライセンスの下でリリースされています。3rdパーティの依存関係は、それ自身のライセンスの下でリリースされており、それらはvendorの下に見つかることに注意してください。
著者
GitHub Engineeringによる執筆