BATCH

複数のDML文を書き込みます。

複数のDML文を書き込みます。

構文

Cassandra 2.1以降。UNLOGGEDオプションはCassandra 3.0から廃止されていることに注意してください。

BEGIN UNLOGGED  BATCH USING TIMESTAMP timestamp dml_statement; dml_statement; ...APPLY BATCH;

Cassandra 2.0.x

BEGIN( UNLOGGED | COUNTER)BATCH USING TIMESTAMP timestamp dml_statement; dml_statement; ...APPLY BATCH;

dml_statementは以下のとおりです。

  • INSERT
  • UPDATE
  • DELETE

構文の凡例

  • 大文字はリテラルを意味する
  • 小文字は、リテラルでないことを意味する
  • イタリック体は指定が任意であることを意味する
  • パイプ(|)記号はORまたはAND/ORを意味する
  • 省略記号(...)は繰り返し可能を意味する
  • 範囲記号「(」および「)」はリテラルではなく、範囲を示す

この構文には、CQL文の終了となるセミコロンは含まれていません。

説明

BATCH文は、複数のデータ操作言語(DML)文(INSERT、UPDATE、DELETE)を1つの論理演算にまとめた上で、各文によって書き込まれたすべてのカラムに対しクライアント指定タイムスタンプを一括して設定します。複数の文をバッチ化することで、クライアント/サーバーとサーバー・コーディネーター/レプリカ間のネットワーク交換を削減できます。Cassandraは要求をできる限り近くのノードに分散させて、パフォーマンスを最適化します。バッチ文のワークロードは不均等になり、多くのノードにアクセスするか、1つのノードに繰り返しアクセスする場合があります。

バッチの使用と誤使用」のトピックで説明されているように、パフォーマンスを最適化することを目的としてバッチを使用しても、通常は成功しません。代わりに、バッチを使用してデータをテーブルに同期化する方が合理的な操作を実現できます。データを読み込む最も速い方法については、「Cassandra: Batch loading without the Batch keyword」(英語)を参照してください。

バッチは、デフォルトではログに記録されます。Cassandraバッチ処理の場合、ログに記録されたバッチとは、バッチの一部が成功すれば、バッチ全体が成功することを意味します。これを実現するために、Cassandraは、まず、シリアライズされたバッチを、そのバッチをBLOBデータとして消費するバッチログ・システム・テーブルに書き込みます。バッチ内の各行が正しく書き込まれ、継続性が維持(ヒント)されたときにバッチログ・データが削除されます。バッチログの操作にはパフォーマンスの低下が伴います。この操作では、他の2つのノードへの書き込みが行われるためです。このペナルティを発生させたくない場合は、Cassandraがバッチログ・システムに書き込まないように、UNLOGGEDキーワードを使用します。
注: UNLOGGED BATCHはCassandra 3.0では廃止されています。

ログに記録されたバッチは、バッチの一部が成功するとバッチ全体が成功することを保証しますが、その他のトランザクション制御はバッチ・レベルで実行しません。たとえば、バッチ隔離は行いません。クライアントは、サーバーで他の行がまだ更新中であっても、バッチによって最初に更新された行を読み取ることができます。ただし、パーティション・キー内でのトランザクショナルな行更新は隔離されているので、クライアントは、部分的な更新を読み取ることはできません。

バッチ内の文の順序は関係ありません。Cassandraは、同じタイムスタンプをすべての行に適用します。特定の順序で実行するには、クライアント指定タイムスタンプを使用する必要があります。

タイムスタンプの使用

BATCH文では、1つの例外を除いて、USING句にクライアント指定タイムスタンプ(整数)を設定できます。バッチ内のDML文に、以下のような比較して設定する(compare-and-set:CAS)文が含まれている場合は、タイムスタンプを使用しないでください。

cqlsh> INSERT INTO users (id, lastname) VALUES (999, 'Sparrow') IF NOT EXISTS

タイムスタンプは、バッチ内のすべての文に適用されます。指定しないと、挿入時の時刻(単位はマイクロ秒)が使用されます。USING句を使用してタイムスタンプを指定しない場合は、BATCH文内の個々のDML文にタイムスタンプを指定できます。

たとえば、INSERT文にタイムスタンプを指定します。

cqlsh> BEGIN BATCH INSERT INTO purchases (user, balance) VALUES ('user1', -8) USING TIMESTAMP 19998889022757000; INSERT INTO purchases (user, expense_id, amount, description, paid) VALUES ('user1', 1, 8, 'burrito', false); APPLY BATCH;
balanceカラムにクライアント指定タイムスタンプが入っていることを確認します。
cqlsh> SELECT balance, WRITETIME(balance) FROM PURCHASES;
balance | writetime_balance ---------+------------------- -8 | 19998889022757000

条件付き更新のバッチ処理

Cassandra 2.0.6以降では、Cassandra 2.0で軽量トランザクションとして導入された条件付き更新をバッチ処理できます。基礎となっているPaxos実装は、パーティションの細分性で動作するので、バッチに含めることができるのは、同じパーティションへの更新のみです。条件付き更新と無条件更新を1つのグループにまとめることはできますが、バッチ内に1つでも条件付き更新の文があれば、バッチ内のすべての条件が適用されるかのように、バッチ全体が1つのPaxosプロポーザルを使用してコミットされます。以下の例では、条件付き更新のバッチ処理を示します。

購入レコードに値を挿入するための文でIF条件句を使用しています。

cqlsh> BEGIN BATCH INSERT INTO purchases (user, balance) VALUES ('user1', -8) IF NOT EXISTS; INSERT INTO purchases (user, expense_id, amount, description, paid) VALUES ('user1', 1, 8, 'burrito', false); APPLY BATCH; cqlsh> BEGIN BATCH UPDATE purchases SET balance = -208 WHERE user='user1' IF balance = -8; INSERT INTO purchases (user, expense_id, amount, description, paid) VALUES ('user1', 2, 200, 'hotel room', false); APPLY BATCH;

この例の続きに、バッチ内で静的(STATIC)カラムを条件付き更新と一緒に使用する方法が示されています。

カウンター更新のバッチ処理

Cassandra 2.1以降では、カウンターのバッチにUNLOGGEDを使用する必要があります。カウンター更新は、Cassandraの他の書き込みとは異なりべき等演算ではないためです。

Cassandra 2.0では、バッチ方式カウンター更新のために、バッチ文にBEGIN COUNTER BATCHを使用します。

Cassandra 2.1の例

cqlsh> BEGIN UNLOGGED BATCH UPDATE UserActionCounts SET total = total + 2 WHERE keyalias = 523; UPDATE AdminActionCounts SET total = total + 2 WHERE keyalias = 701; APPLY BATCH;

Cassandra 2.0の例

cqlsh> BEGIN COUNTER BATCH UPDATE UserActionCounts SET total = total + 2 WHERE keyalias = 523; UPDATE AdminActionCounts SET total = total + 2 WHERE keyalias = 701; APPLY BATCH;