このダイヤルに触るべからず

ここで解説する設定は、定量化可能な性能問題に直面した時にのみ変更すべきです。個別のユースケースや負荷により、それぞれの設定パラメータがクラスタに与える影響は様々です。とはいえ、デフォルト設定は注意深く、かつ保守的に選択されています。

JVMヒープサイズ

デフォルトではCassandraの起動スクリプトはJVMの最大ヒープサイズを1GBに設定しています。これを増やすことを検討してください:但し徐々にです! Cassandraや他のプロセスが過剰にメモリを使用すると、OSのファイルバッファやキャッシュが縮小します。 これらはCassandraの性能上、内部データ構造と同じくらい重要です。

JVMの最大ヒープを過大に設定することは過小に設定するよりもリスクが高まります。過小な設定はJMXで容易に診断できますが、過大な設定が問題の原因であることを特定するのは困難だからです。

RAMを48GB載せたハイエンドマシンでも、JVMの最大ヒープサイズの設定初期値は4GBから始めるのが適当でしょう。OSは貴方が考えるより頭がいいものです。 大まかには、Cassandraの内部データ構造が必要とするメモリサイズは次の数式で求められます。 memtable_throughput_in_mb * 3 * number of hot CFs + 1G + internal caches

また負荷がかかった状態でヒープサイズの上限に達した場合でも、それは真の問題から派生する症状である可能性もあります。はじめによく原因を分析してください。

仮想メモリとスワップ

Cassandra専用マシンでは、全くスワップを持たないのが最適なスワップ設定です。CassandraのJavaプロセスでスワップアウトが起こるとOSによってkillされることになりますが、ホスト全体がスラッシングでアクセス不能になるよりましです。 Linuxユーザはswappiness, overcommit_memory, overcommit_ratioパラメータについて完全に理解し、検討すべきです。

Memtableの閾値

write操作を実行すると、CassandraはデータをMemtablesと呼ばれる、カラムファミリ固有のメモリ内データ構造に格納します。Memtablesは設定可能ないくつかの閾値のいずれかを超えた時点でディスクにフラッシュされます。 初期設定値(64mb/0.3)は意図的に保守的です。メモリ不足によるノード停止を避けるためにはデータを、これらのパラメータを適切にチューニングすることが重要です。

閾値の設定

大きなMemtableはキャッシュに使用できるメモリを減らす:Memtableは実カラムの値を格納するため、少なくとも挿入されるデータと同じサイズのメモリを消費します。実際にはこのデータのインデックスを作成するためのデータ構造のオーバーヘッド分も必要です。値のサイズに比べてカラムや行の数が多い場合、インデックスのオーバーヘッドが無視できなくなるかもしれません。データそのものよりも大きくなることもあり得ます。

言い換えると、どの閾値にどのような値を設定するかは、あなたが使用できるメモリ量から単純な関数では導出できず、カラムファミリの数、カラムファミリごとのカラムの数、ソートされる値のサイズを考慮する必要があります。

Membtableを大きくしてもwrite性能は向上しない:memtableのサイズを大きくするとディスクへのフラッシュ頻度を下げることができますが、write性能の向上には直接には貢献しません。memtableのサイズに依らず、writeされたデータは直接メモリに格納されます。(もしcommitlogとsstableが同じボリュームを共有していたらmemtableの大きさがwriteに影響を与えます。従って、可能であればそれらは別のボリュームに配置すべきです。)

Memtableを大きくすると、より上書きを吸収する:あなたのシステムのwrite負荷が少数の行を頻繁にアクセスする場合(例:Webの記事に対する投票など)、大きなmemtableはより多くの書き換え操作を吸収できるため、sstableがより効率的に生成され、read性能の向上に寄与します。write負荷がバッチ中心であるか、もしくはデータセットが非常に多くの行を含んでいる場合、ほとんどの行はあまり更新されないため、この効果はあまり期待できません。

Memtableを大きくするとcompactionが効率的になる: compactionは階層化されているため、sstableは大きい方が望ましいと言えます。即ち、多数の小さなmemtableは好ましくありません。これもread性能の向上に寄与しますが、writeには影響しません。

以下にstorage-conf.xml(0.7以降ではcassandra.yaml)に現れる閾値と、その解説を示します。

MemtableThroughputInMB

名前が示すように、このパラメータはMemtableのディスクへのフラッシュが発生するまでに格納できる最大のデータ量をMB単位で指定します。 これは挿入される値のサイズとその値を含むカラムのサイズに相当します。

この値が設定されていない場合、デフォルト値は128MBです。

注意: このパラメータはversion 0.6.0以前ではMemtableSizeInMBと呼ばれていました。version 0.7b2以上では設定はカラムファミリ単位に適用されますCASSANDRA-1007

MemtableOperationsInMillions

このパラメータは格納されるカラムの数に関する閾値を設定します。

設定されていない場合、デフォルト値は0.1(100,000オブジェクト)です。設定ファイルの初期値は0.3(300,000オブジェクト)であり、控えめな値と言っていいでしょう。

注意: このパラメータはversion 0.6.0以前ではMemtableObjectCountInMillionsと呼ばれていました。version 0.7b2以上では設定はカラムファミリ単位に適用されますCASSANDRA-1007

JConsoleを使用した閾値の最適化

CassandraのColumnFamily MBeanはいくつもの属性を持っています。それらは最適な閾値を決定するための貴重な情報です。この機能にアクセスするひとつの方法はJConsoleを使用することです。JConsoleはグラフィカルなモニタリングと管理のためのアプリケーションで、JDKに含まれています。

JConsoleを引数なしで起動すると、"New Connection"ダイアログボックスが表示されます。JConsoleをCassandraが起動しているマシンと同じマシンで起動した場合、PIDを用いて接続することができます。その他の場合、リモートに接続する必要があります。デフォルトのCassandra起動スクリプトは以下のJVMオプションで、JavaVMにポート8080で受け付けるように設定します。

この場合、リモート接続用のJMX URLは以下のようになります。

これは次のツールで内部的に使用されています: bin/nodetool src/java/org/apache/cassandra/tools/nodetool.java

jconsole_connect.png

接続してMBeansタブを選択し、org.apache.cassandra.dbセクションを展開すると、定義したColumnFamilyが見えるはずです。

ここには3つの注目すべき属性があります。

  1. MemtableColumnsCount このテーブルのカラムの総数を表します。100個のカラムを持つ100行のデータを保持すると、この値は10,000になります。この属性はMemtableObjectCountInMillionsの閾値を設定するのに役立ちます。

  2. MemtableDataSize 保存されているデータのトータルサイズを決定します。これはすべての保存されている値の和で、Memtableのオーバーヘッドは計上していません。(つまり、Memtableが実際にどれだけメモリを使用しているかは示しません。) MemtableThroughputInMBの値を調整するときに利用してください。

  3. MemtableSwitchCount ColumnFamilyがMemtableをディスクにフラッシュした際にインクリメントされます。

注意: 表示している値を更新するにはRefreshボタンを押す必要があります。

jconsole_attributes.png

forceFlush()を使用して、即時フラッシュをスケジュールすることも可能です。

jconsole_operations.png

stats

MemtableThresholds_JP (last edited 2013-11-14 22:28:22 by GehrigKunz)