sql >> データベース >  >> NoSQL >> Redis

Redisに使用される基礎となるデータ構造は何ですか?

    私はあなたの質問に答えようとしますが、最初は奇妙に見えるかもしれない何かから始めます:Redisの内部に興味がなければ、気にしないでください データ型が内部でどのように実装されるかについて。これは単純な理由によるものです。すべてのRedis操作について、ドキュメントに時間計算量があります。一連の操作と時間計算量がある場合、必要な他の唯一のことは、メモリ使用量に関する手がかりです(データによって異なる可能性のある多くの最適化を行います。後者の数値を取得するための最良の方法は、いくつかの簡単な実世界のテストを行うことです。

    しかし、あなたが尋ねたので、これがすべてのRedisデータ型の基本的な実装です。

    • 文字列 C動的文字列ライブラリを使用して実装されているため、追加操作での割り当てに対して(漸近的に)料金を支払う必要はありません。このようにして、たとえば、二次の振る舞いをする代わりに、O(N)を追加します。
    • リスト リンクリストで実装されています。
    • セット およびハッシュ ハッシュテーブルで実装されます。
    • ソートされたセット スキップリスト(独特のタイプのバランスの取れたツリー)で実装されます。

    ただし、リスト、セット、および並べ替えられたセットのアイテム数が少なく、最大値のサイズが小さい場合は、別のはるかにコンパクトなエンコーディングが使用されます。このエンコーディングはタイプによって異なりますが、すべての操作でO(N)スキャンを強制することが多いコンパクトなデータブロブであるという特徴があります。この形式は小さなオブジェクトにのみ使用するため、これは問題ではありません。小さなO(N)ブロブをスキャンすることは、キャッシュを忘れるです。 つまり、実際には非常に高速であり、要素が多すぎると、エンコーディングは自動的にネイティブエンコーディング(リンクリスト、ハッシュなど)に切り替えられます。

    しかし、あなたの質問は実際には内部だけではなく、何を達成するためにどのタイプを使用するかでした。 。

    文字列

    これは、すべてのタイプの基本タイプです。これは4つのタイプの1つですが、リストは文字列のリスト、セットは文字列のセットなどであるため、複合型の基本タイプでもあります。

    Redis文字列は、HTMLページを保存するすべての明白なシナリオだけでなく、すでにエンコードされているデータの変換を避けたい場合にも適しています。したがって、たとえば、JSONまたはMessagePackを使用している場合は、オブジェクトを文字列として格納するだけで済みます。 Redis 2.6では、Luaスクリプトを使用してこの種のオブジェクトサーバー側を操作することもできます。

    文字列のもう1つの興味深い使用法は、ビットマップであり、一般にバイトのランダムアクセス配列です。これは、Redisがコマンドをエクスポートして、ランダムな範囲のバイト、さらには1ビットにアクセスするためです。たとえば、次の優れたブログ投稿を確認してください:Redisを使用したFastEasyリアルタイムメトリック。

    リスト

    リストは、リストの極端な部分、つまり尻尾の近く、または頭の近くだけに触れる可能性が高い場合に適しています。ランダムアクセスが遅いため、リストはページを表示するのにあまり適していません、O(N)。したがって、リストの適切な使用法は、プレーンキューとスタック、または同じソースと宛先でRPOPLPUSHを使用してループ内のアイテムを処理してリングを「回転」させることです。アイテムの。

    リストは、N個のアイテムの上限付きコレクションを作成する場合にも適しています。通常 上部または下部のアイテムのみにアクセスするか、Nが小さい場合にアクセスします。

    セット

    セットは順序付けられていないデータコレクションであるため、アイテムのコレクションがあるたびに有効であり、コレクションの存在またはサイズを非常に高速にチェックすることが非常に重要です。セットのもう1つの優れた点は、ランダム要素のピークまたはポップのサポートです(SRANDMEMBERおよびSPOPコマンド)。

    セットは、「ユーザーXの友達は何ですか?」などの関係を表すのにも適しています。などなど。しかし、この種のものに適した他のデータ構造は、後で説明するようにソートされたセットです。

    セットは交差点や和集合などの複雑な操作をサポートしているため、データがあり、そのデータに対して変換を実行して出力を取得する場合に、これは「計算」方式でRedisを使用するための優れたデータ構造です。

    小さなセットは非常に効率的な方法でエンコードされます。

    ハッシュ

    ハッシュは、フィールドと値で構成される、オブジェクトを表すのに最適なデータ構造です。ハッシュのフィールドは、HINCRBYを使用してアトミックにインクリメントすることもできます。ユーザー、ブログ投稿、その他の種類のアイテムなどのオブジェクトがある場合 、JSONなどの独自のエンコーディングを使用したくない場合は、ハッシュを使用することをお勧めします。

    ただし、小さなハッシュはRedisによって非常に効率的にエンコードされることに注意してください。また、Redisに、個々のフィールドを非常に高速にアトミックにGET、SET、またはインクリメントするように依頼できます。

    ハッシュは、参照を使用して、リンクされたデータ構造を表すためにも使用できます。たとえば、コメントのlamernews.com実装を確認してください。

    ソートされたセット

    並べ替えられたセットは、リスト以外の、順序付けられた要素を維持するための唯一の他のデータ構造です 。ソートされたセットを使用して、さまざまなクールな作業を行うことができます。たとえば、あらゆる種類のトップサムシングを持つことができます Webアプリケーションのリスト。スコア別のトップユーザー、ページビュー別のトップ投稿、トップは何でも、1つのRedisインスタンスは、1秒あたりの大量の挿入およびget-top-elements操作をサポートします。

    並べ替えられたセットは、通常のセットと同様に、関係を記述するために使用できますが、アイテムのリストをページ分割したり、順序を覚えたりすることもできます。たとえば、並べ替えられたセットを持つユーザーXの友達を覚えている場合、受け入れられた友情の順に簡単に思い出すことができます。

    並べ替えられたセットは、優先キューに適しています。

    並べ替えられたセットは、リストの中央から範囲を挿入、削除、または取得することが常に高速である、より強力なリストのようなものです。ただし、これらはより多くのメモリを使用し、O(log(N))データ構造です。

    結論

    この投稿で情報を提供したいと思いますが、lamernewsのソースコードをhttp://github.com/antirez/lamernewsからダウンロードして、その動作を理解することをお勧めします。 Lamer News内では、Redisの多くのデータ構造が使用されており、特定のタスクを解決するために何を使用するかについて多くの手がかりがあります。

    文法のタイプミスで申し訳ありません。ここは真夜中です。疲れすぎて投稿を確認できません;)



    1. MongoDB$count集約演算子

    2. SpringDataMongoDBのクエリに対して特定のフィールドのみを返す

    3. ARMテンプレート出力を介してRedisprimaryKeyを返す方法は?

    4. 値がリストにすでに存在するかどうかを確認するRedis