web-dev-qa-db-ja.com

プロメテウスはなぜそんなに多くのメモリを消費するのですか?

ノードの大規模な環境を監視するためにPrometheus 2.9.2を使用しています。私たちの環境でPrometheusの最大スケールをテストする一環として、私はテスト環境で大量のメトリックをシミュレートしました。

管理サーバーには16 GBのRAMと100 GBのディスク領域があります。

スケールテスト中に、プロセスがクラッシュするまで、Prometheusプロセスがますます多くのメモリを消費することに気付きました。

Prometheusのメモリ使用量が増加する一方で、WALディレクトリが多くのデータファイルで急速にいっぱいになっていることに気づきました。

管理サーバーは15秒ごとにノードをスクレイピングし、ストレージパラメーターはすべてデフォルトに設定されます。

これが発生する理由と、プロセスのクラッシュを防ぐことができるかどうか、またその方法が知りたいのですが。

ありがとうございました!

3
Thomason

メモリ不足によるクラッシュは通常、クエリが非常に重いために発生します。これは、ルールの1つで設定できます。 (このルールは、プロメテウス自体ではなく、グラファナのページで実行されている場合もあります)

非常に多数のメトリックがある場合、ルールがそれらすべてをクエリしている可能性があります。迅速な修正は、正規表現ではなく特定のラベルでクエリする指標を正確に指定することです。

1
Sutirtha Das

ラベルの組み合わせはビジネスに依存しているため、組み合わせとブロックは無制限である可能性があるため、プロメテウスの現在のデザインのメモリの問題を解決する方法はありません!!!!ただし、小さなブロックを大きなブロックに圧縮することをお勧めします。これにより、ブロックの数が減ります。

2つの理由による大量のメモリ消費:

  1. prometheus tsdbには「head」という名前のメモリブロックがあります。headはすべてのシリーズを最新の時間に保存するため、大量のメモリを消費します。
  2. ディスク上の各ブロックはメモリも消費します。ディスク上の各ブロックはメモリ内にインデックスリーダーを持っているため、残念なことに、ブロックのすべてのラベル、投稿、シンボルがインデックスリーダーの構造体にキャッシュされ、ディスク上のブロックが多いほど、より多くのメモリが消費されます。 。

index/index.goには、次のように表示されます。

type Reader struct {
    b ByteSlice

    // Close that releases the underlying resources of the byte slice.
    c io.Closer

    // Cached hashmaps of section offsets.
    labels map[string]uint64
    // LabelName to LabelValue to offset map.
    postings map[string]map[string]uint64
    // Cache of read symbols. Strings that are returned when reading from the
    // block are always backed by true strings held in here rather than
    // strings that are backed by byte slices from the mmap'd index file. This
    // prevents memory faults when applications work with read symbols after
    // the block has been unmapped. The older format has sparse indexes so a map
    // must be used, but the new format is not so we can use a slice.
    symbolsV1        map[uint32]string
    symbolsV2        []string
    symbolsTableSize uint64

    dec *Decoder

    version int
}
0
chausat