9

Redis は文字列を 64 ビット符号付き整数に解析しようとするため、基数 10 の整数文字列の代わりに 32 ビット符号付き整数のバイナリ表現を格納することをお勧めしますか?

私たちのシステムには、多くの 32 ビット符号付き整数 ID のリストがあります。

I can store them like
lpush mykey 102450  --> redis cast 102450 to 8 bytes long

or store it like 
lpush mykey  \x00\x01\x19\x32  ---> this is just 4 bytes
4

2 に答える 2

19

内部的には、Redis は最も効率的な方法で文字列を保存します。整数を基数 10 の文字列に強制すると、実際にはより多くのメモリが使用されます。

Redisが文字列を保存する方法は次のとおりです-

  1. 10000 未満の整数は共有メモリ プールに格納され、メモリ オーバーヘッドはありません。必要に応じて、redis.h の定数REDIS_SHARED_INTEGERS を変更し、Redis を再コンパイルすることで、この制限を増やすことができます。
  2. 10000 より大きく long の範囲内の整数は、8 バイトを消費します。
  3. 通常の文字列は、len(string) + 長さの 4 バイト + 空き領域のマーキングの 4 バイト + null ターミネータの 1 バイト + malloc オーバーヘッドの 8 バイトを使用します。

引用した例では、文字列の長い v/s 21 バイトの場合は 8 バイトの問題です。

編集 :

では、数字のセットがすべて 10,000 未満の場合、Redis はどのように私のセットを保存するのでしょうか?

それはあなたが持っている要素の数に依存します。

セット内の要素が 512 未満の場合 (「 」を参照set-max-intset-entries)、セットは IntSet として格納されます。IntSet は、ソート済み整数配列の美化された名前です。数値が 10000 未満であるため、要素ごとに 16 ビットを使用します。これは (ほとんど) C 配列と同じくらいメモリ効率が良いです。

512 を超える要素がある場合、セットは HashTable になります。robjセット内の各要素は、16 バイトのオーバーヘッドを持つと呼ばれる構造体にラップされます。構造体には整数の共有プールへのrobjポインターがあるため、整数自体に追加料金を支払う必要はありません。最後に、robjインスタンスはハッシュテーブルに格納され、ハッシュテーブルにはセットのサイズに比例するオーバーヘッドがあります。

要素が消費する正確なメモリ量に関心がある場合は、データセットでredis-rdb-toolsを実行します (免責事項: 私はこのツールの作成者です)。または、クラスMemoryCallbackのソースコードを読むことができます。コメントは、メモリがどのように配置されているかを説明しています。

于 2013-04-22T04:17:23.557 に答える
1

文字列は長さとともに保存されるため、データベースには 4 バイトだけではありません。おそらく、4 バイトのデータ + 4 バイトの長さ + パディングとして保存されるため、何も得られません。

于 2013-04-22T01:05:17.847 に答える