いくつかのビジーなTomcatインスタンス、データベース、およびサポートサービスをホストするDebianLinuxで実行されている本番サーバーがあります。システムは数年間安定して動作していましたが、最近、速度が低下し、メモリの問題が発生したようです。
この間、Tomcatによってホストされるアプリケーションのサイズ、ユーザー、Tomcatインスタンスの数が増加しました。マシンのメモリ制限に対して実行を開始しているようです。
HtopやJava JMXなどのツールを使用して現在のメモリ要件を判断しようとしている)を使用してメモリ監視に慣れ始めました。JVM側で識別されるノブは、ヒープスペースの最大値と初期サイズを設定するためのスイッチです。 。メモリ監視パラメータは、仮想VIRTと予約済みメモリRESです。
私の問題は、ホストされているアプリケーションの最適化作業が成功するまでに時間がかかる可能性があるため、マシンに必要なメモリの量を見つけることです。
すべての仮想サイズを合計すると、物理RAMの倍数が得られますが、カーネルが一般的なライブラリコードのように同一の部分を処理する可能性があるため、おそらく適切な数ではありません。
すべての予約済みサイズを合計すると、実際のメモリ使用量に近くなり、共有メモリ使用量が少なくなります。ただし、これは動的プロセスの結果であり、カーネルやさまざまなアプリケーションによるメモリ割り当てや、さまざまなTomcatインスタンスの起動順序などが役割を果たす可能性があります。
二分試行錯誤のアプローチを開始する前に、RAMを増やし、より穏やかな水域に到達するまで結果のシステムパフォーマンスを測定する前に、より良いものを得る手段があるかもしれないと期待して、この質問を投稿しましたRAM要件の見積もり。
更新:
$ cat /proc/meminfo
MemTotal: 66075980 kB
MemFree: 2117304 kB
Buffers: 396328 kB
Cached: 9286764 kB
SwapCached: 794700 kB
Active: 53198584 kB
Inactive: 10075240 kB
Active(anon): 50010632 kB
Inactive(anon): 3587764 kB
Active(file): 3187952 kB
Inactive(file): 6487476 kB
Unevictable: 5604 kB
Mlocked: 5604 kB
SwapTotal: 4194300 kB
SwapFree: 324 kB
Dirty: 49460 kB
Writeback: 72 kB
AnonPages: 52802056 kB
Mapped: 89356 kB
Shmem: 4448 kB
Slab: 388132 kB
SReclaimable: 324892 kB
SUnreclaim: 63240 kB
KernelStack: 11360 kB
PageTables: 126924 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 37232288 kB
Committed_AS: 47441088 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 386700 kB
VmallocChunk: 34325801336 kB
HardwareCorrupted: 0 kB
AnonHugePages: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
DirectMap4k: 93868 kB
DirectMap2M: 8259584 kB
DirectMap1G: 58720256 kB
$
Asktyagiが述べたように、ホスト上で実行するアプリケーションが多すぎる可能性があります。一般に、単一のホストで多くのJVMを実行すると、メモリがそのうちの1つにすぎないリソースに対して、あらゆる種類の競合が発生する可能性があります。別の例として、CPU、ディスクIOなどを競合するGCスレッドがあります。
複数のTomcatプロセスを実行してスケールアップするとおっしゃいました。いくつのプロセスが適切なオプションであるかを実験することをお勧めします。このためには、別の負荷テスト環境がおそらく不可欠です。
プログラムに必要なメモリ量を確認するには、適切な監視が必要です。 VisualVmなどの基本的なプロファイラーを使用してローカルマシンで実験を開始し、GCの動作を観察し、さまざまな-Xmx設定を試すことができます。また、ワークロードとレイテンシー/スループット要件の重要性に応じて、さまざまなGCアルゴリズム(Shenandoahなど)を試してみることもできます。
クラスターでは、GCログをオンにし、おそらくJava Flight Recorderを介して低オーバーヘッドのプロファイリングを有効にする必要があります。後で、jClarityのCensumなどのツールを使用してGCログから洞察を得ることができます。
理解しておくべき重要なことは、現在のメモリ消費レベルを見て、アプリのメモリ要件を単に「推測」することはできないということです。JVMは、指定した量のメモリを消費しようとするため、10GBを消費する場合は必要ありません。それが必要だという意味です。たった1GBで十分満足できるかもしれません(GCの一時停止が短くなる可能性があるため、さらにパフォーマンスが向上します)。
補足として、オーバーコミット(OOMキラーによって明示される)は悪いことになる可能性があります( http://www.etalabs.net/overcommit.html を参照)、特にサーバーマシンの場合-あなたが望むかもしれませんスワップを完全に無効にします。
正直なところ、すべてのものを1つのボックスにまとめておくことはお勧めできません。また、ホストされているアプリケーションに依存するため、必要なメモリを正確に計算することは困難です。アプリケーションの前でLBを使用し、アプリケーションをさまざまな異なるホストでホストすることをお勧めします。
それでもメモリを計算する場合は、スレッド数とトラフィックレポートに基づいて、アプリケーションの履歴メモリトレンドを取得する必要があります。同じボックスでホストされている他のアプリケーションなど、他の要因にも依存します。
これがお役に立てば幸いです。