Redis 存儲結構體信息,選 hash 還是string?
點擊關注公眾號,Java干貨及時送達
在講到使用hash還是string存儲的選擇前,先了解Redis的hash和string結構。
以下資料引自老錢的Redis深度歷險。
string
string和hash都是Redis的一種數(shù)據(jù)結構。string結構常用來緩存用戶信息,通常將用戶信息結構體使用JSON序列化成字符串,然后將序列化后的字符串存入Redis進行緩存。

Redis的字符串是動態(tài)字符串,可以修改,內(nèi)部結構類似于Java的ArrayList,采用預分配冗余空間的方式來減少內(nèi)存的頻繁分配。
如上圖鎖實,內(nèi)部為當前字符串實際分配的空間capacity,一般高于實際字符串長度len。使用的指令有set, get, mset, mget等
hash
Redis的hash相當于Java的HashMap,內(nèi)部結構實現(xiàn)與HashMap一致,即數(shù)組+鏈表結構

前面說到string適合存儲用戶信息,而hash結構也可以存儲用戶信息,不過是對每個字段單獨存儲,因此可以在查詢時獲取部分字段的信息,節(jié)省網(wǎng)絡流量。
因此就引出了這篇文章,存儲結構體信息是用hash還是string?
以下信息出自StackOverflow ?Redis strings vs Redis hashes to represent JSON: efficiency?
I?want?to?store?a?JSON?payload?into?redis.?There's?really?2?ways?I?can?do?this:
1.?One?using?a?simple?string?keys?and?values.
key:user,?value:payload?(the?entire?JSON?blob?which?can?be?100-200?KB)
SET?user:1?payload
2.?Using?hashes
HSET?user:1?username?"someone"
HSET?user:1?location?"NY"
HSET?user:1?bio?"STRING?WITH?OVER?100?lines"
Keep?in?mind?that?if?I?use?a?hash,?the?value?length?isn't?predictable.?They're?not?all?short?such?as?the?bio?example?above.
Which?is?more?memory?efficient??Using?string?keys?and?values,?or?using?a?hash?
該用戶也是同樣的疑問,因為值的長度是不確定的,所以不知道采用string還是hash存儲更有效率。最新面試題整理好了,大家可以在Java面試庫小程序在線刷題。
這個問題底下有個開發(fā)者回答的非常好,這里翻譯出來供大家一起學習討論,如果有更好的方案,歡迎提出來 首先,答者建議參考redis官方的內(nèi)存優(yōu)化的文章:https://redis.io/topics/memory-optimization,用來理解官方的開發(fā)者是內(nèi)存優(yōu)化方面基于什么考慮。
INCR?id:users
SET?user:{id}?'{"name":"Fred","age":25}'
SADD?users?{id}
INCR?id:users
HMSET?user:{id}?name?"Fred"?age?25
SADD?users?{id}
INCR?id:users
HMSET?users?{id}?'{"name":"Fred","age":25}'
這個方案可以僅用兩個key,不需要很多key。但是沒法對每個用戶對象設置TTL(Time to Live,剩余生存時間),因為對象僅僅是hash中的一個字段,而不是全特性的key
優(yōu)勢:JSON解析很快,尤其是一次查詢多個字段時,對主key的命名空間污染更少 劣勢:如果要存儲很多對象,那么內(nèi)存使用和方案1相當。當只需要查詢一個字段時,會比方案2速度慢。答者不認為這是一個“最佳實踐”
INCR?id:users
SET?user:{id}:name?"Fred"
SET?user:{id}:age?25
SADD?users?{id}
根據(jù)上面的文章,即redis內(nèi)存優(yōu)化,這個方案不推薦(除非對象的屬性需要專門設置TTL或者別的設置)
總的來說,方案4是最不推薦的,方案1和方案2非常相似,也很常見。答者更推薦方案1,因為這個方案允許存儲更復雜的對象(也就是說對象可以有很多層嵌套)。方案3通常用在對命名空間比較有要求的場景下,比如說不想要太多key,不關心TTL等參數(shù)。另外,Redis 系列面試題和答案全部整理好了,微信搜索Java技術棧,在后臺發(fā)送:面試,可以在線閱讀。
參考資料
《Redis深度歷險》
https://juejin.im/book/5afc2e5f6fb9a07a9b362527/section/5afc2e5f51882542714ff291
https://stackoverflow.com/questions/16375188/redis-strings-vs-redis-hashes-to-represent-json-efficiency
原文鏈接:https://blog.csdn.net/u010145219/article/details/99427693
版權聲明:本文為CSDN博主「布魯斯1990」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權協(xié)議,轉載請附上原文出處鏈接及本聲明。

關注Java技術棧看更多干貨

