2010-04-14

[翻訳]rediscookbook/2_basic_commands/pipeline_multiple_commands

### 問題

単一のアトミックコマンドを使って、いくつかの Redis コマンドを実行したい。

### 解法

コマンドのキューを作成し、それらをアトミックに実行するには MULTI/EXEC コマンドを使います。
キューの開始には `MULTI` コマンドを使います。Redis は `OK` を返します。
それから各コマンドのキューを作ってください。最終的には、`EXEC` を使用してコマンドを実行します。
Redis は各コマンド毎にか返値と一緒に multi-bulk を返します。
この基本的な例で、3つの値をリストに追加し、'country-count' と呼ばれるキーを(3に)増加させ、
それからリストのすべての値の範囲を求めます。

必要なら、MULTI キュー と既存のキューをクリアするために DISCARD コマンドを使うことができます。

    redis> MULTI
    OK
    redis> LPUSH country_list france
    QUEUED
    redis> LPUSH country_list italy
    QUEUED
    redis> LPUSH country_list germany
    QUEUED
    redis> INCRBY country_count 3
    QUEUED
    redis> LRANGE country_list 0 -1
    QUEUED
    redis> EXEC
    1. (integer) 1
    2. (integer) 2
    3. (integer) 3
    4. (integer) 3
    5.
     1. germany
     2. italy
     3. france
   

### 検討

MULTI/EXEC (Redis 2.0 で追加予定)は Redis の非常に重要なコンポーネントで、多く語るに値します。
これが何をするのか、そして何をしないのか知ることはとても重要です。

M/E は次に述べるような意味で、「アトミック」です。
キューが実行されている間、他のクライアントが全く Redis サーバにアクセスできません
-- このキューは単一操作として扱われます。これはデータの完全性にとって重要です。

M/E プロセスは、コマンドがキューに追加されるときはいつでも、
構文エラーがあるとすぐに構文エラーを報告しながら実行するよう設計されています。例えば:

    redis> MULTI
    OK
    redis> LPUSH country_list italy
    QUEUED
    redis> LPUSH country_list italy germany
    Wrong number of arguments for 'lpush'


さて、 M/E は完全な「トランザクション」を提供 *しません*
-- 少なくとも常識的な意味では。-- 「ロールバック」の機能を含んでいないからです。
以下のような状況を考えてください。
比較的大きな M/E キュー(例えば、200個のコマンド)を作成して、EXEC を実行します。
すべての溜め込まれたコマンドが実行される前に、
(おそらくメモリを使い果たして)コマンド #148 でサーバがクラッシュしたとしましょう。
はじめの 148 個のコマンドは本当に実行されますが、残りは実行されません。

実際は、M/E では、EXEC コマンドが実行される *前* (つまり、溜め込み中)は 'すべてか無しか' 操作だけなのです。
-- 実行中はそうではありません。

Redis は問題に対処する興味深い方法を提供します。:馴染み深い追加のみファイルです。
Redis の次バージョンでは、キューのコマンド群は EXEC コマンドが完全に成功したときに AOF に書かれるだけです。
このため、万一サーバが中途半端な EXEC 状態でクラッシュしても、前の pre-EXEC 状態に従って状態を再構築できます。


### 参照

0 件のコメント:

コメントを投稿