2013-04-22 6 views
8

Redisは64ビット符号付き整数に文字列を解析しようとしているため、基数10の整数文字列ではなく32ビット符号付き整数のバイナリ表現を格納することをお勧めしますか?Redisで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 

答えて

17

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

  1. 整数未満10000を共有メモリー・プールに格納され、任意のメモリのオーバーヘッドを持っていない - ここ

    は、文字列がどのようにRedisの店です。必要に応じて、定数REDIS_SHARED_INTEGERS in redis.hを変更し、Redisを再コンパイルすることで、この制限を増やすことができます。

  2. 10000より大きく、長さの範囲内の整数は8バイトを消費します。
  3. 通常の文字列は、長さがlen(文字列)+ 4バイト、空き領域をマーキングするために4バイト、ヌルターミネータが1バイト、mallocオーバーヘッドが8バイトです。

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

EDIT:

私は数字のセットを持っているのであれば、すべての10,000未満はどのようにRedisのは、私のセットを格納していますか?

あなたが持っている要素の数によって異なります。

セット内に512個未満の要素がある場合(set-max-intset-entriesを参照)、セットはIntSetとして保存されます。 IntSetは、ソートされた整数配列の栄光に満ちた名前です。あなたの数は10000より少ないので、要素あたり16ビットを使用します。これは、(ほぼ)C配列ほど効率的なメモリです。

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

要素が消費するメモリ量を正確に知りたい場合は、データセットでredis-rdb-toolsを実行してください。または、クラスMemoryCallbackのソースコードを読むことができます。コメントは、メモリのレイアウト方法を説明しています。

+0

ありがとうございます。共有メモリプールについてもう少し説明してください。だから、もし私が10,000よりも少ない数字のセットを持っていれば、レディスはどのように私のセットを保管していますか? – Aresn

+0

@Aresn - 私の答えの更新を参照してください。 10000未満の整数を格納する場合、Redisは非常に効率的なメモリです。 –

+0

@ sripathi-krishnan文字列キーの格納に使用されるバイト数を指定できませんでしたか? "len()+ 4 + 4 + 1 + 8バイト"は値にのみ適用されますか? String(43)=> intのペアの非常に大きなデータセットを格納する必要があり、ボリュームを評価する必要があります。とにかく情報ありがとう! –

1

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

関連する問題