現在、シャーディングされたクラスターが稼働中であり、各レプリカセットのプライマリメンバーのメモリ使用量が8GBと非常に高いことに気付きました。
mongod --auth --bind_ip_all --shardsvr --replSet a --smallfiles --oplogSize 1024 --keyFile /file/somewhere/
(おそらく単純に)oplogSize
が使用するメモリの量を制限すると思った。
これを解決する方法、または私の方法のエラーを強調する方法に関するガイダンスは、高く評価されています。
oplog には 何もない メモリ消費とはほとんど関係ありません。 キャップされたコレクション は、操作が他のレプリカセットメンバーにレプリケートされる 先読みログ の一種として使用されます。
一般的に、MongoDBは特に指示がない限り、最大85%(ギブアンドテイク)のメモリを使用します。このメモリは、RAM=)のインデックスと "ワーキングセット"(最近使用したドキュメントのコピー)を保持して最適なパフォーマンスを確保するために使用されます。技術的に RAMを制限することができます。これは Very Bad Idea™これを行うと、MongoDBのパフォーマンスが大幅に制限され、RAMが不十分なためにスケールアウトまたはスケールアップするタイミングを検出できなくなります。
TL; DR:MongoDBで使用されるRAMを制限する方法を尋ねる必要がある場合は、この手順で発生する副作用を判断できないため、制限しないでください。
基本的に3つのオプションがあります: キャッシュサイズWiredTigers ストレージエンジンの場合は cgroups を使用してメモリを制限しますmongod
can OSから要求するか、Dockerを使用してそれを実行します(これにより少し簡単になりますが、内部ではDockerがcgroupを使用します。iirc)。
次のオプションを構成ファイルに追加します(YAML形式であると想定しています)。
storage:
wiredTiger:
engineConfig:
cacheSizeGB: <number>
ここで、<number>
はRAM MongoDBがWiredTigerのキャッシュにを使用することを許可されていますの最大量です。このパラメーターを操作すると、 severly はパフォーマンスに影響します(一方、MongoDBのメモリ消費量は常に制限されます)。これは、mongod
自体が使用するメモリを制限しないことにも注意してください(たとえば、それぞれ接続には小さなスタックが割り当てられます)。
mongod
の全体的なメモリ消費を制限するRootユーザーとして、最初にcgroupが有効になっていることを確認します。
$ lscgroup
cpuset:/
cpu:/
cpuacct:/
memory:/
devices:/
freezer:/
net_cls:/
blkio:/
Cgroupが使用可能であると想定して、MongoDBのメモリ消費のコントロールグループを/etc/cgconfig.conf
で構成できるようになりました。
group mongodb{
memory {
memory.limit_in_bytes = 512m;
}
}
その後、cgconfigサービスを再起動する必要があります。上記の設定を単純にコピーして貼り付けないでください。512MBを使用すると、MongoDBは(もしあれば)実行されます。 2GB以上のRAMを使用して、必要に応じてメモリ制限を調整します。
次に、作成したコントロールグループにmongod
を割り当てる必要があります。そのためには、/etc/cgrules.conf
を編集する必要があります。
*:mongod memory mongodb/
ここで、*
は、誰がmongod
を開始したかに関係なくこのルールが適用されることを示し、制限はコントロールグループmongod/
のルールに従ってRAMに適用されます。最後のステップとして、cgred
およびMongoDBサービスを再起動する必要があります。mongod
は、指定された量のRAMのみを使用する必要があります。
mongod
の全体的なメモリ消費を制限します。現在実行しているMongoDBのバージョンを特定する
$ mongod -version
db version v3.4.10
git version: 078f28920cb24de0dd479b5ea6c66c644f6326e9
OpenSSL version: OpenSSL 1.0.2n 7 Dec 2017
allocator: system
modules: none
build environment:
distarch: x86_64
target_Arch: x86_64
出力は異なる場合がありますが、db version
、つまりマイナーバージョンのみが必要です。この例では、「3.4」です。
適切なDockerイメージをプルする
$ docker pull mongo:3.4
以前に決定したバージョンのDockerイメージをプルし、プルしたイメージを次のステップで使用する必要があります。
適切なパラメーターを使用してDockerイメージを実行する
$ docker run -d --name mongod --memory=512m \
> --mount type=bind,src=/path/to/your/datafiles,dst=/data/db \
> --mount type=bind,src=/file/somewhere/,dst=/key.file,readonly
> mongod <yourOptions>
ここで注意すべき点:最初のmount
は既存のデータファイルにコンテナ内からアクセスできるようにし、2番目のmount
はキーファイルに対して同じことを行います。それに応じてmongodオプションを調整する必要があります。つまり、keyFile
オプションは、キーファイルをマウントした宛先を指すようにします。詳細は docker documentation および mongo docker imageのREADME を参照してください。
シャードされたクラスターがあり、個々のシャードメンバーのメモリ消費を制限したい。
本番システムの場合、これは Very Bad Idea™です。 mongod
sを実行しているマシンで実行されている他のサービス(高負荷の場合に2つのサービスがリソースを競合させる)、または(上記の方法を使用して)MongoDBが提供するパフォーマンスを人為的に制限します。これは悪いシステム設計です。なぜ最初から破片を作ったのですか?シャーディングは、MongoDBのロードバランシングとスケールアウトの方法です(RAMのような制限要因がこれ以上スケールアップできない場合は、費用に見合うだけの効果が得られないためです)。私は、お客様に繰り返し(そして正直に言えば自分にも)マントラを持っています。
本番データを保持するMongoDBインスタンスは、専用マシンで実行する必要があります。例外なく!
最初にシャーディングした理由とシャードの数によっては、専用のマシンでクラスターを実行した場合はシャーディングする必要がなかった可能性もあります。計算する。
また、クラスターノードで他のサービスを実行するのが良いアイデアであったとしても、それらは明らかにプロビジョニング不足です。 RAMのパフォーマンスが低下した場合と比較すると、基本的には、マシンをRAMに制限するのではなく、適切な量にスケールアップすることは簡単です。そもそも悪いシステム設計を人為的に強制する。
あなたへの私のアドバイスは、上記のアプローチのいずれにも従わないことです。代わりに、専用マシンでMongoDBインスタンスを含むデータを実行します。シャーディングする前に、バックRAMおよびIO-wise(CPUはめったに問題となることはめったにありません))に応じた強さを得る限り、それらをスケールアップします。この執筆時点では、 128GBと256GB RAMとRAID 0(レプリカセットがある場合は、持っていますよね)またはRAID 10(シャードがレプリカセットでない場合-恥ずかしいです;))SSDの場合。
hth
PS RAM for the mongod
s。
MongoDB BOLに従ってここ レプリカセットメンバーを初めて起動すると、MongoDBはデフォルトサイズのoplogを作成します。
UnixおよびWindowsシステムの場合
デフォルト oplog size
はストレージエンジンによって異なります。
Storage Engine Default Oplog Size Lower Bound Upper Bound
In-Memory Storage Engine 5% of physical memory 50 MB 50 GB
WiredTiger Storage Engine 5% of free disk space 990 MB 50 GB
MMAPv1 Storage Engine 5% of free disk space 990 MB 50 GB
64ビットmacOSシステムの場合
デフォルトのoplog
サイズは192 MB
ストレージエンジンに応じて、物理メモリまたは空きディスク領域のいずれか:
Storage Engine Default Oplog Size
In-Memory Storage Engine 192 MB of physical memory
WiredTiger Storage Engine 192 MB of free disk space
MMAPv1 Storage Engine 192 MB of free disk space
ほとんどの場合、デフォルトのoplog
サイズで十分です。たとえば、oplog
が空きディスク領域の5%であり、24 hours of operations
の場合、セカンダリは、古くなりすぎて複製を続行できなくなることなく、最大24時間、oplogからのエントリのコピーを停止できます。ただし、ほとんどのレプリカセットの操作ボリュームははるかに少なく、oplogs
はより多くの操作を保持できます。
注:New in version 3.6.
この手順では、 replSetResizeOplog コマンドを使用して、レプリカセットの各メンバーのoplogのサイズを変更します。 secondary メンバーで開始してから primary に進みます=。
重要:
replSetResizeOplog
を実行できるのは、Wired Tigerストレージエンジンで実行されているレプリカセットメンバーのみです。
レプリカセットメンバーに接続します
Mongoシェルを使用してレプリカセットメンバーに接続します。
mongo --Host <hostname>:<port>
注:レプリカセットが authentication を適用する場合、ローカルデータベースを変更する権限を持つユーザーとして認証する必要があります。 clusterManager または clusterAdmin role 。
oplogの現在のサイズを確認します
use local
db.oplog.rs.stats().maxSize
MaxSizeフィールドには、コレクションサイズがバイト単位で表示されます。
レプリカセットメンバーのoplogサイズを変更する
サイズを変更するには、 replSetResizeOplog を実行して、必要なサイズをメガバイト単位でサイズパラメータとして渡します。指定するサイズは、990または990メガバイトより大きくなければなりません。
次の操作は、レプリカセットメンバーのoplogサイズを16ギガバイト、つまり16000メガバイトに変更します。
db.adminCommand({replSetResizeOplog: 1, size: 16000})