AWS に 9 ノードのクラスターがあります。最近、いくつかのノードがダウンしたため、再起動後にクラスターを修復したいと考えています。しかし、修復操作によって大量の memtable フラッシュが発生し、JVM GC が失敗することがわかりました。その結果、ノードがハングします。
Cassandra 3.1.0 を使用しています。
java version "1.8.0_231"
Java(TM) SE Runtime Environment (build 1.8.0_231-b32)
Java HotSpot(TM) 64-Bit Server VM (build 25.231-b32, mixed mode)
ノード ハードウェアは 32GB メモリと 4 コア CPU です。ヒープは16GBです。ノードごとに、約 200 GB の sstables。
JVM のハングは非常に高速です。修復プロセスが開始されると、すべてが機能します。メモリ、CPU、IOをチェックしました。ストレスは見つかりませんでした。ランダムな時間 (ストリーミング タスクが完了している) の後、memtableflushwriter 保留中のタスクが非常に速く増加し、GC が失敗しました。JVM がハングし、ヒープダンプが作成されました。問題が発生したとき、CPU の使用率が低く、AWS EBS ディスク メトリクスで I/O レイテンシーを見つけることができませんでした。
ヒープダンプファイルを確認しました。テーブル修復の大きな memtables オブジェクトがいくつかあります。memtable オブジェクトのサイズは約 400 ~ 700MB です。memtables は 20 秒で作成されます。さらに、12000以上のmemtablesを見ることができます。これらの memtable には、6000 個の sstable_activity memtable があります。
最初は、memtable フラッシュ ライターがボトルネックになっているのではないかと思います。だから私はそれを4スレッドに増やします。そして、ノードのメモリを2倍にします。しかし、うまくいきません。修復中に、保留中のタスクが急速に増加し、ノードが再びハングします。また、修復トークンの範囲を 1 つだけ vnode に減らしましたが、それでも失敗しました。
このようなログがいくつか表示されます
WARN [STREAM-IN-/10.0.113.12:7000] 2020-04-02 05:05:57,150 BigTableWriter.java:211 - Writing large partition ....
書き込み sstables には 300 ~ 500 MB があります。いくつかの大きなものは 2+ GB に達します。
Cassandra のソース コードを確認します。また、テーブルにマテリアライズド ビューがある場合、通常の書き込みプロセスで sstables を処理する必要があることがわかりました。したがって、問題はストリーミングの COMPLETE 段階で発生すると思われます。
ストリーミング後、受信コールバック関数は更新されたパーティション sstables をロードし、通常の書き込みとしてミューテーションを作成します。したがって、ヒープ内の memtables が増加します。さらに、修復されたテーブル以外に追加の memtables を作成する flush() も呼び出します。memtables のサイズがクリーンアップのしきい値を超えています。したがって、フラッシュが呼び出されます。しかし、フラッシュでは十分なメモリを解放できません。何度もフラッシュが呼び出されました。一方、フラッシュは memtables も増やします。
誰でも同じ問題に遭遇しますか?私の結論が正しい場合、それを修正する方法は?