2013-04-22 41 views
8

由於Redis嘗試將字符串解析爲64位有符號整數,因此存儲32位有符號整數的二進制表示而不是基數爲10的整數字符串是一個好主意嗎?在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個字符串實際上會佔用更多的內存。

這裏是字符串如何存儲的Redis -

  1. 整數小於10000存儲在共享存儲池,並沒有任何的內存開銷。如果您願意,可以通過更改常數REDIS_SHARED_INTEGERS in redis.h並重新編譯Redis來增加此限制。
  2. 整數大於10000且在長範圍內消耗8個字節。
  3. 常規字符串需要len(字符串)+ 4字節的長度+ 4字節用於標記空閒空間+ 1字節用於空終止符+ 8字節用於malloc開銷。

在你引用的例子中,一個8字節的問題,對於字符串的長v/s 21個字節。

編輯:

所以,如果我有一組數字都超過10000如何Redis的存儲我的一套少?

這取決於你有多少元素。

如果您的集合中的元素少於512個(請參閱set-max-intset-entries),則該集合將作爲IntSet存儲。 IntSet是Sorted Integer Array的一個美化名稱。由於你的數字少於10000,它會使用每個元素16位。它(幾乎)像C數組一樣具有內存效率。

如果您有超過512個元素,則該集合將成爲一個HashTable。該集合中的每個元素都被封裝在一個稱爲robj的結構中,該結構的開銷爲16字節。 robj結構有一個指向共享的整數池的指針,因此您不需要爲整數本身支付任何額外費用。最後,robj實例存儲在散列表中,散列表的開銷與集合的大小成正比。

如果您對某個元素消耗的內存量確切感興趣,請對您的數據集運行redis-rdb-tools。或者您可以閱讀MemoryCallback類的源代碼,這些註釋說明了內存佈局的方式。

+0

謝謝你的回答。請您解釋一下關於共享內存池的更多信息。所以如果我有一組數字都小於10,000,Redis如何存儲我的設置? – Aresn 2013-04-22 04:39:26

+0

@Aresn - 查看我的回答更新。如果你存儲的整數小於10000,Redis將會非常有效的記憶。 – 2013-04-22 14:33:02

+0

@ sripathi-krishnan你不能指定多少字節用於存儲字符串鍵嗎? 「len()+ 4 + 4 + 1 + 8字節」僅適用於值嗎? 我們需要存儲一個非常大的數據集string(43)=> int並且需要評估音量。無論如何感謝您的信息! – 2013-12-04 18:26:39

1

字符串存儲與長度,所以它不會在數據庫中只有4個字節 - 它可能存儲爲4個字節的數據+ 4字節長度+填充,這樣你就不會獲得任何東西。

相關問題