Kafka が高速である 6 つの理由

Kafka が高速である 6 つの理由

[[335450]]

この記事はWeChatの公開アカウント「JavaKeeper」から転載したもので、著者は実在の人物です。この記事を転載する場合はJavaKeeper公式アカウントまでご連絡ください。

Kafka を MQ として使用する場合でも、ストレージ層として使用する場合でも、機能は 2 つだけです (非常にシンプルに見えます)。 1 つは、プロデューサーによって生成されたデータがブローカーに保存されることであり、もう 1 つは、コンシューマーがブローカーからデータを読み取ることです。 Kafka の速度は、読み取りと書き込みの 2 つの側面に反映されます。 Kafka が高速である理由についてお話ししましょう。

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

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

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

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

並列処理が可能であれば、速度は確実に向上し、1 人のワーカーよりも複数のワーカーの方が確実に高速に動作します。

「異なるディスクに並行して書き込むことはできますか?ディスクの読み取りと書き込みの速度を制御できますか?」

まず、ディスク/IO について簡単に説明しましょう。

「ハードディスクのパフォーマンスを制限する要因は何ですか?ディスクのI/O特性に基づいてシステムを設計するにはどうすればよいですか?」ハードディスク内の主なコンポーネントは、ディスクプラッター、トランスミッションアーム、読み取り/書き込みヘッド、およびスピンドルモーターです。実際のデータはディスクに書き込まれ、読み取りと書き込みは主にトランスミッションアームの読み取り/書き込みヘッドによって行われます。実際の操作中、スピンドルはディスクプラッターを回転させ、次にトランスミッションアームを伸ばして読み取りヘッドがディスクを読み書きできるようにします。ディスクの物理構造を下図に示します。

単一のディスクの容量には限りがあるため、ハードディスクには通常 2 つ以上のディスクが搭載されています。各ディスクには 2 つの面があり、どちらにも情報を記録できるため、1 つのディスクは 2 つのヘッドに対応します。ディスクは多数のセクター形の領域に分割されており、各領域はセクターと呼ばれます。ディスクの中心を中心としてディスク表面にある異なる半径の同心円をトラックと呼び、異なるディスク上の同じ半径のトラックで構成された円筒をシリンダと呼びます。トラックとシリンダーはどちらも、異なる半径の円を表します。多くの場合、トラックとシリンダーは互換的に使用できます。ディスク プラッターの垂直ビューを次の図に示します。

画像ソース: commons.wikimedia.org ディスクに影響を与える主な要因はディスク サービス時間、つまりディスクが I/O 要求を完了するのにかかる時間であり、これはシーク時間、回転遅延、およびデータ転送時間の 3 つの部分で構成されます。機械式ハードドライブの連続読み取りおよび書き込みパフォーマンスは非常に優れていますが、ランダム読み取りおよび書き込みパフォーマンスは非常に劣ります。これは主に、ヘッドが正しいトラックに移動するのに時間がかかるためです。ランダム読み取りおよび書き込み中は、ヘッドを継続的に移動する必要があり、ヘッドのアドレス指定に時間が浪費されるため、パフォーマンスは高くありません。ディスク パフォーマンスを測定するための主な重要な指標は、IOPS とスループットです。 Kafka や HBase などの多くのオープンソース フレームワークでは、追加書き込みを通じてランダム I/O を可能な限りシーケンシャル I/O に変換し、アドレス指定時間と回転遅延を削減して IOPS を最大化します。興味のある学生はディスクI/O[1]をご覧ください。

ディスクの読み取りと書き込みの速度は、ディスクの使用方法、つまり、順次読み取りと書き込みか、ランダム読み取りと書き込みかによって異なります。

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

画像ソース: kafka.apache.org

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

「かなり前に誰かがベンチマークをしました: 1 秒あたり 200 万回の書き込み (3 台の安価なマシンで) http://ifeve.com/benchmarking-apache-kafka-2-million-writes-second-three-cheap-machines/

ディスク容量が限られているため、すべてのデータを保存することはできません。実際、メッセージング システムとして、Kafka はすべてのデータを保存する必要はなく、古いデータを削除する必要があります。順次書き込みのため、Kafka がさまざまな削除戦略を使用してデータを削除する場合、「読み取り/書き込み」モードを使用してファイルを変更するのではなく、パーティションを複数のセグメントに分割し、各セグメントが物理ファイルに対応し、ファイル全体を削除することでパーティション内のデータを削除します。この方法は古いデータをクリアし、ファイルへのランダム書き込み操作を回避します。

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

キャッシュ層を導入する目的は、Linux オペレーティングシステムのディスクアクセスのパフォーマンスを向上させることです。キャッシュ層は、ディスク上のデータの一部をメモリにキャッシュします。データ要求が到着すると、データがキャッシュ内に存在し、最新のものであれば、データはユーザープログラムに直接渡され、基盤となるディスクの操作が排除され、パフォーマンスが向上します。キャッシュ層は、ディスク IOPS が 200 を超える主な理由の 1 つでもあります。Linux 実装では、ファイル キャッシュは 2 つのレベルに分かれており、1 つはページ キャッシュ、もう 1 つはバッファー キャッシュです。各ページ キャッシュには、複数のバッファー キャッシュが含まれています。ページ キャッシュは主に、プロセスがファイルに対して読み取り/書き込み操作を行うときに、ファイル システム上のファイル データのキャッシュとして使用されます。バッファー キャッシュは主に、システムがブロック デバイスを読み書きするときに、ブロック上のデータをキャッシュするためにシステムによって使用されるように設計されています。

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

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

ブローカーはデータを受信した後、ディスクに書き込むときにデータをページ キャッシュに書き込むだけで、データが完全にディスクに書き込まれることは保証しません。この観点から、マシンがクラッシュすると、ページ キャッシュ内のデータがディスクに書き込まれず、データが失われる可能性があります。ただし、このような損失は、停電などによりオペレーティング システムが動作を停止した場合にのみ発生し、このシナリオは Kafka レベルのレプリケーション メカニズムによって完全に解決できます。このような状況でデータが失われないようにするために、ページ キャッシュ内のデータを強制的にディスクにフラッシュすると、実際にはパフォーマンスが低下します。このため、Kafka ではページ キャッシュ内のデータを強制的にディスクにフラッシュするための flush.messages および flush.ms パラメータが提供されていますが、Kafka ではこれらの使用は推奨されていません。

4. ゼロコピー技術

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

「オペレーティングシステムの中核はカーネルです。カーネルは通常のアプリケーションから独立しており、保護されたメモリ空間にアクセスでき、基盤となるハードウェアデバイスにアクセスできます。ユーザープロセスがカーネルを直接操作するのを防ぎ、カーネルのセキュリティを確保するために、オペレーティングシステムは仮想メモリをカーネル空間 (Kernel-space) とユーザー空間 (User-space) の 2 つの部分に分割します。」

従来の Linux システムでは、標準 I/O インターフェイス (読み取りや書き込みなど) はデータ コピー操作に基づいています。つまり、I/O 操作により、カーネル アドレス空間のバッファーとユーザー アドレス空間のバッファー間でデータがコピーされるため、標準 I/O はキャッシュ I/O とも呼ばれます。これを行う利点は、要求されたデータがすでにカーネルのキャッシュ メモリに格納されている場合、実際の I/O 操作を削減できることですが、欠点は、データのコピー プロセスによって CPU オーバーヘッドが発生することです。

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

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

4.1 ディスクへのネットワークデータの永続化(プロデューサーからブローカーへ)

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

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

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

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

「DMA (ダイレクト メモリ アクセス): ダイレクト メモリ アクセス。DMA は、CPU を介さずに周辺機器とシステム メモリ間の双方向データ転送を可能にするハードウェア メカニズムです。DMA を使用すると、システム CPU を実際の I/O データ転送プロセスから解放できるため、システム スループットが大幅に向上します。

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

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

Kafka の場合、プロデューサーによって生成されたデータはブローカーに保存されます。このプロセスは、ソケット バッファーからネットワーク データを読み取り、実際にはカーネル空間で直接ディスクに書き込むことができます。ソケット バッファーのネットワーク データをアプリケーション プロセス バッファーに読み込む必要はありません。ここで、アプリケーション プロセス バッファは実際にはブローカーであり、ブローカーは永続化のためにプロデューサーからデータを受信します。

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

「メモリ マップ ファイル: mmap と略され、MMFile とも呼ばれます。mmap を使用する目的は、カーネル読み取りバッファのアドレスをユーザー空間バッファにマップすることです。これにより、カーネル バッファをアプリケーション メモリと共有できるようになり、カーネル読み取りバッファからユーザー バッファにデータをコピーするプロセスが不要になります。その動作原理は、オペレーティング システムのページを直接使用して、ファイルを物理メモリに直接マッピングすることです。マッピングが完了すると、物理メモリでの操作がハード ディスクに同期されます。この方法を使用すると、I/O が大幅に改善され、ユーザー空間からカーネル空間へのコピーのコストが節約されます。

Mmap にも明らかな欠陥があり、信頼性が低いのです。 mmap に書き込まれたデータは、実際にはハードディスクに書き込まれません。オペレーティング システムは、プログラムがアクティブにフラッシュを呼び出したときにのみ、データをハード ディスクに書き込みます。 Kafka は、アクティブにフラッシュするかどうかを制御するためのパラメーター producer.type を提供します。 Kafka が mmap に書き込んだ直後にフラッシュして Producer に戻る場合、それは同期 (sync) と呼ばれます。 Kafka が flush を呼び出さずに mmap に書き込んだ直後に Producer に戻る場合、それは非同期 (async) と呼ばれ、デフォルトは sync です。

ゼロコピー テクノロジーとは、コンピューターが操作を実行するときに、CPU が最初に 1 つのメモリ領域から別のメモリ領域にデータをコピーする必要がないため、コンテキストの切り替えと CPU のコピー時間が短縮されることを意味します。その機能は、ネットワーク デバイスからユーザー プログラム空間へのデータグラム転送プロセスにおけるデータ コピーとシステム コールの数を減らし、CPU の関与をゼロにし、この点での CPU 負荷を完全に排除することです。現在、ゼロコピー技術には主に3つの種類があります[3]。

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

4.2 ディスクファイルはネットワーク経由で送信されます(ブローカーからコンシューマーへ)

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

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

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

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

Linux 2.4 以降のカーネルは、sendfile システム コールを介してゼロコピーを提供します。データは DMA 経由でカーネル バッファーにコピーされた後、CPU コピーを必要とせずに DMA 経由で NIC バッファーに直接コピーされます。これはゼロコピーという用語の由来でもあります。データのコピーが削減されるだけでなく、ファイルの読み取りからネットワークへの送信まですべてが sendfile 呼び出しで完了するため、プロセス全体でコンテキスト スイッチが 2 回しか発生せず、パフォーマンスが大幅に向上します。

ここで Kafka が採用したソリューションは、NIO の transferTo/transferFrom を介してオペレーティング システムの sendfile を呼び出すことによってゼロ コピーを実装することです。合計2回のカーネルデータコピー、2回のコンテキストスイッチ、1回のシステムコールが発生し、CPUデータコピーが排除されます。

5. バッチ処理

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

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

6. データ圧縮

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

概要 |次に面接官にKafkaがなぜ速いのかと聞かれたら、こう答えよう。

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

参考文献

[1] Meituan - ディスクI/Oについて: https://tech.meituan.com/2017/05/19/about-desk-io.html

[2] Kafkaゼロコピー: https://zhuanlan.zhihu.com/p/78335525

[3] Linux - ゼロコピー: https://cllc.fun/2020/03/18/linux-zero-copy/

<<:  [高同時実行性] 数十億のトラフィック下で分散電流制限を実現するにはどうすればよいでしょうか?これらの理論をマスターしなければなりません! !

>>:  クラウド移行について

推薦する

SEOフォーラムの現状分析からより有益なSEO情報を得る方法

SEO 実践者として、私と同じように貴重な SEO 情報を見つけるためにフォーラムに行くことを好む人...

ウェブマスター向け情報サイトが復活しつつあるが、草の根ウェブマスターは持ちこたえなければならない

ウェブマスター業界の台頭に伴い、その派生品も多くの草の根ウェブマスターに歓迎されてきました。SEOト...

NeedAssistant - 5 ドル / kvm / 2g メモリ / 10g SSD / 1000M ポート / 無制限トラフィック

NeedAssistant.comは未知の新しい商人です。現在わかっていることは、そのWHMCSが認...

百度のザクロアルゴリズムアップデートが教えてくれること

Baidu の関係者と Baidu のウェブ検索不正対策チームの回答によると、「Baidu ザクロ ...

NetSuiteの主要な技術革新は、さまざまな業界の企業の急速な成長に貢献しています。

Oracle NetSuite は本日、あらゆる業界の企業の収益増加、国際展開、ビジネス ユーザーの...

安定したウェブサイトスペースはSEO最適化の基礎です

最近、Guangxian Technology の Xiao Ming は、企業 Web サイトの構...

Baidu による旅行ウェブサイトのプロモーションに関する経験と洞察

2012年に旅行会社にSEOスーパーバイザーとして入社してから1年以上が経ちました。いろいろな思いが...

クラウドネイティブのモダナイゼーションが増加中

昨年、Enterprise Strategy Group は、分散クラウド コンピューティングに関連...

2023 年のクラウド トレンド トップ 10

これらの傾向は、人工知能、デジタル主権規制、および専門的な業界ソリューションによる大きな技術的変化が...

SaaS の洞察: 中国の SaaS の過去と現在

[[398891]] SaaS は 20 世紀後半に誕生し、「古い」エンタープライズ アプリケーショ...

画像とテキストのストーリー: JVM の世界へ誘う記事

[[428766]]最近、私はほとんどの余暇時間を、シンプルな RPC フレームワーク (初心者でも...

世界で最も急成長しているドメイン名解決プロバイダートップ10:中国に4社

IDC Review Network (idcps.com) は 4 月 29 日に次のように報告し...

seopassword の 6 つのマーケティング トラップの分析。あなたはそのトラップに陥っていませんか?

Seopasswordは、最近SEO業界のダークホースとみなされています。わずか2、3か月で、百度イ...