Buffer テーブルエンジン
書き込み対象のデータを RAM 上でバッファリングし、定期的に別のテーブルへフラッシュします。読み取り時には、バッファとその別のテーブルの両方から同時にデータを読み取ります。
Buffer テーブルエンジンの代替として推奨されるのは、非同期インサート を有効化することです。
エンジンパラメータ
database
database – データベース名。currentDatabase() もしくは文字列を返す他の定数式を使用できます。
table
table – データをフラッシュする対象のテーブル。
num_layers
num_layers – 並列レイヤー数。物理的には、テーブルは互いに独立したバッファが num_layers 個ある形で表現されます。
min_time, max_time, min_rows, max_rows, min_bytes, および max_bytes
バッファからデータをフラッシュするための条件。
オプションのエンジンパラメータ
flush_time, flush_rows, および flush_bytes
バックグラウンドでバッファからデータをフラッシュするための条件 (省略または 0 の場合は、flush* パラメータは存在しないものとして扱われます) 。
すべての min* 条件が満たされるか、少なくとも 1 つの max* 条件が満たされた場合、データはバッファからフラッシュされ、宛先テーブルに書き込まれます。
また、少なくとも 1 つの flush* 条件が満たされると、バックグラウンドでフラッシュが開始されます。これは max* とは異なり、flush* によって、Buffer テーブルへの INSERT クエリにレイテンシを追加しないように、バックグラウンドフラッシュを個別に構成できます。
min_time, max_time, および flush_time
最初の書き込み時点からの経過時間 (秒) に関する条件。
min_rows, max_rows, および flush_rows
バッファ内の行数に関する条件。
min_bytes、max_bytes、flush_bytes
バッファ内のバイト数に対する条件です。
書き込み中、データは 1 つ以上のランダムなバッファ (num_layers で設定) に挿入されます。あるいは、挿入するデータパーツが十分に大きい場合 (max_rows または max_bytes を超える場合) は、バッファを介さずに宛先テーブルへ直接書き込まれます。
データをフラッシュする条件は、num_layers 個の各バッファごとに個別に計算されます。たとえば、num_layers = 16 かつ max_bytes = 100000000 の場合、RAM の最大消費量は 1.6 GB です。
例:
merge.hits と同じ構造を持ち、Buffer エンジンを使用する merge.hits_buffer テーブルを作成します。このテーブルに書き込むと、データは RAM にバッファされ、後で 'merge.hits' テーブルに書き込まれます。単一のバッファが作成され、次のいずれかの条件を満たすとデータがフラッシュされます。
- 前回のフラッシュから 100 秒が経過した場合 (
max_time) または - 100 万行が書き込まれた場合 (
max_rows) または - 100 MB のデータが書き込まれた場合 (
max_bytes) または - 10 秒が経過し (
min_time) 、かつ 10,000 行 (min_rows) および 10 MB (min_bytes) のデータが書き込まれた場合
たとえば、1 行しか書き込まれていない場合でも、100 秒後には必ずフラッシュされます。一方、多数の行が書き込まれている場合は、より早くデータがフラッシュされます。
サーバーが停止するときは、DROP TABLE または DETACH TABLE の場合も含めて、バッファされたデータも宛先テーブルにフラッシュされます。
データベース名とテーブル名には、シングルクォーテーションで囲んだ空文字列を設定できます。これは宛先テーブルがないことを示します。この場合、データのフラッシュ条件に達すると、バッファは単に消去されます。これは、メモリ内に一定範囲のデータを保持する用途で役立つことがあります。
Buffer テーブルから読み取る場合、データはバッファと宛先テーブル (存在する場合) の両方から処理されます。 なお、Buffer テーブルはインデックスをサポートしません。つまり、バッファ内のデータはフルスキャンされるため、大きなバッファでは低速になる可能性があります (下位テーブル内のデータについては、そのテーブルがサポートするインデックスが使用されます) 。
Buffer テーブル内のカラム集合が下位テーブルのカラム集合と一致しない場合、両方のテーブルに共通するカラムのみが挿入されます。
Buffer テーブルと下位テーブルのいずれかのカラムで型が一致しない場合、エラーメッセージがサーバーログに出力され、バッファは消去されます。 バッファがフラッシュされる時点で下位テーブルが存在しない場合も同様です。
サーバーが異常終了した場合、バッファ内のデータは失われます。
FINAL と SAMPLE は Buffer テーブルでは正しく動作しません。これらの条件は宛先テーブルには渡されますが、バッファ内のデータ処理には使用されません。これらの機能が必要な場合は、Buffer テーブルは書き込み専用とし、読み取りは宛先テーブルからのみ行うことを推奨します。
Buffer テーブルにデータを追加する際は、バッファの 1 つがロックされます。そのため、同時にテーブルから読み取り操作が行われていると遅延が発生します。
Buffer テーブルに挿入されたデータは、下位テーブル内では異なる順序や異なるブロックに配置される場合があります。このため、Buffer テーブルを CollapsingMergeTree への正しい書き込みに用いるのは困難です。問題を避けるには、num_layers を 1 に設定できます。
宛先テーブルがレプリケートされている場合、Buffer テーブルに書き込むと、レプリケートされたテーブルに期待される特性の一部が失われます。行の順序やデータパーツのサイズがランダムに変化することで、データ重複排除が機能しなくなり、レプリケートされたテーブルに対して信頼できる「厳密に一度だけ」の書き込みを行うことが不可能になります。
これらの欠点により、Buffer テーブルの使用はごく限られたケースにのみ推奨されます。
Buffer テーブルは、単位時間あたりに多数のサーバーから大量の INSERT が送信され、挿入前にデータをバッファリングできないために INSERT が十分な速度で実行できない場合に使用されます。
なお、Buffer テーブルであっても、1 行ずつデータを挿入することには意味がありません。この方法では、スループットは毎秒数千行程度にとどまり、より大きなブロック単位でデータを挿入することで、毎秒 100 万行を超えるスループットを得ることができます。