Kafka が MQ として使用されるか、ストレージ層として使用されるかにかかわらず、その機能は 2 つだけです。1 つはプロデューサーによって生成されたデータをブローカーに保存することであり、もう 1 つはコンシューマーがブローカーからデータを読み取ることです。 Kafka の速度は、読み取りと書き込みの 2 つの側面に反映されます。 Kafka が高速である理由についてお話ししましょう。
パーティションを使用して並列処理を実装する 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台の安価なマシンで)
ディスク容量が限られているため、すべてのデータを保存することはできません。実際、メッセージング システムとして、Kafka はすべてのデータを保存する必要はなく、古いデータを削除する必要があります。 順次書き込みのため、Kafka がさまざまな削除戦略を使用してデータを削除する場合、「読み取り/書き込み」モードを使用してファイルを変更するのではなく、パーティションを複数のセグメントに分割します。 各セグメントは物理ファイルに対応しており、ファイル全体を削除するとパーティション内のデータが削除されます。 この方法は古いデータをクリアし、ファイルへのランダム書き込み操作を回避します。 ページキャッシュを最大限に活用する キャッシュ層を導入する目的は、Linux オペレーティング システムのディスク アクセスのパフォーマンスを向上させることです。キャッシュ レイヤーは、ディスク上のデータの一部をメモリにキャッシュします。 データ要求が到着すると、データがキャッシュ内に存在し、最新である場合、データはユーザー プログラムに直接渡されるため、基盤となるディスクに対する操作が不要になり、パフォーマンスが向上します。キャッシュ レイヤーは、ディスク IOPS が 200 を超える主な理由の 1 つでもあります。 Linux 実装では、ファイル キャッシュは 2 つのレベルに分かれており、1 つはページ キャッシュ、もう 1 つはバッファー キャッシュです。各ページ キャッシュには複数のバッファー キャッシュが含まれます。 ページ キャッシュは主に、プロセスがファイルに対して読み取り/書き込み操作を実行する場合に、ファイル システム上のファイル データのキャッシュとして使用されます。 バッファ キャッシュは主に、システムがブロック デバイスを読み書きするときにブロック データをキャッシュするシステムによって使用されるように設計されています。 ページキャッシュを使用する利点:
ブローカーはデータを受信した後、ディスクに書き込むときにデータをページ キャッシュに書き込むだけで、データが完全にディスクに書き込まれることは保証しません。この観点から、マシンがクラッシュすると、ページ キャッシュ内のデータがディスクに書き込まれず、データが失われる可能性があります。 ただし、このような損失は、停電などによりオペレーティング システムが動作を停止した場合にのみ発生し、このシナリオは 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 つのシステム コールが必要です。
このプロセスには、実際には 4 つのデータ コピーが含まれます。
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]。
②ディスクファイルはネットワーク経由で送信される(ブローカーから消費者へ) これを実現する従来の方法は、最初にディスクを読み取り、次にソケットを使用して送信することですが、実際には 4 つのコピーが関係します。
このプロセスは、上記の制作メッセージと比較できます。
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 が高速な理由を尋ねられたら、私はこう答えます。
参考文献:
https://tech.meituan.com/2017/05/19/about-desk-io.html
https://zhuanlan.zhihu.com/p/78335525
https://cllc.fun/2020/03/18/linux-zero-copy/ 著者: 偽物ではない 編集者:タオ・ジアロン 出典: 公開アカウント JavaKeeper (ID: JavaKeeper) から転載 |
<<: チェック・ポイントの2020年クラウド・セキュリティ・レポートは、パブリッククラウドにおけるエンタープライズ・セキュリティの問題と課題を浮き彫りにしている
ショートビデオ、セルフメディア、インフルエンサーのためのワンストップサービスまず、Weiboについて...
サトシ・ナカモトは暗号メーリンググループでは若手(おそらく30代前半)ですが、非常に目立つ立場にあり...
はじめに:青島美天ネットワークテクノロジー株式会社のCEOである韓静奎氏は本日、Xueqiuに「36...
「効率的な並行性」は、JVM シリーズの最後の記事です。この記事では主に、仮想マシンがマルチスレッド...
ゲームマーケティングは、Xiaoma によって最も収益性の高いオンラインマーケティングとして称賛され...
【51CTO.comオリジナル記事】 2017年12月1日〜2日、51CTO主催のWOTD 2017...
Hero Entertainmentの会長であるYing Shulingは、自分自身をパッケージング...
cmivps (~) は毎年恒例のダブル 11 イベントを開始しました。すべての VPS が 30%...
自社製品をグループ購入にうまく参加させるにはどうすればよいでしょうか? グループ購入活動をより強力に...
Meilishuoは、Weiboなどのソーシャルメディアを女性向けオンラインショッピングの分野に垂直...
現在の国際環境はますます複雑化、深刻化しており、国防や科学技術安全保障の重要性はより顕著になっていま...
moecloud の米国ロサンゼルスの cn2 gia vps が 15% オフで販売されており、1...
[[440688]] [51CTO.com クイック翻訳]ハイブリッドマルチクラウドの概要今日、企業...
一昨日、「cloudsigma:高速VPS、フィリピン・サウジアラビアなどに11のデータセンター、最...
キーワードの最適化に携わる SEO 担当者にとって、キーワードの競争力を分析することは基本的なスキル...