分散システム Kafka と ES では、JVM メモリを増やす方が良いでしょうか?

分散システム Kafka と ES では、JVM メモリを増やす方が良いでしょうか?

この記事では、実稼働環境からの実践的な経験を共有します。オンライン システムをデプロイする場合、JVM ヒープ メモリ サイズが大きいほど良いのでしょうか?

この記事では、通常の Java アプリケーション システムではなく、Kafka と Elasticsearch という 2 つの分散システムのオンライン展開について主に説明します。

データを処理するために Java システム独自のメモリに依存しますか?

まず、独自に開発した Java アプリケーション システムであっても、ミドルウェア システムであっても、実装時に独自の Java プロセスのメモリに基づいてデータを処理するかどうかを選択する必要があります。

皆さんご存知のとおり、Java や Scala などのプログラミング言語はすべて、最下層で JVM に依存しています。したがって、JVM が使用されている限り、JVM プロセスのメモリに大量のデータを配置することを検討できます。

例を挙げてみましょう。以前、メッセージ ミドルウェア システムについて説明したことを覚えているかもしれません。

たとえば、システム A がシステム B にメッセージを送信できる場合、中間にメッセージ ミドルウェアが必要です。システム A はまずメッセージをメッセージ ミドルウェアに送信し、次にシステム B がメッセージ ミドルウェアからメッセージを消費します。

次の図をご覧ください。

メッセージがメッセージ ミドルウェアに送信された後、それを処理する 1 つの方法は、データを独自の JVM メモリにバッファリングすることです。

その後、一定時間が経過すると、メッセージが自身のメモリからディスクに更新され、以下に示すように、メッセージが永続化されます。

Java システム独自のメモリに依存することの欠点は何ですか?

上記と同様の方法を使用し、高い並行性で書き込まれた大量のメッセージをバッファリングするためのメモリ バッファを設計するなど、Java システム独自のメモリに依存してデータを処理する場合は、欠陥があります。

*** の欠陥は、実際には JVM の GC の問題です。この GC はガベージコレクションです。それが何であるかを簡単に説明します。

Java プロセスに常に大量のデータが詰め込まれている場合、このデータはメモリ内のバッファリングに使用されますが、しばらくするとこのデータはディスクに書き込まれることが想像できます。

では、ディスクに書き込んだ後も、これらのデータをメモリに保持する必要があるのでしょうか?明らかにそうではありません。このとき、メモリ内の不要なデータをリサイクルし、メモリ領域を解放するために、JVM ガベージ コレクション メカニズムが使用されます。

ただし、JVM がガベージ コレクションを実行する場合、ストップ ザ ワールドと呼ばれる状況が発生し、作業スレッドが停止されてガベージ コレクションが実行されることになります。

このとき、ガベージコレクションが実行されると、ミドルウェアシステムが実行できなくなる可能性があります。

たとえば、リクエストを送信した場合、リクエストを受信するための作業スレッドが停止し、バックグラウンドのガベージ コレクション スレッドがガベージ オブジェクトを収集しているため、応答できないことがあります。

次の画像をご覧ください。

JVM のガベージ コレクターは、CMS から G1 まで、常に進化と開発を続けており、ガベージ コレクションの影響を軽減し、作業スレッドの一時停止を可能な限り減らすよう努めています。

しかし、大量のデータを管理するために JVM メモリに完全に依存している場合、ガベージ コレクション中に常に何らかの影響を受けることになります。

したがって、特に一部のビッグデータ システムやミドルウェア システムにとって、JVM GC (ガベージ コレクター) の問題は、実際には最も厄介な問題です。

JVMではなくOSキャッシュに依存するように最適化されています

したがって、Kafka や Elasticsearch などの分散ミドルウェア システムも JVM 上で実行されますが、大量のデータを管理するために OS キャッシュに依存することを選択します。

つまり、大量のデータを管理するために JVM 独自のメモリに依存するのではなく、オペレーティング システムによって管理されるメモリ バッファーです。

具体的には、Kafka を例に挙げます。 Kafka にデータを書き込むと、実際にはディスク ファイルに直接書き込まれます。

ただし、ディスク ファイルが書き込まれる前に、実際には、オペレーティング システムによって管理されるメモリ領域である OS キャッシュに入ります。その後、一定時間が経過すると、オペレーティング システムは OS キャッシュ データをディスクにフラッシュすることを選択します。

そして、その後にデータを消費する際には、実際には OS キャッシュ (メモリ バッファ) からのデータの読み取りが優先されます。

これは、オペレーティング システム レベルのメモリ領域に完全に基づいており、高い読み取りおよび書き込みパフォーマンスを備えた OS キャッシュに基づいてデータの書き込みおよび読み取りを行うことに相当します。

さらに、大量のデータをバッファリングするために独自の JVM に依存しないため、複雑で時間のかかる JVM ガベージ コレクション操作を回避できるという利点もあります。

次の図は、典型的な Kafka 操作プロセスを示しています。

たとえば、人気のある分散検索システムである Elasticsearch も同様のメカニズムを使用しています。

大量のデータをバッファリングするために OS キャッシュに大きく依存し、検索や照会中に、まず OS キャッシュ (メモリ領域) からデータを読み取ることができるため、非常に高い読み取りおよび書き込みパフォーマンスが保証されます。

OS キャッシュに依存するシステムの場合、JVM メモリを増やす方が良いでしょうか?

さて、本題に入りましょう。たとえば、Kafka や Elasticsearch などの前述のシステムをオンラインの本番環境にデプロイすると、大量のデータをバッファリングするために OS キャッシュに大きく依存することが分かります。では、JVM ヒープ メモリ サイズを割り当てる場合、大きいほど良いのでしょうか?

明らかにそうではありません。 32GB のメモリを搭載したマシンがあるとします。状況を理解せず、JVM にできるだけ多くのメモリを割り当てる必要があると愚かに考えると、たとえば JVM に 16G のヒープ メモリ領域を割り当てた場合、他のプログラム自体が数 GB のメモリを占有するため、OS キャッシュに残されるメモリは 10GB 未満になる可能性があります。

この場合、ディスクに書き込むときに OS キャッシュが収容できるデータの量は非常に制限されます。

たとえば、ディスクに書き込むデータが合計 20 GB ある場合、10 GB のデータのみを OS キャッシュに配置でき、残りの 10 GB のデータはディスクにのみ配置できます。

このとき、データを読み取る場合、読み取り要求の少なくとも半分はディスクから読み取る必要があり、OS キャッシュから読み取ることはできません。 OS キャッシュは 10G のデータの半分しか保持できず、残りの半分はディスク上にあると誰が言ったのでしょうか。次の図に示すように、これを回避する方法はありません。

この時点で、リクエストの半分はディスクからデータを読み取っており、必然的にパフォーマンスが低下します。

Elasticsearch を使用するときに、多くの人がこの問題に遭遇します。 ESの読み取り速度が遅いといつも感じています。 ES に書き込まれた数億のデータを読み取るには数秒かかります。

数秒かかりますか? ES クラスターを展開するときに JVM に割り当てすぎるメモリがあり、OS キャッシュに数 GB のメモリを残している場合、数億のデータのほとんどは OS キャッシュではなくディスク上に存在することになります。 *** 読み取り中に大量のディスクを読み取り、数秒かかるのは正常です。

正しいアプローチ: シナリオに基づいてOSキャッシュにメモリを追加する

したがって、Kafka や Elasticsearch などの本番システムをデプロイする場合は、JVM に 6 GB または数 GB のメモリのみを割り当てる必要があります。

メモリ領域をあまり必要とせず、JVM メモリ管理データに依存しないためです。もちろん、具体的な設定には正確なストレス テストと最適化が必要です。

ただし、このようなシステムでは、OS キャッシュ用に十分なメモリ領域を予約する必要があります。たとえば、32GB のメモリを搭載したマシンでは、OS キャッシュ用に 20GB を超えるメモリ領域を予約できます。

したがって、この時点で、マシンが合計 20 GB のデータを書き込んだと仮定すると、そのすべてが OS キャッシュに存在できます。

その後、後でデータをクエリするときに、OS キャッシュからすべてのデータを読み取り、メモリに完全に依存することができます。そうすれば、パフォーマンスは確実にミリ秒単位になり、クエリの完了に数秒かかることは不可能になります。

全体のプロセスを下の図に示します。

したがって、オンライン生産システムに何らかのテクノロジーを導入する場合は、まずそのテクノロジーの原理やソースコードを深く理解し、その特定のワークフローを把握した上で、最適な生産パフォーマンスを確保するために、生産環境の展開計画をターゲットを絞って合理的に設計することをお勧めします。

Chinese Huperzine: 10 年以上の BAT アーキテクチャ経験、一流インターネット企業のテクニカル ディレクター。数百人のチームを率いて、数億のトラフィックを処理する複数の高同時実行システムを開発しました。長年の研究で蓄積してきた研究論文や経験の要約を文書にまとめましたので、皆様にご紹介したいと思います。 WeChat 公開アカウント: Shishan’s Architecture Notes (ID: shishan100)。

<<:  すべてのビジネスをクラウドで実行することは本当に良い戦略でしょうか?

>>:  高並列アーキテクチャシリーズ: Kafka、RocketMQ、RabbitMQ の長所と短所の比較

推薦する

ウェブマスターがソフト記事執筆のインスピレーションを得る方法の簡単な分析

ソフト記事のプロモーションにより、ウェブサイトに予想外の利益がもたらされました。ソフト記事はさまざま...

石家荘のSEOレベルは一般的に低い

2018年最もホットなプロジェクト:テレマーケティングロボットがあなたの参加を待っています石家荘イン...

Baiduの外部最適化を行う方法についての考察

ウェブサイト運営の最適化のプロセスにおいて、Baidu の検索エンジン最適化は間違いなく最大の市場シ...

張小龍は過剰な内部消費に抵抗できるか?それはWeChatにとって生死の問題だ

私は、WeChatが現在のインターネット企業の中で最もオープンな製品かもしれないと常に感じてきました...

百度6月の大型アップデートにおけるウェブサイトペナルティの3つの状況を分析

6月の百度の大型アップデートを受けて、私たちはペナルティを受けたウェブサイトを詳細に観察しました。同...

インテリジェントな運用と保守における分散アクティブ知覚の実践

はじめに: 企業のデジタル化により、運用と保守のインテリジェントな変革が不可避になりました。 Cre...

人気のTik Tokショート動画をマーケティングに活用する方法

月収10万元の起業の夢を実現するミニプログラム起業支援プランTik Tokといえば、現在最も人気のあ...

「Tencent Game Manager」を例に、ユーザーの成長についてお話ししましょう。

1. 市場背景市場の状況を考え、分析することで、自社製品の意義や価値を検証し、開発に適した成長ポイン...

インデックス700 Baiduには600万以上の単一記事のインデックスがあります。なぜ1位にランクできるのでしょうか?

今朝、「歯科インプラント」というキーワードで検索したところ、偶然、ある病院の記事が 1 件だけ検索結...

スタイリッシュなチームを結成

あなたのチームが他のチームよりも優れていると言うなら、その理由は何ですか?みんなが優れた専門能力を持...

【2016年最新版】モバイルインターネット業界の専門用語を完全網羅!

モバイルインターネットプロフェッショナルレベル4試験が始まりました〜 CPA、CPD、CPI、CPS...

インターネット大手の参入ゲームのグラデーションレイアウト

Baidu は 91 Wireless Assistant を 19 億ドルで買収しました。モバイル...

QingCloud が正式に発表: ジャカルタ パブリック クラウド ゾーンが正式にオープン

[元記事は51CTO.comより] 12月25日、 QingCloud副社長の林元氏はメディアに対し...