プログラム猿の成長軌跡のRedis (4) ~文字列型Redisデータ構造の紹介~

はじめに
Java を学習したことのある学生は、文字列とは主に Java 言語の文字列型を指し、これは Java の基本的なデータ型に属さないことを知っているはずです。Redis では文字列型とは何でしょうか? 一般的な使用シナリオは何ですか? 一般的なコマンドは何ですか?

Redisの文字列型とは何ですか?

String 型は Redis の 2 つの部分で構成され、1 つの部分はキー (キー)、もう 1 つの部分は値 (値) です。Redis はキーと値をバインドし、値の値を検索します。キー。

String型の利用シーン

  1. タイムアウト設定が必要な共有セッションや確認コードなどのデータを保存するために使用されます
    Setex session_key 7200 session_value // 2 時間 (2 * 60 * 60) 後に期限切れになるように設定します (秒単位)
  2. 商品情報やユーザー情報などのjson文字列(シリアル化されたオブジェクト)を格納するために使用されます。
    Mset key1 userinfo1 key2 userinfo2
  3. 分散ロックの設定に使用
    setnx lockname lockvalue
  4. カウント
    セットカウンタ 1
    増加カウンタ

文字列 一般的に使用されるコマンド: (redis)

  1. append key value // キーがすでに存在する場合、APPEND コマンドはパラメータ Value のデータを既存の Value の末尾に追加します。キーが存在しない場合、APPEND コマンドは新しいキー/値を作成し、戻り値は新しい値の長さになります。
  2. 増加/減少キー //アトミックデータのプラス/マイナス
  3. incrby/decrby キー nb // アトミック データ プラス/マイナス nb
  4. キーを取得 // データを取得
  5. set key value // データを保存します。キーがすでに存在する場合は、元の値を上書きします。
  6. strlen キー // 値の長さ
  7. setex key minutes value // 2 つの操作をアトミックに完了します。1 つは、キーの値を指定された文字列に設定し、同時に Redis サーバー内のキーの生存時間 (秒単位) を設定することです。
  8. setnx key value // キーが存在しない場合は値を格納します
  9. mget key1 [key2 …] // key1とkey2の値を取得します
  10. mset key1 value1 [key2 value2 ...] //value1、value2を設定します

Redis文字列型の動的メモリ割り当てメカニズム? (延長)

Redis の文字列はメモリを動的に割り当てます。内部構造の実装は Java の ArrayList に似ています (負荷係数と実際の最大長に従って配列の長さを動的に拡張します)。文字列の長さが 1M 未満の場合は 2 倍拡張方式を使用し、サイズが 1M を超える場合は 1M で容量を拡張するというルールもあります。ただし、文字列の合計長が 512M を超えることはできません。
RedisはC言語をベースに開発されているため、C言語の構造体(struct)を使って記述することができ、その構造体をsdsと名付けています。
Struct SDS { T len; // 既存データ長T alloc; // 配列容量Char flags; // 特殊フラグChar[] buff; // 格納文字列};




なぜこのように設定されているのでしょうか?

  1. alloc — 配列拡張の複雑さを軽減する
    Java の場合、配列を拡張するときに length を使用して配列の長さを取得できますが、C 言語ではできません。メモリを割り当てるたびに、 void *malloc(size) または void を使用します。 *calloc(size ) メソッドを使用して割り当てますが、明らかに、割り当てる必要があるアドレスの長さを渡す必要があります。したがって、この設計はより迅速に拡張できます。時間計算量は O(1) です。
  2. Len — 切り詰めることなくデータの整合性を確保します。
    画像やビデオなどのバイナリ ファイルを保存する文字列の場合、途中に「0」文字が含まれることがありますが、「0」文字が読み取られると読み取りが停止されることは誰もが知っています。したがって、データ切り捨ての整合性を確保するために、既存のデータ長がここに追加されます。
    さらに、容量と併用して、頻繁なメモリ割り当てを削減することもできます。SDS の場合、文字列を追加するとき (append コマンド)、プログラムは alloc-len を使用して、残りの空きメモリが追加コンテンツを割り当てるのに十分であるかどうかを比較します。十分でない場合は、自然にメモリの再割り当てがトリガーされます。保存するのに十分なスペースがある場合は、メモリの再割り当てを行わずに直接割り当てられます。その拡張戦略は、文字列のサイズが 1M 未満の場合、各割り当ては len * 2 であり、つまり 100% の冗長性が予約され、文字列のサイズが 1M を超えると、無駄を避けるために 1M のスペースのみが追加されます。割り当てられており、最大値は 512M を超えません。

  3. フラグ — データを保存するためにどのsds 構造体が使用されるかを決定しますデータを
    保存するために sdshdr5 構造体
    #define SDS_TYPE_8 1 // フラグの最初の 3 桁は 001 で、sdshdr8 構造体がデータの保存に使用されることを示します
    #define SDS_TYPE_16 2 // 最初の3 桁は 001 です。フラグの 3 桁は 010 で、sdshdr16 構造がデータの保存に使用されることを示します。
    #define SDS_TYPE_32 3 // フラグの最初の 3 桁は 011 で、sdshdr32 構造がデータの保存に使用されることを示します
    #define SDS_TYPE_64 4 //フラグの最初の 3 桁は 100 で、データの保存に sdshdr64 構造体が使用されていることを示します。
    このようにして、最適な構造体を選択してデータを保存し、メモリの最適化を向上させることができます。
    Redis の sds.h ソース コードには、次の 5 種類の sdshdr (上記の構造) があります (以下はすべてソース コードです)。
struct __attribute__ ((__packed__)) sdshdr5 {
    
    
    unsigned char flags; /* 3 lsb of type, and 5 msb of string length */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr8 {
    
    
    uint8_t len; /* used */
    uint8_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr16 {
    
    
    uint16_t len; /* used */
    uint16_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr32 {
    
    
    uint32_t len; /* used */
    uint32_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr64 {
    
    
    uint64_t len; /* used */
    uint64_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};

メモリモデルは次のとおりです。
ここに画像の説明を挿入

注: ここで、len は配列の実際の長さを表し、alloc は配列割り当ての長さを表します。最初のタイプでは、len と alloc がないため、配列の長さを自動的に拡張できません。事前に割り当てられたアドレスが使い果たされると、データのレプリケーションはパフォーマンスを大量に消費するため、ほとんど使用されません。

さらに多くのリンク

Redis のインストールhttps://blog.csdn.net/qq_31236027/article/details/121879741
Redis の概要https://blog.csdn.net/qq_31236027/article/details/121879604
Redis データ構造の概要https://blog.csdn。 net/qq_31236027/article/details/121894713

おすすめ

転載: blog.csdn.net/qq_31236027/article/details/122016881