redis faq

5445 ワード

なぜredisは他のkey-valueストレージと異なるのですか?
主に2つの原因があります.
  • key-value DBでは、redisは、原子の動作を定義するより複雑なデータ型の値を含むことができる異なる進化経路である.Redisデータ型は基本的なデータ構造と密接に関連しており,追加の抽象層を必要とせずにプログラマーに露出している.
  • redisはメモリ・データベースですが、ディスクに永続化されると、データセットがメモリより大きくならないという制限の下で、高速な読み書きに達する異なるトレードオフを表します.メモリ・データベースのもう1つの利点は、複雑なデータ構造のメモリ表現がディスク上の同じデータ構造よりも操作しやすいため、内部の複雑さが小さい場合、redisが多くできることです.同時に、ディスク上の2つのストレージフォーマット(RDBおよびAOF)はランダムアクセスに適している必要がないため、コンパクトであり、常に追加可能な方法で生成することができる(新しいバージョンはメモリ内のデータコピーから生成されるため、AOFログの交互は追加可能な操作のみである).従来のディスクストレージに比べて、この設計も異なる課題に直面しています.メモリ上のプライマリ・データとして、redis操作は、ディスクに常に更新されたバージョンのデータセットがあることを確認するために注意して処理する必要があります.

  • redisのメモリ使用量はいくらですか?
    いくつかのケースをあげます(すべてのケースは64ビットのインスタンスを使用して取得されます):
  • 空のインスタンスは、3 MBメモリを使用します.
  • 100万個の小さなkeys->文字列タイプのvalueのキー値ペアには85 MBのメモリが使用されます.
  • 100万個のkeys->Hashタイプの値は、160 MBのメモリを使用する5つのフィールドを持つオブジェクトを表します.

  • テストケースは簡単です.redis-benchmarkツールINFO memoryのコマンドを使用してランダム・データセットを生成し、使用したスペースを確認します.
    64ビットシステムは、32ビットシステムに比べて同じkeysを格納する場合、特にkeysとvaluesが小さい場合、多くのメモリを使用します.これは、64ビットシステムのポインタが8バイトかかるためです.しかし、もちろん64ビットシステムに多くのメモリを持つことができるので、大規模なredis serverを実行するためには、多かれ少なかれ64ビットシステムが必要です.もう一つの選択肢はスライスです.
    私はredisの高度な操作と特性が好きですが、すべてのものをメモリに維持するのが好きではありません.メモリよりも大きなデータセットを持つことはできません.これに対して計画は変わりますか?
    従来、redis開発者は仮想メモリや他のシステムを使用して、redisがRAMよりも大きなデータセットを使用できるようにしようと試みていましたが、私たちができることがあれば、メモリがデータを提供し、ディスクを使用してストレージを行うことができます.したがって、redisのディスクバックエンドを構築する計画はありません.ほとんどのredis機能は、結局、その現在の設計の直接的な結果である.本当に問題が必要な総RAMメモリではなく、実際に複数のredisインスタンスにデータセットを分割する必要がある場合は、ドキュメントのPartitioning pageを読んで詳細を参照してください.最近、redisラボ、redis開発のスポンサー会社は、RAM/flashのハイブリッド方式を使用してより大きなデータセットにアクセスし、偏ったアクセスモードを持つ「Redis on flash」ソリューションを開発しました.より多くの情報を表示できますが、この機能はオープンソースのRedisコードライブラリの部分ではありません.
    redisはディスク・データベースと一緒に使用するのは良い考えですか?
    はい、一般的な設計モデルには、redisで非常に小さなデータを「書き換える」ことが含まれています(そして、redisデータ構造のデータを使用して問題を効率的にモデリングする必要があります)、大きなblobsデータはSQLまたは従来の永続化ディスクデータベースに書き込まれます.同様に、Redisを使用して、ディスク・データベースに格納されている同じデータ・サブセットの別のコピーをメモリに格納する場合があります.これはキャッシュに似ているように見えますが、通常、redisデータセットはディスクDBデータとともに更新され、キャッシュがヒットしていないときにリフレッシュされないため、実際にはより優れたモデルです.
    redisメモリの使用を減らすには何ができますか?
    できれば32ビットのredisインスタンスを使用できます.また、redisは、いくつかの要素の特殊なシーンでこれらのデータ型をよりコンパクトに表すことができるため、hash、lists、sorted sets、整形setsをよく利用しなければならない.詳細については、Memory Optimization pageを参照してください.
    redisがメモリを超えて実行されるとどうなりますか?
    redisはLinuxカーネルOOM killerによって殺されたり、エラーがクラッシュしたり、遅くなったりします.現代のオペレーティングシステムではmalloc()がNULLを返すのは一般的ではありません.通常、サーバがスワップを開始し(スワップスペースが構成されている場合)、redisのパフォーマンスが低下し始めるので、いくつかの点が間違っていることに気づくかもしれません.redisには内蔵保護があり、ユーザーはメモリ使用制限を設定することができ、プロファイルではmaxmemoryパラメータを使用してredisが使用できるメモリを制限します.この制限に達すると、redisはエラー書き込みコマンドに返信し始めます(ただし、読み取りコマンドを受け入れ続けます).または、redisを使用してキャッシュの最大制限に達するとkeysを駆逐するように構成できます.LRUキャッシュとしてredisを使用する計画がある場合は、詳細なドキュメントRedis as an LRU cacheがあります.INFOコマンドはredisが使用しているメモリの数を報告するので、スクリプトを書いてredisサーバを監視し、redisが制限に達する前に危険状態、臨界条件をチェックすることができます.
    Linuxでは空きメモリがたくさんあっても、バックグラウンドはfork()エラーで保存に失敗します!
    簡単な回答:echo 1 > /proc/sys/vm/overcommit_memory詳細な回答:現代のオペレーティングシステムでは、redisバックグラウンド保存モードはforkのcopy-on-write(書き込みとコピー)の意味に依存します.redis forks(サブプロセスの作成)は親プロセスの完全なコピーです.サブプロセスdump DBはディスク上にあり、最終的に終了します.理論的には、サブプロセスは親プロセスと同じくらい多くのメモリをコピーとして使用する必要がありますが、実際には、多くの現代のオペレーティングシステムがcopy-on-writeの意味を実現しているため、親子プロセスが共通のメモリページを共有することに感謝します.1つのメモリ・ページは、サブプロセスまたは親プロセスで変更が発生した場合にのみコピーされます.理論的には、サブプロセスが保存されている間にすべてのメモリページが変更される可能性があるため、Linuxはサブプロセスがどれだけのメモリを消費するかを事前に知ることができません.overcommit_memoryの設定が0の場合、forkは失敗します.必要な同じ多くの空きRAMがすべての親プロセスのメモリページをコピーしていない限り、3 GBのredisデータセットがあり、2 GBの空きメモリしかない場合は失敗します.overcommit_memoryを1に設定してLinuxにリラックスを伝え、forkをより楽観的な割り当てで実行し、これはredisが望んでいることである.Linux仮想メモリがどのように動作するか、overcommit_memoryovercommit_memoryの他の代替方法を理解するには、Red Hat Magazineの古典的な文章「Understanding Virtual Memory」から良いソースがあります.Proc(5)のマニュアルページを参照して、使用可能な値の説明を参照することもできます.
    redisディスクスナップショットは原子ですか?
    はい、redisバックグラウンド保存プロセスは、常にサービスがコマンドを実行していない場合にforkedを実行するので、ディスクスナップショットの観点から、各コマンドのレポートは原子であり、RAMでも原子である.
    redisは単一スレッドです.複数のCPU/コアの利用方法
    redis cpuを使用することがボトルネックになるのはよくありません.通常、redisはメモリかネットワークの制限です.たとえば、pipelining redisを使用して通常のLinuxシステム上で実行すると、毎秒100 W個のリクエストを送信することができるので、アプリケーションが主にO(N)またはO(log(N))のコマンドを使用している場合、CPUはほとんど使用されません.しかし、CPU使用率を最大化するために、同じbox(非翻訳部分:1つのエンティティマシンが複数のコンテナに分割される可能性があるため、1つのサーバの後ろに直接機械的に翻訳されると考えられる)で複数のredisインスタンスを起動し、異なるサーバと見なすことができます.単一のマシンでは足りない場合があるので、複数のCPUを使用したい場合は、前に述べたスライス方法を考えてみましょう.パーティション・ページでは、複数のredisインスタンスの使用に関するPartitioning pageの詳細を参照できます.しかしredis 4.0ではredisをよりスレッド化し始めた.これは、バックグラウンドでオブジェクトを削除したり、redisモジュールで実装されたコマンドをブロックしたりすることに限られています.将来のバージョンでは、redisをより多くのスレッド化する計画です.
    個々のredisインスタンスがkeysを保持できる最大数はいくらですか?Hash,List,Set,Sorted Setにおける最大要素数は?
    redisは最大2^32個のkeysを持つことができ、各インスタンスは最小2.5億個のkeysを持つことができることを実証した.各hash,list,set,sorted setは,2^32要素を持つことができる.言い換えれば、あなたの制限はシステムで使用可能なメモリかもしれません.
    私のslaveはそれのmasterと異なる数のkeysを自称して、どうしてですか?
    もしあなたがkeysを使用してtiem to live(redisが期限切れ)を制限しているなら、これは正常な行為です.次に、何が起こったのかを説明します.
  • masterは、slaveと最初に同期したときにRDBファイルを生成する.
  • RDBファイルには、masterで期限切れになったkeysは含まれませんが、メモリに残っています.
  • その後、これらのkeysは、論理が期限切れになってもredis masterのメモリに残っています.彼らは存在するとは思われませんが、その後、メモリが回収され、アクセス時に増分され、表示される回収が表示されます.しかし、これらのkeysはデータセットの論理部分ではないが、INFO出力でDBSizeコマンドと通知される.
  • slaveがmasterによって生成されたRDBファイルを読み出すと、これらのkeysのセットはロードされません.

  • したがって,期限切れ時間を設定した多くのkeysセットのユーザにとってslaveで見られるkeysは減少するため,これは仮想的であるが,インスタンスコンテンツには実際の論理的相違はない.