「Code Brother」による Redis シリーズの記事の 1 つ、「Redis Core: スピードの秘密」では、Redis のパフォーマンス最適化について詳しく説明しています。 Redis の「スピード」の内部秘密を、IO、スレッド、データ構造、エンコーディングなどの側面から深く分析します。 65番兄弟は深い感銘を受けました。 Kafka を学習する過程で、Kafka も優れたパフォーマンスを持つミドルウェアであることがわかりました。そこで彼は Brother Code に Kafka のパフォーマンス最適化について話すように依頼しました。そこで、ブラザーコードはこのパフォーマンスブログ投稿をカフカシリーズのオープニング作品として使うことにしました。 Kafka シリーズの記事をプレビューしますので、お楽しみに: パフォーマンスについて説明することから、Kafka の旅を始めましょう。カフカの「スピード」の秘密を詳しく見てみましょう。 Kafka のパフォーマンス最適化のさまざまな手段を学習できるだけでなく、さまざまなパフォーマンス最適化方法論を抽出することもできます。これらの方法論は、私たち自身のプロジェクトにも適用でき、高性能なプロジェクトの作成に役立ちます。 関公 vs. 秦瓊
「はい、この記事は「分散キャッシュの選択」や「分散ミドルウェアの比較」に関するものではありません。私たちは、これら 2 つの異なる分野のプロジェクトのパフォーマンス最適化に焦点を当て、優れたプロジェクトのパフォーマンス最適化の一般的な手段と、さまざまなシナリオの特別な最適化方法を検討します。 多くの人は多くのことを学び、多くのフレームワークを理解していますが、実際の問題に遭遇すると、知識が不足していると感じることがよくあります。これは、学習した知識が体系化されておらず、具体的な実装から効果的な方法論が抽出されていないことを意味します。 オープンソース プロジェクトを学習する上で非常に重要なポイントは、帰納法、つまりさまざまなプロジェクトの優れた実装を方法論にまとめ、それを自分の実践に適用することです。 冒頭挨拶Ma Ge: 合理性、客観性、慎重さはプログラマーの特徴であり利点ですが、多くの場合、少し感情的かつ衝動的であることも必要であり、それによって意思決定を迅速化することができます。 「悲観主義者は正しく、楽観主義者は成功する。」誰もが楽観的に問題を解決する人であることを願っています。 Kafka パフォーマンスの概要非常に抽象的な観点から見ると、パフォーマンスの問題は次の 3 つのカテゴリに分類されます。
Kafka のようなネットワーク分散キューの場合、ネットワークとディスクが最適化の最優先事項となります。上記の抽象的な問題の場合、高い抽象度では解決策も非常に簡単です。
問題とアイデアがわかったところで、Kafka の役割を見てみましょう。これらの役割は最適化できるポイントです。
はい、問題点、アイデア、最適化ポイントはすべてリストされています。これら 3 つの方向すべてにおいて、可能な限り改良することができます。この方法では、すべての実装が一目でわかります。 Kafka の実装を見なくても、最適化できる領域が 1 つまたは 2 つ考えられます。 それは考え方です。質問を提起 > 問題点をリストアップ > 最適化方法をリストアップ > 特定のエントリ ポイントをリストアップ > トレードオフと実装の改善。 これからは、最適化のポイントや方法を自分で考えてみるのも良いでしょう。完璧である必要はなく、実装が簡単かどうかを心配する必要もありません。ちょっとアイデアを考えてみましょう。 65 兄:いいえ、私はバカで怠け者です。直接私に伝えればいいですよ。私は無料でやる方が得意です。 「順番に書いてください」Brother 65: Redis は純粋なメモリベースのシステムであり、Kafka もディスクの読み取りと書き込みを行う必要があります。どのように比較できるでしょうか? ディスクへの書き込みが遅いのはなぜですか?理由を知らずに結論だけを知ることはできません。この質問に答えるには、学校で学んだオペレーティング システムの授業に戻る必要があります。 65 教科書はまだ持っていますか?さあ、ディスクの章に進み、ディスクの動作原理を確認しましょう。 65 兄:幽霊はまだそこにいるよ。コースが半分も終わらないうちに、その本はなくなってしまいました。試験中に視力が優れていなかったら、私はまだ卒業していなかったでしょう。 「古典的な写真をご覧ください: ディスク IO を完了するには、シーク、回転、データ転送の 3 つのステップが必要です。 ディスク IO パフォーマンスに影響を与える要因は上記の 3 つのステップで発生するため、費やされる主な時間は次のとおりです。
したがって、ディスクへの書き込み時にシークと回転を省略すると、ディスクの読み取りと書き込みのパフォーマンスが大幅に向上します。 Kafka は、ディスク書き込みパフォーマンスを向上させるために順次ファイル書き込みを使用します。ファイルを順番に書き込むと、ディスクのシークと回転の回数が大幅に減ります。磁気ヘッドはトラック上で動き回る必要がなくなり、高速で前進します。 Kafka の各パーティションは、順序付けられた不変のメッセージ シーケンスです。新しいメッセージはパーティションの末尾に継続的に追加されます。 Kafka では、パーティションは単なる論理的な概念です。 Kafka はパーティションを複数のセグメントに分割します。各セグメントは物理ファイルに対応します。 Kafka は、順次ファイル書き込みであるセグメント ファイルに追加します。 65 ブラザー:Kafka はなぜ追加書き込み方式を使用できるのですか? 「これは Kafka の性質に関係しています。Kafka と Redis を見てみましょう。簡単に言うと、Kafka は Queue であり、Redis は HashMap です。Queue と Map の違いは何でしょうか? キューは FIFO であり、データは順序付けられます。 HashMap データは順序付けられておらず、ランダムに読み書きできます。 Kafka の不変性と秩序性により、Kafka は追加専用のアプローチを使用してファイルを書き込むことができます。 実際、上記の特性を満たす多くのデータ システムでは、追加書き込みを使用してディスク パフォーマンスを最適化できます。代表的な例としては、Redis の AOF ファイル、各種データベースの WAL (Write ahead log) メカニズムなどが挙げられます。 そのため、自社のビジネスの特性を明確に理解していれば、ターゲットを絞った最適化を行うことができます。 「ゼロコピー」兄65: ハハ、インタビューでこれ聞かれたよ。答えが平均的なものなのは残念です。 ゼロコピーとは何ですか?Kafka の観点から見ると、Kafka Consumer は Broker ディスクの読み取りからネットワーク経由で Consumer への送信まで、Broker ディスクに保存されているデータを消費し、そのプロセスにはどのようなシステム インタラクションが関係しているのでしょうか。 Kafka Consumer は Broker からデータを消費し、Broker は sendfile を使用してログを読み取ります。従来の IO モデルを使用する場合、疑似コード ロジックは次のようになります。
図に示すように、従来の IO プロセスを使用すると、最初にネットワーク IO が読み取られ、次にディスク IO が書き込まれるため、実際にはデータを 4 回コピーする必要があります。
65 兄:ああ、オペレーティングシステムはそんなに愚かなのか?あちこちコピーするだけです。 「オペレーティングシステムが愚かなわけではありません。オペレーティングシステムは、各アプリケーションが独自のユーザーメモリを持つように設計されており、ユーザーメモリはカーネルメモリから分離されています。これは、プログラムとシステムのセキュリティのためです。そうしないと、各アプリケーションのメモリがあちこちに散らばってしまい、自由に読み書きできるようになります。 ただし、ゼロコピー技術、英語では Zero-Copy というものもあります。ゼロコピーとは、上記データのコピー回数を最小限に抑え、コピーの CPU オーバーヘッドとユーザーモードとカーネルモード間のコンテキスト切り替え回数を削減し、データ転送のパフォーマンスを最適化することを意味します。 ゼロコピーの一般的なアイデアは 3 つあります。
Kafka は mmap と sendfile を使用してゼロコピーを実現します。それぞれ Java の MappedByteBuffer および FileChannel.transferTo に対応します。 ゼロコピーを実装するには、次のように Java NIO を使用します。
このモデルでは、コンテキストスイッチの回数が 1 回に削減されます。具体的には、transferTo() メソッドは、DMA エンジンを介してブロック デバイスにデータを読み取りバッファに読み込むように指示します。このバッファは、ソケットへのステージングのために別のカーネル バッファにコピーされます。最後に、ソケット バッファーは DMA 経由で NIC バッファーにコピーされます。 レプリカの数を 4 個から 3 個に減らしましたが、これらのレプリカのうち CPU が関係するのは 1 個だけです。また、コンテキストスイッチの数も 4 から 2 に削減しました。これは大きな改善ですが、クエリ ゼロ コピーはまだありません。後者は、Linux カーネル 2.4 以降と、収集操作をサポートするネットワーク インターフェイス カードを実行している場合に、さらなる最適化として実装できます。下記の通りです。 前の例に基づいて、transferTo() メソッドを呼び出すと、デバイスは DMA エンジンを介してデータをカーネル読み取りバッファに読み取ります。ただし、収集操作を使用する場合、読み取りバッファとソケット バッファ間のコピーは行われません。代わりに、NIC には読み取りバッファへのポインタとオフセットおよび長さが与えられ、これは DMA によってクリアされます。 CPU はバッファのコピーにはまったく関与しません。 ゼロコピーの詳細については、この記事「ゼロコピーとそのアプリケーションの簡単な分析」をお読みください。 ページキャッシュプロデューサーがブローカーにメッセージを生成すると、ブローカーは pwrite() システム コール (Java NIO の FileChannel.write() API に対応) を使用して、オフセットに従ってデータを書き込みます。このとき、データはまずページ キャッシュに書き込まれます。コンシューマーがメッセージを消費すると、ブローカーは sendfile() システム コール (FileChannel.transferTo() API に対応) を使用して、ページ キャッシュからブローカーのソケット バッファーにデータをゼロ コピーで転送し、ネットワーク経由で送信します。 リーダーとフォロワー間の同期は、上記のコンシューマーがデータを消費するプロセスに似ています。 カーネル内のフラッシャー スレッドがスケジュールされ、sync()/fsync() が呼び出されると、ページ キャッシュ内のデータがディスクに書き戻されます。プロセスがクラッシュしても、データの損失を心配する必要はありません。さらに、コンシューマーが消費したいメッセージがページ キャッシュにない場合は、ディスクにアクセスしてメッセージを読み取り、隣接するブロックの一部を事前に読み取り、ページ キャッシュに格納して次の読み取りを容易にします。 したがって、Kafka プロデューサーの生産率がコンシューマーの消費率とそれほど変わらない場合、ディスク アクセスをほとんど行わずに、ブローカー ページ キャッシュの読み取りと書き込みによって生産と消費のプロセス全体をほぼ完了できます。 ネットワークモデル65 ブラザー:Javaプログラマーとしては、ネットワークは当然Nettyです。 「はい、Netty は JVM 分野の優れたネットワーク フレームワークであり、高性能なネットワーク サービスを提供します。ほとんどの Java プログラマーがネットワーク フレームワークについて言及するとき、最初に思い浮かぶのは Netty です。Dubbo、Avro-RPC、その他の優れたフレームワークはすべて、基盤となるネットワーク通信フレームワークとして Netty を使用しています。 Kafka は RPC 用に独自のネットワーク モデルを実装します。基礎となるレイヤーは Java NIO に基づいており、Netty と同じ Reactor スレッド モデルを使用します。 Reacotrモデルは主に3つの役割に分かれています
従来のブロッキング IO モデルでは、各接続は独立したスレッドによって処理される必要があります。同時接続数が多いと、多くのスレッドが作成され、リソースが消費されます。ブロッキング IO モデルでは、接続が確立された後、現在のスレッドに読み取るデータがない場合、スレッドは読み取り操作でブロックされ、リソースが無駄になります。 従来のブロッキング IO モデルの 2 つの問題に対応するため、Reactor モデルはプーリングの考え方に基づいており、接続ごとにスレッドを作成することを回避します。接続が完了すると、ビジネス処理はスレッド プールに引き渡されます。 IO 再利用モデルに基づいて、すべての接続を待たずに、複数の接続が同じブロッキング オブジェクトを共有します。処理すべき新しいデータがある場合、オペレーティングシステムはプログラムに通知し、スレッドはブロッキング状態から抜け出し、ビジネスロジック処理を実行します。 Kafka は、Reactor モデルに基づいて多重化および処理スレッド プールを実装します。そのデザインは次のとおりです。 新しい接続を処理するための Acceptor スレッドが含まれています。アクセプターには、ソケット要求を選択して読み取る N 個のプロセッサ スレッドと、要求を処理して応答する、つまりビジネス ロジックを処理する N 個のハンドラー スレッドがあります。 I/O 多重化により、複数の I/O ブロッキングを同じ選択ブロッキングに多重化できるため、システムはシングルスレッドの場合に複数のクライアント要求を同時に処理できます。その最大の利点は、システムのオーバーヘッドが低く、新しいプロセスやスレッドを作成する必要がないため、システム リソースのオーバーヘッドが削減されることです。 概要: Kafka Broker の KafkaServer 設計は、優れたネットワーク アーキテクチャです。 Java ネットワーク プログラミングについて学習したい、またはこのテクノロジを使用する必要がある学生は、ソース コードを読むことをお勧めします。 「Code Brother」による今後の Kafka シリーズの記事でも、このソース コードの解釈について説明します。 バッチ処理と圧縮Kafka プロデューサーはブローカーにメッセージを 1 つずつ送信しません。 Kafka を使用したことがある学生は、Producer に batch.size と linger.ms という 2 つの重要なパラメーターがあることを知っておく必要があります。これら 2 つのパラメーターは、プロデューサーのバッチ送信に関連しています。 Kafka Producer の実行プロセスを次の図に示します。 メッセージの送信は、次のプロセッサを順番に通過します。
Kafka は、lz4、snappy、gzip など複数の圧縮アルゴリズムをサポートしています。 Kafka 2.1.0 は ZStandard を正式にサポートします - ZStandard は Facebook のオープンソース圧縮アルゴリズムで、超高圧縮率 (圧縮率) を提供するように設計されています。詳細については、zstd を参照してください。 プロデューサー、ブローカー、コンシューマーは同じ圧縮アルゴリズムを使用します。プロデューサーがブローカーにデータを書き込み、コンシューマーがブローカーからデータを読み取る場合、データを解凍する必要すらありません。最後に、コンシューマーがメッセージをポーリングするときにデータが解凍されるため、ネットワークとディスクのオーバーヘッドが大幅に削減されます。 パーティションの同時実行Kafka のトピックは複数のパーティションに分割でき、各パーティションはデータの順序を保証するキューに似ています。同じグループ内の異なるコンシューマーが同時にパーティションを消費します。パーティションは、実際には Kafka の並列処理を調整するための最小単位です。したがって、パーティションを追加するごとに消費の同時実行性が増加すると言えます。 Kafka には優れたパーティション割り当てアルゴリズムである StickyAssignor があり、これによりパーティション割り当てが可能な限りバランスが取れ、各再配分の結果が以前の割り当て結果と可能な限り一致することが保証されます。この方法では、クラスター全体のパーティションが可能な限りバランスが取れており、各ブローカーとコンシューマーの処理が過度に偏ることがなくなります。 65 兄弟: では、パーティションの数が多いほど良いということですか? "もちろん違います。 パーティションが増えると、開くファイルハンドルも増えますKafka ブローカーでは、各パーティションはファイル システム内のディレクトリに対応します。 Kafka データ ログ ファイル ディレクトリでは、各ログ データ セグメントにインデックス ファイルとデータ ファイルの 2 つのファイルが割り当てられます。したがって、パーティションの数が増えると、必要なファイル ハンドルの数が大幅に増加するため、必要に応じて、オペレーティング システムで開くことができるファイル ハンドルの数を調整する必要があります。 クライアント/サーバーが使用するメモリが増えるクライアント プロデューサーには batch.size というパラメーターがあり、デフォルトは 16 KB です。各パーティションのメッセージをキャッシュし、いっぱいになったらバッチで送信します。これはパフォーマンスを向上できる設計のようです。ただし、このパラメータはパーティション レベルであるため、パーティションの数が増えるほど、キャッシュのこの部分に必要なメモリも増えることは明らかです。 高可用性の削減パーティションの数が多いほど、各ブローカーに割り当てられるパーティションの数も多くなります。ブローカーがダウンすると、回復時間が非常に長くなります。 ファイル構造 Kafka メッセージはトピックによって分類されます。各トピックは互いに独立しており、相互に影響を与えません。各トピックは 1 つ以上のパーティションに分割できます。各パーティションには、メッセージ データを記録するログ ファイルがあります。 Kafka の各パーティション ログは、サイズに応じて物理的に複数のセグメントに分割されます。
インデックスはスパース インデックスを使用するため、各インデックス ファイルのサイズは制限されます。 Kafka は mmap を使用してインデックス ファイルをメモリに直接マップするため、インデックスの操作にディスク IO は必要ありません。 mmap の Java 実装は MappedByteBuffer に対応します。 65 兄弟のメモ: mmap はメモリ マッピング ファイルの方法です。つまり、ファイルまたはその他のオブジェクトがプロセスのアドレス空間にマッピングされ、ファイルのディスク アドレスとプロセス仮想アドレス空間内の仮想アドレスの間に 1 対 1 のマッピング関係が実現されます。このようなマッピング関係を実装すると、プロセスはポインターを使用してこのメモリ セクションの読み取りと書き込みを行うことができ、システムはダーティ ページを対応するファイル ディスクに自動的に書き戻すため、読み取りや書き込みなどのシステム コール関数を呼び出さずにファイル操作が完了します。逆に、カーネル空間によってこの領域に加えられた変更はユーザー空間にも直接反映されるため、異なるプロセス間でのファイル共有が可能になります。 Kafka はバイナリ検索を最大限に活用して、オフセットに対応するメッセージの位置を見つけます。
要約するKafka は優れたオープンソース プロジェクトです。パフォーマンスの最適化は非常に徹底しており、私たちが徹底的に研究する価値のあるプロジェクトです。思考であれ実現であれ、真剣に見つめて考えるべきです。 Kafka パフォーマンスの最適化:
この記事はWeChatの公開アカウント「MaGeByte」から転載したもので、以下のQRコードからフォローできます。この記事を転載する場合は、Code Byte の公開アカウントにご連絡ください。 |
<<: クラウド コンピューティングの経済的メリットを実現する 5 つの方法
>>: 2つのセッションからデジタルトランスフォーメーションの新たなトレンドについての洞察を得る
DigitalVirt VPS はいかがでしょうか?米国の AS4837 ライン上の Digital...
ショッピングモールの崩壊により、約20の銀行が支払い不履行に対する権利保護の渦に巻き込まれた。消費者...
タオバオは、咳をするだけで広範囲に影響を及ぼすほど巨大だ。タオバオ・アライアンスが来年からキャッシュ...
chicagovps.net は、ダラス、ニューヨーク、シカゴにデータセンターを持つ超安価な独立サー...
[[207428]] vSAN 6.6 では、VMware は新しいストレッチ クラスタ構成オプショ...
ホストユンはどうですか? hostyun 韓国 VPS はどうですか? Hostyun は、月額 1...
朗報です。Vultr は、スタッフが過去数年にわたって製品の大規模なアップグレードに取り組んできたこ...
Google セキュリティ ブログによると、3 月初旬に新しいタイプの DDOS 攻撃手法が登場しま...
今年、多くのウェブマスターが、ウェブサイトの最適化を行っても長い間改善が見られず、時間が経つにつれて...
ご存知のとおり、クラウド ストレージはビッグ データを扱うのではなく、物理サーバーやオペレーティング...
ウェブサイトの初期の頃は、集中的なサービスを提供するために一般的に 1 台のマシンを使用していました...
colossuscloud は、近年新たに立ち上げられた serverpoint (1998 年に独...
SEO 業界に参入したばかりの人は、通常、外部リンクの構築から始めます。これは、外部リンクの構築には...
cmivps の香港 VPS のデフォルト設定は中国本土最適化ですが、私が使用した多くのネットワーク...
Baidu Webmaster Platform の情報エリアに注目すると、Baidu が Web ...