@oranie さんのブログ記事への返信です。 たいへん遅くなりました。申し訳ないです。
repairとcompactionのコストが高すぎる
Cassandraにノードを追加する(Bootstrap)と、そのノードが担当するレプリカのデータを他のノードから取得します。 Repairはノードが保持するレプリカの整合性を検証して修復します。
どちらもデータを他のノードから取得しますが、ファイルを1つづつやり取りするため時間がかかるのは事実です。 この部分にまだまだ改善の余地があります。次のメジャーバージョンで抜本的に見直します。
ファイルのストリーミングはデフォルトで400Mbit/secに制限されています。帯域に余裕があれば設定(cassandra.yaml
の stream_throughput_outbound_megabits_per_sec
)を変更しても良いかもしれません。
単位はMBit/sec、 0で制限なしです。
1.2から導入されたVirtual Nodeを使うとBootstrapが早くなるようです。が、Repairがまだうまく対応していません。
removeも重い
先に新しいノードを追加できます。新しいノードを追加する時に、置き換えるノードのトークン-1で新しいノードを立ち上げます。 新しいノードが起動したら、壊れたノードのトークンをremoveすれば時間がかかりません(故障したノードのトークン範囲は実質0になるため)。
参考: http://www.datastax.com/docs/1.1/operations/cluster_management#replacing-a-dead-node
ノード追加分の性能向上や負荷分散はノードが増えるほどコストが高くなる
ノードを追加する場合は5台から10台、10台から20台と倍に増やすときが一番コストがかかりません。 既存のノードはトークンをいじる必要はないので、データの受け渡しが少なくて済みます。 ただし、この場合も新しいノードは1台ずつ起動します。 クラスタ拡張時にrepairは必要ではないです。
既存のクラスタに任意にノードを追加していく運用であれば、元記事にあるように時間がかかります。
参考: http://www.datastax.com/docs/1.1/cluster_management#adding-capacity-to-an-existing-cluster
nodetool repairについて prをつけた場合first rangeとのみ同期するrepair処理になるようだけど、イマイチ使いドコロが分かっていない。
-pr
の動作はその通りです。 -pr
はクラスタ内のすべてのノードに対して順次repairを実行する場合に使います。
Cassandraは運用の一環として、データの不整合を解消するため、定期的にrepairを実行することを推奨しています。
-pr
を付けない場合、レプリカを含めノードが持つすべてのトークン範囲に対してrepairが実行されますが、
クラスタ内のすべてのノードに対して順次repairを実行する場合は、クラスタ内の重複するトークン範囲を複数回repairすることになります。
JVMで動作するアプリ、という点を理解しないといけない
これはその通りですね。。。最近のCassandraでは、極力GCの影響を受けないよう、Bloom Filterやキャッシュなどをヒープ外に自前で管理するようにしています。 ヒープサイズの推奨最大値は8GBから多くてもせいぜい12GBです。それ以上になるとGC時にひどい目をみます。
ちなみにCassandraは定期的にMemtableの容量を監視しており、定期的に大きいMemtableをSSTableに書き出しています。 ログファイルに以下のように出力されている部分がそうです。
WARN [ScheduledTasks:1] 2013-02-08 19:53:38,442 GCInspector.java (line 145) Heap is 0.779908773550403 full. You may need to reduce memtable and/or cache sizes. Cassandra will now flush up to the two largest memtables to free up memory. Adjust flush_largest_memtables_at threshold in cassandra.yaml if you don't want Cassandra to do this automatically
WARN [ScheduledTasks:1] 2013-02-08 19:53:38,448 StorageService.java (line 2855) Flushing CFS(Keyspace='Foo', ColumnFamily='Bar') to relieve memory pressure
また、GCにかかっている時間も定期的に監視しています。
INFO [ScheduledTasks:1] 2013-02-08 22:00:52,636 GCInspector.java (line 122) GC for ParNew: 217 ms for 1 collections, 7112824896 used; max is 10611589120
特にCassandraが利用しているGC方式であるConcurrentMarkSweepに時間がかかっていることを検出すると、上記のMemtableの強制フラッシュを行ったりします。
すみません、だいぶ遅くなった追加の質問なのですが、
「1.2から導入されたVirtual Nodeを使うとBootstrapが早くなるようです。が、Repairがまだうまく対応していません。」
このrepairが上手く動かないというのはJIRAに既に上がっていますでしょうか?
ちょっと1.2系の運用も検討していて、repairの問題について把握したいと思いまして・・・。