原理メモリの最適化は古典的な問題です。 K8S が具体的に何をするのかを見る前に、まずプロセスを抽象化し、自分たちだったらどのように最適化するかを考えてみましょう。このプロセスは、サーバーからデータを取得するための外部同時要求として単純に抽象化できます。スループットに影響を与えずにサーバーのメモリ消費を削減するにはどうすればよいですか?一般的にはいくつかの方法があります:
このシナリオではデータ圧縮は適用できない可能性があります。確かに圧縮によってネットワーク伝送帯域幅が削減され、リクエスト応答速度が向上しますが、サーバー側メモリの最適化にはあまり効果がありません。 kube-apiserver はすでに gzip ベースのデータ圧縮をサポートしています。 Accept-Encoding を gzip に設定するだけです。詳細については公式サイト[1]を参照されたい。 もちろん、シリアル化された結果をキャッシュすることは、多数のクライアント要求があるシナリオ、特にサーバーが複数のクライアントに同時にデータを送信する必要がある場合に適しています。シリアル化された結果をキャッシュする利点は、シリアル化プロセスが 1 つだけ必要になるため、より明らかになります。シリアル化が一度完了していれば、後で他のクライアントにデータを送信するときに以前の結果を直接使用できるため、不要な CPU とメモリのオーバーヘッドが削減されます。もちろん、シリアル化された結果をキャッシュする操作自体も、ある程度のメモリを消費します。クライアントの数が少ない場合、この操作はあまり効果的ではなく、追加のメモリ消費を引き起こす可能性もあります。 kube-apiserver 監視リクエストはこのシナリオに完全に適合します。 次の記事では、kube-apiserver がこれら 2 つの点をどのように最適化するかを紹介します。 成し遂げる以下のタイムラインに記載されているさまざまな問題と最適化は、おそらく、数多くある問題と最適化のほんの一部にすぎません。 キャッシュシリアル化結果タイムライン
したがって、WebSocket 形式でウォッチを使用していない場合 (デフォルトでは Http Transfer-Encoding: chunked が使用される)、理論的には 1.17 にアップグレードすると問題なくなります。 原理写真 CacheableObject インターフェースを追加し、すべてのエンコーダーで CacheableObject をサポートしました。 cachingObject は CacheableObject インターフェースを実装します。そのオブジェクトは、対象のイベント オブジェクト (Pod など) です。 serializations はシリアル化された結果を保存するために使用されます。シリアル化の方法には json、yaml、protobuf の 3 つがあるため、識別子はシリアル化の種類を表す識別子です。 cachingObject の生成 上の図では、Cacher の dispatchEvent が独自の受信 chan データを消費し、関連するすべての cacheWatchers にイベントを送信するときに、イベント オブジェクトを cachingObject に変換し、cacheWatcher の入力 chan に送信します。最終的な Encode 操作は、最終オブジェクトが serveWatch メソッドでシリアル化されるときに呼び出されます。まず、シリアル化された結果がすでに存在するかどうかを判断します。そうなる場合は、シリアル化の繰り返しを避けるために直接再利用されます。 知らせ: 上の図では、len(watchers) >= 3 が過去のものになった場合は、cachingObject にラップします。新しいコード ロジックでは、次の判断が削除されました。ウォッチャーの数に関係なく、cachingObject は均一にカプセル化されます。 Init イベント (watchcache 内のすべてのデータ) は cachingObject にカプセル化されません。 Cacher 受信チャネルに送信されたデータのみが cachingObject に変換されます。つまり、Get/List リクエストはウォッチキャッシュから直接データを返すため、この最適化は完全に無効です。 Watch リクエストの場合、一部の Init Event データが引き続き watchcache から取得され返される可能性があるため、一部のデータは返されるときに既存のシリアル化結果を再利用しません。ここは魔法のような場所です。 cacheWatcher の入力チャネルのイベント オブジェクトのオブジェクトは、Pod などの通常のリソース オブジェクト、または CacheableObject オブジェクトである可能性があり、実際のリソース オブジェクトは CacheableObject のオブジェクトに格納されます。 Init イベントもカバーしないのはなぜですか? KEP 1152 では、まず Cache incoming chan のカバレッジを実装すると、大きなメリットが得られ、以前に見つかった問題が解決されると述べられています。さらに最適化が必要な場合は、Init イベントもカバーする可能性を再評価します。ストリーミングウォッチエンコーダをリファクタリングしてキャッシュを有効にする#120300[6]のコメントにも関連する議論があります。 写真 この最適化項目はKEP 3157ウォッチリスト[7]にも記載されています。 メモリ割り当ての最適化タイムライン
原理2 の場合、SpliceBuffer は、embeddedEncodeFn によるシリアル化された結果 []byte のディープ コピーを回避し、浅いコピーを通じてメモリ割り当てを効果的に最適化するように巧みに定義されています。 ベンチマーク結果は重要
3に関しては、厳密に言えば、このPRはメモリ割り当てを最適化するために使用されているのではなく、v1.29でリリースされた問題110146[10]で言及されている、jsonのシリアル化中にjson.compactによって引き起こされるCPU使用率の上昇の問題を解決するために使用されています。問題は、リソース オブジェクトのシリアル化の結果が前述のように cachingObject を通じてキャッシュされるものの、最終的にクライアントに送り返されるのは、まだシリアル化が必要な Event オブジェクトであるため発生します。 json.compact は各 Marshal の後に呼び出されます。これは、golang に付属する JSON シリアル化の実装です。 golang jsonソースコード[11]を参照することができます。この修正は、json.compact の影響を回避するために、リソース オブジェクトのシリアル化結果をキャッシュすることに基づいて、イベントのシリアル化結果をキャッシュするものです。 このPRには多くの変更が含まれます。その実装についてはまだいくつか疑問があります。私はコミュニティに相談するために問題122153[12]を提起しました。それがわかったら、この実装について説明する別の記事を用意する予定です。これには、ウォッチ ハンドラーのシリアル化ロジック全体が関係します。エンコーダーは深くネストされています。 Google の神でさえ、コードをレビューした際に次のようなコメントを残しました。 写真 写真 このコードを読んでいるときに、インターフェースが前後にジャンプして混乱しました。これらのエンコーダーを理解するために、段階的にデバッグするための単体テストを作成しました。本当にネストされています。以下は、これら 5 つのネスト層の概要です。 ウォッチエンコーダ —> ウォッチエンベデッドエンコーダ —> エンコーダー付きアロケーター —> コーデック —> json.シリアライザー それらはすべて Encoder インターフェースを実装しています... cachingObject のシリアル化と同様に、イベントのシリアル化にも追加のメモリ領域が必要ですが、各イベントの複数のシリアル化によって発生するメモリと CPU の消費を回避できるため、メモリの最適化にも役立ちます。 効果ウォッチリストと上記の最適化を通じて、コミュニティは最適化効果をもたらしました 最適化前 写真 最適化後 写真 やっとKube-apiserver メモリ最適化シリーズには、これまでの準備も含まれており、現在 6 つの記事があります。関連する知識をすべて理解すれば、kube-apiserver に対する理解が確実に深まります。今後もこの内容に注目して随時補足していきたいと思います〜 シリアル化は、メソッドを調整するだけなので単純に聞こえますが、それをうまく使用するのは簡単ではありません。多くの場合、このような場所が個人の能力を最もよく反映します。技術は日常の中に現れ、真実は細部の中に現れます。専門家が書いたコードを見て、設計やアイデアを理解し、要約し、変換して、自分の用途に取り入れます。 K8s は使いやすいですが、使いこなすのは簡単ではなく、舞台裏で何が起こっているのか理解するのは困難です。 10 年以上にわたる反復を経て、このプロジェクトはコードの量と複雑さの両面で非常に困難なものとなり、現在も反復と更新が続けられています。しかし、道は長くても歩き続ければ目的地にたどり着くでしょう。仕事は難しいですが、やれば成功するかもしれませんが、やらなければ絶対に成功しません。 話は安い、コードとPPTを見せてください 最後に、最先端の技術や業界の動向について議論するために、私のWeChat:YlikakuYを追加することを歓迎します〜 参考文献[1] kubernetes-api: https://kubernetes.io/zh-cn/docs/concepts/overview/kubernetes-api/ [2]問題#75294: https://github.com/kubernetes/kubernetes/issues/75294 [3]kep#1152-less-object-serializations: https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/1152-less-object-serializations [4]pr#119801: https://github.com/kubernetes/kubernetes/pull/119801 [5]問題#83898: https://github.com/kubernetes/kubernetes/issues/83898 [6]pr#120300: https://github.com/kubernetes/kubernetes/pull/120300 [7]kep#3157 ウォッチリスト: https://github.com/kubernetes/enhancements/blob/master/keps/sig-api-machinery/3157-watch-list/README.md [8]pr#108186: https://github.com/kubernetes/kubernetes/pull/108186 [9]pr#118362: https://github.com/kubernetes/kubernetes/pull/118362/ [10]問題#11014: https://github.com/kubernetes/kubernetes/issues/110146 [11]golang#json: https://github.com/golang/go/blob/d8762b2f4532cc2e5ec539670b88bbc469a13938/src/encoding/json/encode.go#L498 [12]問題#122153: https://github.com/kubernetes/kubernetes/issues/122153 |
<<: クラウド移行に関する注意事項 | ByteDanceの超大規模データベース製品技術の進化を理解するための図
2012年に国内のSEO業界が非常に発展したことに気づいているかどうかはわかりません。この年、Bai...
6月7日、雲奇会議上海サミットにおいて、世界的スナック食品大手のモンデリーズ・インターナショナルの代...
キーワードは検索エンジン最適化の重要な要素です。オンラインプロモーションの分野では、キーワードの適切...
2022年9月22日、 Mixue Bingchengは深セン証券取引所のメインボードに目論見書を公...
クラウドネイティブ時代において、国内外の多くのクラウドベンダーが強力な技術的配当をリリースしています...
budgetnode は Access Internet Ltd のブランドであり、今年登録番号10...
ハイブリッド クラウドの導入を推進している企業の CIO の中には、クラウド コンピューティングによ...
Baidu Kステーション事件は終わってからかなり経っているが、多くのウェブマスターは事件のことを考...
VPS (仮想プライベート サーバー) への移行には、通常、次の手順が含まれます。適切な VPS プ...
zji現在、香港の葵湾データセンターの独立サーバーでは特別クリアランスセールが行われています。CN2...
iniz.com のシンガポール VPS は、実は数日前から市場に出回っているのですが、迂回問題のた...
1. クラウド ストレージ アーキテクチャの概要クラウド ストレージは、サービスとしてのデータ スト...
企業が新しい ERP システムを選択する際に最も重要な考慮事項の 1 つは、オンプレミスの ERP ...
クリスマスの雰囲気がますます強くなり、CEEN「世界名靴淘宝顧客」プロモーションコンテスト[シーズン...
ドイツの有名なサーバー商人であるContaboは、創業20年を迎え、クラウドサーバー、VDS、専用サ...