元々は私のブログに投稿されました
デフォルトでは、Kubebuilder とコントローラー ランタイムを使用して構築されたオペレーターは、一度に 1 つのリコンサイル リクエストを処理します。オペレータ開発者がアプリケーションのロジックを推論してデバッグするのが容易になるため、これは賢明な設定です。また、コントローラーから ectd や API サーバーなどのコア Kubernetes リソースへのスループットも制限されます。
しかし、ワークキューがバックアップを開始し、リクエストがキュー内に残されて処理を待っているために平均調整時間が増加した場合はどうなるでしょうか?幸いなことに、コントローラー ランタイムのコントローラー構造体には MaxConcurrentReconciles フィールドが含まれています (以前 Kubebuilder のヒント記事で述べたように)。このオプションを使用すると、単一のコントローラーで実行する同時調整ループの数を設定できます。したがって、1 より大きい値を指定すると、複数の Kubernetes リソースを同時に調整できます。
オペレーターとしての取り組みの初期に、私が抱いた疑問の 1 つは、同じリソースが 2 つ以上のゴルーチンによって同時に調整されていないことをどのように保証できるかということでした。 MaxConcurrentReconciles を 1 より大きく設定すると、調整ループ内のオブジェクトの状態が外部ソース (別のスレッドで実行されている調整ループ) からの副作用によって変化する可能性があるため、あらゆる種類の競合状態や望ましくない動作が発生する可能性があります。 .
私はこれについてしばらく考え、ゴルーチンが特定のリソース (名前空間/名前に基づいて) のロックを取得できるようにする sync.Map ベースのアプローチを実装しました。
コントローラーのワークキューにすでにこの機能が含まれていることを最近 (k8s Slack チャネルで) 知ったので、この努力はすべて無駄だったことがわかりました。ただし、実装はより単純です。
これは、k8s コントローラーのワークキューが固有のリソースが順番に調整されることをどのように保証するかについての簡単な説明です。したがって、MaxConcurrentReconciles が 1 より大きく設定されている場合でも、特定のリソースに対して一度に動作する調整関数は 1 つだけであると確信できます。
client-go/util
コントローラー ランタイムは、client-go/util/workqueue ライブラリを使用して、基礎となる調整キューを実装します。パッケージの doc.go ファイルのコメントには、ワークキューが次のプロパティをサポートしていることが記載されています:
- 公平: アイテムは追加された順序で処理されます。
- ケチ: 1 つの項目は同時に複数回処理されません。処理される前に項目が複数回追加された場合、処理されるのは 1 回だけです。
- 複数の消費者と生産者。特に、アイテムの処理中にアイテムを再度キューに入れることができます。
- 通知をシャットダウンします。
ちょっと待ってください...私の答えはここの 2 番目の項目、「けちな」プロパティにあります。これらのドキュメントによると、キューはコードを 1 行も記述することなく、この同時実行性の問題を自動的に処理します。実装を見てみましょう。
ワークキューはどのように機能しますか?
ワークキュー構造体には、Add、Get、Done の 3 つの主要なメソッドがあります。コントローラー内では、情報提供者が調整リクエスト (汎用 k8s リソースの名前空間名) をワークキューに追加します。別のゴルーチンで実行されている調整ループは、キューから次のリクエストを取得します (キューが空の場合はブロックされます)。このループは、コントローラーに書き込まれたカスタム ロジックをすべて実行し、コントローラーはキュー上で Done を呼び出し、リコンサイル リクエストを引数として渡します。これにより、プロセスが再度開始され、調整ループは Get を呼び出して次の作業項目を取得します。
これは、RabbitMQ でのメッセージの処理に似ています。ワーカーがキューから項目を取り出して処理し、処理が完了し、項目をキューから削除しても安全であることを示す「Ack」をメッセージ ブローカーに送り返します。キュー。
それでも、QuestDB Cloud のインフラストラクチャを強化するオペレーターを運用環境で実行しており、ワークキューが宣伝どおりに動作することを確認したいと考えていました。そこで、動作を検証するための簡単なテストを作成しました。
ちょっとしたテスト
これは、「Stingy」プロパティを検証する簡単なテストです:
package main_test import ( "testing" "github.com/stretchr/testify/assert" "k8s.io/client-go/util/workqueue" ) func TestWorkqueueStingyProperty(t *testing.T) { type Request int // Create a new workqueue and add a request wq := workqueue.New() wq.Add(Request(1)) assert.Equal(t, wq.Len(), 1) // Subsequent adds of an identical object // should still result in a single queued one wq.Add(Request(1)) wq.Add(Request(1)) assert.Equal(t, wq.Len(), 1) // Getting the object should remove it from the queue // At this point, the controller is processing the request obj, _ := wq.Get() req := obj.(Request) assert.Equal(t, wq.Len(), 0) // But re-adding an identical request before it is marked as "Done" // should be a no-op, since we don't want to process it simultaneously // with the first one wq.Add(Request(1)) assert.Equal(t, wq.Len(), 0) // Once the original request is marked as Done, the second // instance of the object will be now available for processing wq.Done(req) assert.Equal(t, wq.Len(), 1) // And since it is available for processing, it will be // returned by a Get call wq.Get() assert.Equal(t, wq.Len(), 0) }
ワークキューは内部でミューテックスを使用するため、この動作はスレッドセーフです。そのため、キューを壊すために複数の goroutine を使用してキューから高速で読み書きするテストをさらに作成したとしても、ワークキューの実際の動作はシングルスレッド テストの動作と同じになります。
すべてが失われたわけではない
Kubernetes の標準ライブラリには、このような小さな宝石がたくさん隠されており、その一部はあまり目立たない場所 (go クライアント パッケージにあるコントローラー ランタイム ワークキューなど) にあります。この発見や、私が過去に同様の発見をしたにもかかわらず、これらの問題を解決しようとするこれまでの試みは完全な時間の無駄ではないと今でも感じています。これらは、分散システム コンピューティングの基本的な問題について批判的に考えることを強制し、内部で何が起こっているのかをより深く理解するのに役立ちます。そのため、「Kubernetes が成功した」ことがわかるまでに、コードベースを簡素化し、おそらく不必要な単体テストをいくつか削除できると安心しています。
以上がKubernetes オペレーターは同時実行性をどのように処理しますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

goisidealforbuildingscalablessystemsduetoitssimplicity、効率性、およびビルド・インコンカレンシsupport.1)

intionSingOrunautomaticallyは()andareuseforstingupenments andinitializingvariables.usemforsimpletasks、回避効果を回避し、測定可能性を測定することを検討します。

goinitializeSpackages intheordertheyareimport extionsitions withinitionsiteintheirdefinition ordord、およびfilenamesdetermineTheOordCrossMultiplefiles.thisprocesccanbeandeanded by -dependenciessedieSiesは、このマイレアドカンフレシニティン化の対象となります

custominterfacesingoarecrucialforwritingfficable、maintable、andtatablecode.theyeNabledeveloveerStofofofovioroverimplementation、拡張、methodsodsignaturesthattypespessmustimment、interfaceforoderueusavelya

シミュレーションとテストにインターフェイスを使用する理由は、インターフェイスにより、実装を指定せずに契約の定義を可能にし、テストをより孤立し、メンテナンスしやすくするためです。 1)インターフェイスの暗黙的な実装により、モックオブジェクトを簡単に作成できます。これにより、テストの実際の実装を置き換えることができます。 2)インターフェイスを使用すると、ユニットテストでのサービスの実際の実装を簡単に置き換えることができ、テストの複雑さと時間を短縮できます。 3)インターフェイスによって提供される柔軟性により、さまざまなテストケースのシミュレートされた動作の変更が可能になります。 4)インターフェイスは、テスト可能なコードを最初から設計し、コードのモジュール性と保守性を向上させるのに役立ちます。

Goでは、init関数はパッケージの初期化に使用されます。 1)init関数は、パッケージの初期化時に自動的に呼び出され、グローバル変数の初期化、接続の設定、構成ファイルの読み込みに適しています。 2)ファイルの順序で実行できる複数のinit関数がある場合があります。 3)それを使用する場合、実行順序、テストの難易度、パフォーマンスへの影響を考慮する必要があります。 4)副作用を減らし、依存関係の注入を使用し、初期化を遅延させることをお勧めします。

go'sselectStatementStreamLinesConcurrentProgrambyMultipLexIngoperations.1)Itallow swaitingonMultipleChanneloperations、実行、exectingThefirstreadyone.2)

コンテキストアンドウェイトグループは、フォーマネングに焦点を合わせており、contextAllowsingSignalingCancellationAndDeadlinesAcrossapiboundariesを採用し、GoroutinesscanSclacefly.2)WaitGroupssynchronizeGoroutines、Allcompletebebroproproproproproproprotinesを保証します


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

SublimeText3 Linux 新バージョン
SublimeText3 Linux 最新バージョン

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

AtomエディタMac版ダウンロード
最も人気のあるオープンソースエディター

EditPlus 中国語クラック版
サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ホットトピック









