ついに、Kafka がなぜこんなに速いのかが分かりました!

ついに、Kafka がなぜこんなに速いのかが分かりました!

Kafka が MQ として使用されるか、ストレージ層として使用されるかにかかわらず、その機能は 2 つだけです。1 つはプロデューサーによって生成されたデータをブローカーに保存することであり、もう 1 つはコンシューマーがブローカーからデータを読み取ることです。

[[337633]]
画像はPexelsより

Kafka の速度は、読み取りと書き込みの 2 つの側面に反映されます。 Kafka が高速である理由についてお話ししましょう。

[[337634]]

パーティションを使用して並列処理を実装する

Kafka が Pub-Sub メッセージング システムであることは誰もが知っています。公開またはサブスクライブのいずれの場合でも、トピックを指定する必要があります。

トピックは単なる論理的な概念です。各トピックには 1 つ以上のパーティションが含まれ、異なるパーティションは異なるノードに配置できます。

一方、異なるパーティションを異なるマシンに配置できるため、クラスターの利点を最大限に活用してマシン間の並列処理を実現できます。

一方、パーティションは物理的にフォルダに対応しているため、同一ノード上に複数のパーティションが存在する場合でも、同一ノード上の異なるパーティションを異なるディスクに配置するように構成することができ、ディスク間の並列処理を実現し、複数ディスクの利点を最大限に発揮することができます。

並列処理が可能であれば、速度は確実に向上し、1 人のワーカーよりも複数のワーカーの方が確実に高速に動作します。データを異なるディスクに並行して書き込むことはできますか?ディスクの読み取りおよび書き込みの速度を制御できますか?まず、ディスク I/O について簡単に説明します。

ハードディスクのパフォーマンスに対する制約は何ですか?ディスク I/O 特性に基づいてシステムを設計するにはどうすればよいですか?

ハードディスク内の主なコンポーネントは、ディスク プラッター、ドライブ アーム、読み取り/書き込みヘッド、およびスピンドル モーターです。実際のデータはディスク上に書き込まれ、読み取りと書き込みは主に伝送アーム上の読み取り/書き込みヘッドを通じて行われます。

実際の動作では、スピンドルがディスク プラッターを回転させ、次にトランスミッション アームを伸ばして読み取りヘッドがプラッター上で読み取りと書き込みを行えるようにします。

ディスクの物理構造を次の図に示します。

単一のディスクの容量には限りがあるため、ハードディスクには通常 2 つ以上のディスクが搭載されています。各ディスクには 2 つの面があり、どちらにも情報を記録できるため、1 つのディスクは 2 つのヘッドに対応します。

ディスクは多数のセクター形の領域に分割されており、各領域はセクターと呼ばれます。ディスクの中心を中心としてディスク表面にある異なる半径の同心円をトラックと呼び、異なるディスク上の同じ半径のトラックで構成された円筒をシリンダと呼びます。

トラックとシリンダーはどちらも、異なる半径の円を表します。多くの場合、トラックとシリンダーは互換的に使用できます。

ディスク プラッターの垂直ビューを次の図に示します。

ディスクに影響を与える主な要因はディスク サービス時間、つまりディスクが I/O 要求を完了するのにかかる時間であり、これはシーク時間、回転遅延、およびデータ転送時間の 3 つの部分で構成されます。

機械式ハードドライブの連続読み取りおよび書き込みパフォーマンスは非常に優れていますが、ランダム読み取りおよび書き込みパフォーマンスは非常に劣ります。これは主に、ヘッドが正しいトラックに移動するのに時間がかかるためです。ランダム読み取りおよび書き込み中は、ヘッドを継続的に移動する必要があり、ヘッドのアドレス指定に時間が浪費されるため、パフォーマンスは高くありません。ディスクを測定するための主な重要な指標は、IOPS とスループットです。

Kafka や HBase などの多くのオープンソース フレームワークでは、追加書き込みを通じてランダム I/O を可能な限りシーケンシャル I/O に変換し、アドレス指定時間と回転遅延を削減して IOPS を最大化します。

興味のある学生はディスクI/O [1]を参照してください。ディスクの読み取りと書き込みの速度は、ディスクの使用方法、つまり、順次読み取りと書き込みか、ランダム読み取りと書き込みかによって異なります。

ディスクへの順次書き込み

Kafka の各パーティションは順序付けられた不変のメッセージ シーケンスであり、新しいメッセージはパーティションの末尾に継続的に追加され、順次書き込みが行われます。

かなり前に誰かがベンチマークをしました: 1秒あたり200万回の書き込み (3台の安価なマシンで)

  1. http://ifeve.com/benchmarking-apache-kafka-2-million-writes-second-three-cheap-machines/

ディスク容量が限られているため、すべてのデータを保存することはできません。実際、メッセージング システムとして、Kafka はすべてのデータを保存する必要はなく、古いデータを削除する必要があります。

順次書き込みのため、Kafka がさまざまな削除戦略を使用してデータを削除する場合、「読み取り/書き込み」モードを使用してファイルを変更するのではなく、パーティションを複数のセグメントに分割します。

各セグメントは物理ファイルに対応しており、ファイル全体を削除するとパーティション内のデータが削除されます。

この方法は古いデータをクリアし、ファイルへのランダム書き込み操作を回避します。

ページキャッシュを最大限に活用する

キャッシュ層を導入する目的は、Linux オペレーティング システムのディスク アクセスのパフォーマンスを向上させることです。キャッシュ レイヤーは、ディスク上のデータの一部をメモリにキャッシュします。

データ要求が到着すると、データがキャッシュ内に存在し、最新である場合、データはユーザー プログラムに直接渡されるため、基盤となるディスクに対する操作が不要になり、パフォーマンスが向上します。キャッシュ レイヤーは、ディスク IOPS が 200 を超える主な理由の 1 つでもあります。

Linux 実装では、ファイル キャッシュは 2 つのレベルに分かれており、1 つはページ キャッシュ、もう 1 つはバッファー キャッシュです。各ページ キャッシュには複数のバッファー キャッシュが含まれます。

ページ キャッシュは主に、プロセスがファイルに対して読み取り/書き込み操作を実行する場合に、ファイル システム上のファイル データのキャッシュとして使用されます。

バッファ キャッシュは主に、システムがブロック デバイスを読み書きするときにブロック データをキャッシュするシステムによって使用されるように設計されています。

ページキャッシュを使用する利点:

  • I/O スケジューラは、連続する小さなブロック書き込みを大きな物理書き込みに組み立てて、パフォーマンスを向上させます。
  • I/O スケジューラは、ディスク ヘッドの移動時間を短縮するために、一部の書き込み操作の順序を変更しようとします。
  • すべての空きメモリ(JVM 以外のメモリ)を最大限に活用します。アプリケーション層キャッシュ (JVM ヒープ メモリなど) を使用すると、GC の負荷が増加します。
  • 読み取り操作はページ キャッシュ内で直接実行できます。消費速度と生成速度が同程度であれば、物理ディスク経由でデータを交換する必要さえない場合もあります (ページ キャッシュ経由で直接)。
  • プロセスを再起動すると、JVM 内のキャッシュは無効になりますが、ページ キャッシュは引き続き使用できます。

ブローカーはデータを受信した後、ディスクに書き込むときにデータをページ キャッシュに書き込むだけで、データが完全にディスクに書き込まれることは保証しません。この観点から、マシンがクラッシュすると、ページ キャッシュ内のデータがディスクに書き込まれず、データが失われる可能性があります。

ただし、このような損失は、停電などによりオペレーティング システムが動作を停止した場合にのみ発生し、このシナリオは Kafka レベルのレプリケーション メカニズムによって完全に解決できます。

このような状況でデータが失われないようにするために、ページ キャッシュ内のデータを強制的にディスクにフラッシュすると、実際にはパフォーマンスが低下します。

このため、Kafka ではページ キャッシュ内のデータを強制的にディスクにフラッシュするための flush.messages および flush.ms パラメータが提供されていますが、Kafka ではこれらの使用は推奨されていません。

ゼロコピー技術

Kafka には、ネットワーク データをディスクに保存するプロセス (プロデューサーからブローカー) と、ディスク ファイルをネットワーク経由で送信するプロセス (ブローカーからコンシューマー) が多数あります。このプロセスのパフォーマンスは、Kafka の全体的なスループットに直接影響します。

オペレーティング システムの中核はカーネルです。カーネルは通常のアプリケーションから独立しており、保護されたメモリ領域にアクセスでき、基盤となるハードウェア デバイスにアクセスできます。

ユーザープロセスがカーネルを直接操作するのを防ぎ、カーネルのセキュリティを確保するために、オペレーティングシステムは仮想メモリをカーネル空間とユーザー空間の 2 つの部分に分割します。

従来の Linux システムでは、標準 I/O インターフェイス (読み取りや書き込みなど) はデータ コピー操作に基づいています。つまり、I/O 操作により、カーネル アドレス空間のバッファーとユーザー アドレス空間のバッファー間でデータがコピーされるため、標準 I/O はキャッシュ I/O とも呼ばれます。

これを行う利点は、要求されたデータがすでにカーネルのキャッシュ メモリに格納されている場合、実際の I/O 操作を削減できることですが、欠点は、データのコピー プロセスによって CPU オーバーヘッドが発生することです。

Kafkaの生成と消費を次の2つのプロセスに簡略化します[2]。

  • ディスクへのネットワークデータの永続化(プロデューサーからブローカーへ)
  • ディスクファイルはネットワーク経由で送信されます(ブローカーから消費者へ)

① ネットワークデータはディスクに保存される(プロデューサーからブローカーへ)

従来のモードでは、ネットワークからファイルへのデータ転送には、4 つのデータ コピー、4 つのコンテキスト スイッチ、および 2 つのシステム コールが必要です。

  1. data = socket.read () // ネットワークデータを読み取る
  2. ファイル file = new File()
  3. file.write(data) // ディスクに保存
  4. ファイル.フラッシュ()

このプロセスには、実際には 4 つのデータ コピーが含まれます。

  • まず、ネットワーク データは DMA コピーを通じてカーネル状態のソケット バッファーにコピーされます。
  • 次に、アプリケーションはカーネル状態バッファ データをユーザー状態 (CPU コピー) に読み取ります。
  • 次に、ユーザー プログラムはユーザー状態バッファーをカーネル状態にコピーします (CPU コピー)。
  • 最後に、DMA コピーを通じてデータがディスク ファイルにコピーされます。

DMA (ダイレクト メモリ アクセス): 直接メモリ アクセス。 DMA は、CPU を介さずに周辺機器とシステム メモリ間の双方向データ転送を可能にするハードウェア メカニズムです。

DMA を使用すると、システム CPU を実際の I/O データ転送プロセスから解放できるため、システムのスループットが大幅に向上します。

同時に、次の図に示すように 4 つのコンテキスト スイッチが存在します。

データ ストレージは通常リアルタイムではなく、Kafka プロデューサー データの永続性についても同様です。 Kafka のデータはハードディスクにリアルタイムで書き込まれません。これは、最新のオペレーティング システムのページング ストレージを最大限に活用してメモリを使用し、I/O 効率を向上させます。これが、前のセクションで説明したページ キャッシュです。

Kafka の場合、プロデューサーによって生成されたデータはブローカーに保存されます。このプロセスは、ソケット バッファーからネットワーク データを読み取り、実際にはカーネル空間で直接ディスクに書き込むことができます。

ソケット バッファーのネットワーク データをアプリケーション プロセス バッファーに読み込む必要はありません。ここで、アプリケーション プロセス バッファは実際にはブローカーであり、ブローカーは永続化のためにプロデューサーからデータを受信します。

この特別なシナリオでは、ソケット バッファーからネットワーク データを受信するときに、アプリケーション プロセスは中間処理を必要とせず、それを直接保持します。 mmap メモリ ファイル マッピングを使用できます。

メモリマップ ファイル: mmap と略され、MMFile とも呼ばれます。 mmap を使用する目的は、カーネル内の読み取りバッファのアドレスをユーザー空間のバッファにマッピングすることです。

これにより、カーネル バッファーとアプリケーション メモリの共有が可能になり、カーネル読み取りバッファーからユーザー バッファーにデータをコピーするプロセスが不要になります。

その動作原理は、オペレーティング システムのページを直接使用して、ファイルを物理メモリに直接マッピングすることです。マッピングが完了すると、物理メモリ上の操作がハードディスクに同期されます。

このアプローチを使用すると、ユーザー空間からカーネル空間へのコピーのオーバーヘッドを排除することで、大幅な I/O の改善を実現できます。

Mmap にも明らかな欠陥があります。それは信頼性が低いことです。 mmap に書き込まれたデータは、実際にはハードディスクに書き込まれません。オペレーティング システムは、プログラムがアクティブに Flush を呼び出したときにのみ、データをハード ディスクに書き込みます。

Kafka は、アクティブにフラッシュするかどうかを制御するためのパラメーター producer.type を提供します。 Kafka が mmap に書き込んだ直後にフラッシュし、その後 Producer に戻る場合、それは同期 (sync) と呼ばれます。

mmap に書き込んだ後、Flush を呼び出さずにすぐに Producer に戻ることを非同期 (async) と呼び、デフォルトは sync です。

ゼロコピー テクノロジーとは、コンピューターが操作を実行するときに、CPU が最初に 1 つのメモリ領域から別のメモリ領域にデータをコピーする必要がないため、コンテキストの切り替えと CPU のコピー時間が短縮されることを意味します。

その機能は、ネットワーク デバイスからユーザー プログラム空間へのデータグラム転送プロセスにおけるデータ コピーとシステム コールの数を減らし、CPU の関与をゼロにし、この点での CPU 負荷を完全に排除することです。

現在、ゼロコピー技術には主に3つの種類があります[3]。

  • 直接 I/O: データはカーネルを直接通過し、ユーザー アドレス空間と I/O デバイス間で転送されます。カーネルは、仮想ストレージの構成など、必要な補助作業のみを実行します。
  • カーネルとユーザー空間間のデータのコピーを回避: アプリケーションがデータにアクセスする必要がない場合、カーネル空間からユーザー空間、mmap、sendfile、splice && tee、sockmap へのデータのコピーを回避できます。
  • コピーオンライト: コピーオンライト技術では、データを事前にコピーする必要はなく、変更が必要なときに部分的にコピーされます。

②ディスクファイルはネットワーク経由で送信される(ブローカーから消費者へ)

これを実現する従来の方法は、最初にディスクを読み取り、次にソケットを使用して送信することですが、実際には 4 つのコピーが関係します。

  1. バッファ = File.read   
  2. ソケット.send(バッファ)

このプロセスは、上記の制作メッセージと比較できます。

  • まず、システム コールを通じてファイル データがカーネル バッファー (DMA コピー) に読み込まれます。
  • 次に、アプリケーションはメモリ状態バッファのデータをユーザー状態バッファ (CPU コピー) に読み取ります。
  • 次に、ユーザー プログラムがソケットを介してデータを送信すると、ユーザー状態バッファー データがカーネル状態バッファーにコピーされます (CPU コピー)。
  • 最後に、データは DMA を介して NIC バッファにコピーされます。

Linux 2.4 以降のカーネルは、Sendfile システム コールを介してゼロコピーを提供します。データは DMA 経由でカーネル バッファーにコピーされた後、CPU コピーを必要とせずに DMA 経由で NIC バッファーに直接コピーされます。これはゼロコピーという用語の由来でもあります。

データのコピーが削減されるだけでなく、ファイルの読み取りとネットワーク送信全体が Sendfile 呼び出しによって完了するため、プロセス全体でコンテキスト スイッチが 2 回しか発生せず、パフォーマンスが大幅に向上します。

ここで Kafka が採用したソリューションは、NIO の transferTo/transferFrom を介してオペレーティング システムの Sendfile を呼び出すことによってゼロ コピーを実装することです。

合計 2 回のカーネル データ コピー、2 回のコンテキスト スイッチ、および 1 回のシステム コールが発生し、CPU データ コピーが排除されます。

バッチ処理

多くの場合、システムのボトルネックとなるのは CPU やディスクではなく、ネットワーク IO です。

したがって、オペレーティング システムによって提供される低レベルのバッチ処理に加えて、Kafka クライアントとブローカーは、データをネットワーク経由で送信する前に、複数のレコード (読み取りと書き込みの両方) をバッチで蓄積します。

レコードをバッチ処理すると、より大きなパケットが使用されるため、ネットワークの往復コストが削減され、帯域幅の使用率が向上します。

データ圧縮

プロデューサーはデータを圧縮してブローカーに送信し、ネットワーク転送コストを削減できます。現在サポートされている圧縮アルゴリズムは、Snappy、Gzip、LZ4 です。データ圧縮は通常、最適化ツールとしてバッチ処理と組み合わせて使用​​されます。

次回、面接官に Kafka が高速な理由を尋ねられたら、私はこう答えます。

  • パーティション並列処理。
  • ディスクの特性を最大限に活用するために、ディスクに順番に書き込みます。
  • 最新のオペレーティング システムのページング ストレージ ページ キャッシュは、メモリを活用して I/O 効率を向上させるために使用されます。
  • ゼロコピー技術が使用されます。プロデューサーによって生成されたデータはブローカーに永続化され、mmap ファイル マッピングを使用して順次かつ高速な書き込みが実現されます。顧客はブローカーからデータを読み取り、Sendfile を使用してディスク ファイルを OS カーネル バッファーに読み込み、それを NIO バッファーに転送してネットワーク送信することで、CPU 消費を削減します。

参考文献:

  • 美団 - ディスクI/O

https://tech.meituan.com/2017/05/19/about-desk-io.html

  • Kafka ゼロコピー

https://zhuanlan.zhihu.com/p/78335525

  • Linux - ゼロコピー

https://cllc.fun/2020/03/18/linux-zero-copy/

著者: 偽物ではない

編集者:タオ・ジアロン

出典: 公開アカウント JavaKeeper (ID: JavaKeeper) から転載

<<:  チェック・ポイントの2020年クラウド・セキュリティ・レポートは、パブリッククラウドにおけるエンタープライズ・セキュリティの問題と課題を浮き彫りにしている

>>:  パブリッククラウドに関する10の誤解

推薦する

ミニプログラムとARが出会うと、ブラックテクノロジーマーケティングもこのように展開される

月収10万元の起業の夢を実現するミニプログラム起業支援プラン[Lieyun.com(WeChat:i...

HUAWEI Cloud GaussDB(openGauss用):業界の悩みを解決し、Huaweiの消費者向けクラウドデータベースを分散型クラウドへと変革する支援

今日のデジタル時代において、データは企業の中核資産となり、ビジネスの革新と持続可能な発展を推進してい...

オンライン教育:従来の教育の受動的でオープンな内容が弱点

ロビン・リー氏が言うように、インターネットは伝統的な産業を変えつつあります。タクシー配車アプリはすで...

perfectip $39.99 サーバー/E5520/12G メモリ/500G ハードディスク/100M 無制限

perfectip は特別価格のサーバーを立ち上げましたが、これは構成の面で絶対にお金に見合う価値が...

Oracle Brontoは、すべてのチャネルでパーソナライズされた製品推奨を提供します。

インターネット小売業者トップ 1000 社に対するクラウドベースの電子メール マーケティングの大手プ...

ソウルもビリビリから「悪循環を断ち切る」方法を学びたい?

ソウルのソーシャルネットワーキングの本来の目的は、商業化の道に逆らう運命にある。ユーザー数の伸び悩み...

JVMの原理と徹底的なチューニング

[[436050]] JVMとはJVM は、ユーザー モードで実行され、アプリケーションを通じてクロ...

有能なウェブマスターになる方法について語る [パート 2]

前回は主にデータ セキュリティ、Web サイト セキュリティ、サーバー セキュリティなどの問題につい...

テンセントの情報流通の決戦か?

ショートビデオ以外にテンセントが常に「懸念している」ビジネスがあるとすれば、それは情報の流れに違いな...

bgpto: 専用サーバーのサマープロモーション、日本のマシンは 35% オフ、シンガポールのマシンは 25% オフ、20M の帯域幅、月額 93 ドルから

bgp.to は、日本とシンガポールのデータセンターの独立サーバーに特別プロモーションを提供していま...

簡単な分析:地域観光ウェブサイトの運営方法

地域旅行サイトとして、まずはサイトへの高品質で自然な外部リンクを公開する必要があります。まず、ソウル...

テンセントクラウドとサンフォーが正式に戦略提携

1月29日、Tencent CloudとSangforは戦略協力協定に署名し、正式に戦略的パートナー...

ウェブサイトの外部リンクを構築するときは、「自分の強みを生かし、弱点を避ける」方法を知る必要があります。

外部リンクは、SEO の中核から切り離せないトピックです。外部リンクソースの選択方法、外部リンク計画...

dedipath - 6 ドル/5g メモリ/100g SSD/2 コア/5T トラフィック/2IP/ロサンゼルス

dedipath は最近設立されたホスティング ブランドのようです。現時点では、あまり情報がありませ...

エンタープライズインターネットマーケティングの位置付け: 会社のインターネット部門は何を行っているか?

中国におけるインターネットユーザー数とネットワークハードウェア設備の発展に伴い、オンラインショッピン...