FrontPage  Index  Search  Changes  RSS  Login

[KVS][Redis] Redis 概要

概要

Key-Value Store の Redis について、公式サイトの README を参考に概要をつかむためのメモ(ほぼ、簡易な訳のみ)。

特徴

README に入る前に、プロジェクトサイトのトップページに書かれている特徴から、いくつか抜粋。

  • Posix システム向けに ANCI-C で書かれている
  • 対応言語
    • Ruby
      • (+) Rack::Session と Rack::Cache を Redis に対応させたものもある
      • (+) DataMapper の Redis 用アダプタがある
    • Python
    • Twisted Python
    • PHP
    • Erlang
    • Tcl
    • Perl
    • Lua
    • JAVA
    • Scala
    • Clojure

導入

  • Redis はデータベース
  • Redis はキーと値のペアからなる辞書を実装した非常にシンプルなデータベース
  • Redis は単一の型の値しか持てない多くの Key-Value Store と異なり、以下の型をサポートしている
    • String
    • List
    • Set
    • Sorted Set (Version 1.1 以降)
  • 値の型によって、値自身についてどんな操作(コマンドと呼ぶ)ができるかが決まる
    • 例えば、List 型の値に対しては、LPUSH コマンドか RPUSH コマンドを利用して O(1) で値を追加する事ができる
    • 要素の範囲を得るには LRANGE コマンド
    • リストをトリムするには LTRIM コマンド
    • Set 型も非常に柔軟で、Set 型の値(String 型の値の順序なし集合)に要素を追加したり削除したりできる
      • また、サーバに問い合わせて、他の Set 型の値と結合させる事もできる
  • 各コマンドは、サーバサイドのアトミック操作として処理される
  • 完全なコマンドの一覧は CommandReference - redis - Project Hosting on Google Code
  • 見方を変えると、Redis はデータ構造サーバとも言える
  • Redis の利用者は、具象データ構造の実装とアルゴリズムに対する責務から守る抽象データ型へのインターフェースを仮想的に提供される(TODO: よくわからない)
    • 原文: A Redis user is virtually provided with an interface to Abstract Data Types, saving her from the responsibility to implement concrete data structures and algorithms.
  • 実際、Redis におけるアルゴリズムとデータ構造の両方は、ベストパフォーマンスを得られる手段を、適切に選択する
  • Redis は全てのデータをメモリ上に読み込み管理するが、時々 Redis は非同期にディスクに書き込んでデータセットを永続化する
    • サーバを(再)起動する度に、データセットはダンプデータから読み込まれる
  • Redis はデータセットをいつ保存するかを設定できる
    • 何回変更したか
    • 何秒経過したか
    • 例えば、1000 回変更した時と、前回の保存から 60 秒が経過した時、など
  • データ書き込みは非同期なため、クラッシュした場合は、最後のいくらかのデータは失われる
    • 大抵のアプリケーションで、これは受け入れられる問題
    • これが問題であれば、master-slave レプリケーションをサポートしているので、これを使えば問題にならないはず

Kye-Value データベース

  • 先述の全ての特徴から、スケーラブルなアプリケーションのために単独の DB として Redis を使えば、いかなるリレーショナルデータベースも必要なくなる

Redis と Memcached の違い

  • Memcached は永続性がない
    • (そもそも、主目的がキャッシュ)
  • Redis はアプリケーションのためのメインデータベースとして利用できる
  • Memcached の様に Redis は Key-Value モデルだが、値は文字列だけでなく List や Set を利用でき、また複雑な命令もサポートしている

Redis と Tokyo Cabinet / Tyrant の違い

  • Tokyo Cabinet は同期的にディスクに書き出すが、Redis は全てのデータセットをメモリ上に持ち、非同期的にディスクに書き込む
    • Tokyo Cabinet はより安全で、データセットが RAM 以上な場合に良い考え方かもしれない
    • Redis は高速(安全性は master-slave レプリケーションで確保できる)
  • Redis は高水準の操作とデータ構造をサポートしている
    • Tokyo Cabinet は名前付きフィールドを持った行からデータを構成する様なデータベースが行える類いの操作をサポートしている
      • Redis にできる様なサーバサイドでの List と Set の操作はできない
  • Tokyo Cabinet はネットワーク層を実装していない
    • Tokyo Cabinet へのインターフェースである Tokyo Tyrant と呼ばれるネットワーク層を利用する事で、クライアントサーバ形式で Tokyo Cabinet と通信できる
    • Redis はサーバ内部に組み込みでネットワーク通信をサポートし、基本的にそれだけで外部とデータセットの間のインターフェースとなる
  • Redis は Tokyo Tyrant で Tokyo Cabinet にアクセスするよりも、非常に高速であると報告されている
    • Redis は、一般的な Linux マシンで、並列に 50 のクライアントから毎秒 100,000 の操作を期待できる

Redis はロックをサポートするか

  • サポートしない
    • アトミック原則を提供しプログラマがロックフリーアルゴリズムとともに Redis を利用できる様にする、という考え方
    • 例)
      • 10 台のコンピュータと 1 つの Redis サーバがあるとする
      • 非常に長いテキストに含まれる単語を数えたい
      • テキストを 10 台のコンピュータ分に分割し、各コンピュータはそのテキストの一部を処理する
      • 単語を発見するたびに Redis の INCR コマンドでアトミックにカウンタを増加させる事ができる
      • アトミック原則は INCR/DECR のみならず、List の PUSH/POP、POP RANDOM KEY 操作、UPDATE などがあり、他にもある
  • (キー粒度のロックを計画中?)
    • News: locking with key-granularity is now planned

複数のデータベースをサポート

  • 別の同期原則(?)は複数のデータベースをサポートすること
  • 通常、新しい接続の度に DB 0 が選択されるが、SELECT コマンドで別のデータベースを選択できる
  • MOVE コマンドでアイテムを別の DB にアトミックに移動できる

Redis のデータ型

  • String
    • ただのバイトシーケンス
    • Redis の String はバイナリセーフなので、テキストのみならず、画像や圧縮データなど、何でも扱える
  • List
    • String の配列
    • List の先頭や末尾に新しい String を追加したり、長さを求めたり、範囲を得たり、指定した長さで切り詰めたり、並び替えたり、他にもいろいろな操作をサポートしている
  • Set
    • 順序を持たない String の集合
    • 要素の追加や削除、集合の交差・結合・引き算、他にも色々な操作をサポートしている
  • 値は String か List か Set
  • キーは String のサブセットで、改行("\n")と空白(" ")を含められない
  • 場合によっては、String は Redis にパースされ数値に変換される
    • 例えば、任意のキーで格納された数字を INCR コマンドでアトミックに増加させる場合
      • この場合、Redis は内部で 'long long' 型の 64-bit 符号付き整数の数値として扱う事ができる

チュートリアル

$ wget http://redis.googlecode.com/files/redis-1.02.tar.gz
$ tar xvzf redis-1.02.tar.gz
$ cd redis-1.02
$ make
$ ./redis-server redis.conf
$ telnet localhost 6379
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying fe80::1...
telnet: connect to address fe80::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
SET foo 3
bar
+OK
  • "SET foo 3<RET>"
    • 次の 3 byte を foo というキーに SET する
  • "bar<RET>"
    • 3 byte 分のデータを送る
  • "+OK"
    • 成功を伝えるサーバからの応答
GET foo
$3
bar
  • "GET foo"
    • foo というキーの値を得る
  • "$3"
    • 返る値のバイト数
  • "bar"
    • 返ってきた値
GET blabla
$-1
  • "GET blabla"
    • blabla という(存在しない)キーの値を得る
  • "$-1"
    • 長さの代わりに "$-1" という文字列で存在しない事を知らせる応答
EXISTS nokey
:0
EXISTS foo
:1
  • "EXISTS nokey"
    • nokey というキーが存在するか問い合わせる
  • ":0"
    • 存在しない事を意味する ":0" という応答
  • "EXISTS foo"
    • foo というキーが存在するか問い合わせる
  • ":1"
    • 存在する事を意味する ":1" という応答
Last modified:2009/11/11 00:16:21
Keyword(s):[kvs] [redis]
References: