FAQ

Redis はなぜ他のキー・バリューストアと違うのか?

それには 2 つの理由があります。

  • Redis は、複雑なデータタイプをもつことができ、またそれらに対して定義されたアトミックな操作を備えている、という点で、他のキー・バリュー DB とは異なる進化を遂げてきました。Redis のデータタイプは基礎的なデータ構造と深い関わりをもち、付加的な抽象レイヤを介することなくプログラマに公開されています。

  • Redis はディスクにも永続化を行いますが、インメモリデータベースであり、そこにはトレードオフが存在します。つまり、メモリ容量より大きなデータ・セットを保持できない代わりに、高速な書き込みと読み込みを達成します。インメモリデータベースのもうひとつの利点は、複雑なデータ構造のメモリ表現は、同じ構造をディスクに格納するのに比較すると、よりシンプルに操作できる、というものです。そのため Redis は内部的な複雑さを抑えながら多くの仕事をします。同時に、 2 つのオン・ディスクのストレージフォーマット (RDB と AOF) はランダムアクセスに適している必要がなく、そのためコンパクトで、常に追記のみのスタイルで生成されます(AOF ログローテーションも、メモリ上のコピーから新しいバージョンが生成されるため、追記のみの操作で済みます)。

Redis のメモリ・フットプリントは?

いくつかの例を挙げます(すべて、64 bit インスタンスで測定したものです):

  • 空のインスタンスは 1MB 以下のメモリを消費します。

  • 100 万個の小さなキー -> 文字列値のペアは、 100MB 以下のメモリを消費します。

  • 100 万個のキー -> ハッシュ値(5 つのフィールドをもつ)のペアは、200MB 以下のメモリを消費します。

あなたのユースケースで試すことも簡単です。 redis-benchmark ユーティリティを使ってランダムなデータ・セットを生成し、 INFO memory コマンドで使用量を確認してください。

64 bit システムは、32 bit システムよりも、同じキーを格納するために相当に大きなメモリを使います。とくにキーとバリューが小さな場合に顕著で、これは 64 bit システムではポインタに 8 byte 必要なためです。しかしもちろん、64 bit システムではより多くのメモリを使えるという利点があり、大きな Redis サーバーを運用するためには事実上 64 bit システムが必要です。別の手段としてはシャーディングがあります。

私は Redis の高水準なオペレーションと機能が好きだが、すべてがメモリ上にあり、メモリより大きなデータセットを持てない、という点は気に入らない。この点を変える計画はあるのか?

過去に、Redis 開発者は仮想メモリや他のシステムを使って、RAM よりも大きなデータ・セットを扱えるように試みたことがあります。しかし結局、私たちは 1 つのことをうまくやることで満足しています: データはメモリ上で提供され、ディスクはストレージとして使われる。今のところ、Redis のバックエンドにディスクを使う計画はありません。現在のデザインが Redis そのものなのです。

もし、あなたの実際の問題が、必要とする RAM の量ではなく、複数の Redis インスタンスにデータ・セットを分割することなら、より詳しい情報のために Partitioning を参照してください。

Redis をオンディスク・データベースと一緒に使うことは良い考えですか?

はい。一般的なデザインパターンとして、非常に書き込みの多い小さなデータ(と、あなたの問題を効率的にモデリングするために Redis のデータ構造を必要とするデータ)を Redis、大きな blob を SQL または結果整合性を担保するオンディスクデータベースに格納する、というものがあります。

Redis のメモリ使用量を抑えるためにできることはありますか?

可能なら、 32 bit の Redis インスタンスを使ってください。小さなハッシュ、リスト、ソート済みセット、integer からなるセットを活用してください。要素数が少ない特殊なケースの場合、Redis はよりコンパクトにこれらのデータタイプを表現します。詳しい情報は メモリ最適化 を参照してください。

Redis がメモリを使い切ったらどうなりますか?

Linux カーネルの OOM killer に kill されるか、エラーによりクラッシュするか、または性能が落ち始めるでしょう。最近のオペレーティングシステムでは、malloc() が NULL を返すことは稀で、サーバーはスワップを始めるために Redis の性能が落ちはじめ、何か問題が発生していることに気づくでしょう。

INFO コマンドは Redis が使用しているメモリ量をレポートするため、致命的な状態のチェックのために、あなたの Redis サーバーをモニターするスクリプトを書くことができます。

Redis はユーザーがメモリ使用量の制限を設定するための、ビルトインの保護機構を備えています。設定ファイルの maxmemory オプションを使って、Redis が使えるメモリを制限します。もしこの制限を超えたら、Redis は書き込みコマンドに対してエラーを返し始めます(ただし、読み出しのみのコマンドについては受付け続けます)。もしくは、キャッシュ目的で Redis を使用している場合は、最大メモリ制限に達したときにはキーを evict するように設定することも可能です。

Redis を LRU キャッシュとして使う にドキュメントされています。

(Linux 環境で) 十分なフリー RAM があるのに、バックグラウンド・セーブが fork() エラーで失敗する!

端的な答え: echo 1 > /proc/sys/vm/overcommit_memory :)

そして、長い回答:

Redis のバックグラウンド・セーブの枠組みは、近代的なオペレーティングシステムの fork の copy-on-write セマンティックに依存しています: Redis の fork (子プロセスの生成) は、正確に親プロセスのコピーです。子プロセスは、 DB をディスクにダンプした後、終了します。理論上は、子供はコピーされる親と同じだけのメモリを使用しますが、実際には近代的なオペレーティングシステムの copy-on-write セマンティックの実装により、親子のプロセス同士は共通のメモリページを 共有 します。あるページは、子供もしくは親によって変更されたときに限り、複製されます。理論的には、子プロセスがセーブを実行している間にすべてのページが変更される可能性があるため、Linux は子プロセスがどのくらいのメモリを必要とするか、事前に知ることはできません。そのため、 overcommit_memory が 0 に設定されている場合、実際に複製される、親の全メモリページに相当するフリー RAM がないと fork は失敗するでしょう。たとえば、もしあなたが 3 GB の Redis データ・セットを持っていて、2 GB のフリー RAM しかないような場合です。

overcommit_memory を 1 に設定すると、Linux は その制限を緩和し、より最適な allocation 方針で fork を実行します。これは、あなたが Redis に求める動作と一致するでしょう。

Linux の仮想メモリがどのように動作するかと、overcommit_memory および overcommit_ratio の他の選択肢について理解するための良いリソースとしては、Red Hat Magine からの古典があります。 “Understanding Virtual Memory”

Redis のオンディスク・スナップショットはアトミックですか?

はい。Redis のバックグラウンド・セーブ プロセスは、常にサーバーがコマンドを実行していない間に fork されるため、RAM 上でアトミックに実行されるコマンドはディスク・スナップショットの点から見てもアトミックです。

Redis はシングル・スレッドで動作するが、マルチ CPU / コアを活用するにはどうすれば良いか?

Redis は通常、メモリまたはネットワーク・バウンドであるため、CPU がボトルネックになることは非常に稀です。たとえば、平均的な Linux システムで動いている Redis でパイプライニングを使った場合、50 万リクエスト/秒 の性能を発揮します。そのため、あなたのアプリケーションが主に O(N) または O(log(N)) のコマンドを使うなら、CPU を使いすぎる、ということは起こりにくいです。

しかし、CPU 使用効率を最大化するために、複数の Redis インスタンスを同一マシン上に立てて、それぞれ独立したサーバーとして扱うことも可能です。いずれにせよどの時点かで、1 つのインスタンスでは十分ではなくなるかもしれません。もし複数の CPU を使いたい場合は、早い段階で何らかのシャーディングを検討すると良いでしょう。

複数の Redis インスタンスを扱うにあたっての詳しい情報は、 Partitioning page を参照してください。

1 つの Redis インスタンスは最大いくつまでキーを持てますか?また、リスト、セット、ソート済みセットがもてる最大要素数はいくつですか?

Redis は 2^32 個までのキーを扱えます。現実的には、インスタンスごとに少なくとも 2 億 5000 万個 のキーを扱えることがテストされています。

各リスト、セット、およびソート済みセットは 2^32 個の要素を格納できます。

言い換えると、限界はシステムで利用可能なメモリ量による、といえます。

スレーブが保持するキーの数が、マスターが保持するキーの数と異なります。なぜでしょうか?

もしキーに time to live (Redis expires) が設定されていたら、これは正常な振る舞いです。何が起こっているか:

  • マスターは、スレーブとの初期同期時に RDB ファイルを生成します。

  • RDB ファイルは、マスタ上ですでに expire されているが、まだメモリ上には存在しているキーを含みません。

  • これらのキーは、論理的には expire されていても、Redis マスターのメモリ上にはまだ存在しています。これらは存在しているとは考慮されず、使用しているメモリ領域はインクリメンタルに、または明示的なアクセス時に再利用されます。これらのキーはデータ・セットの論理的な一部ではありませんが、 INFO コマンドおよび DBSIZE コマンドでは通知されます。

  • マスターにより生成された RDB ファイルをスレーブが読んだとき、これらのキーはロードされません。

この作用の結果、多くの expire されたキーが存在するケースにおいて、スレーブ上では少ないキーしか存在しない、ということは一般的にあります。しかし、インスタンスが保持する内容に論理的な差異はありません。

Redis とはどういう意味ですか?

REmote DIctionary Server を意味しています。

なぜ Redis プロジェクトを始めたのですか?

もともとは、Redis は LLOOGG をスケールさせるために始まりました。しかし基本的な動くサーバーができた後、私は他の仲間とこの仕事を共有する、という考えを気に入り、Redis はオープンソース・プロジェクトへと発展しました。