<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Redis 存儲(chǔ)結(jié)構(gòu)體信息,選 hash 還是string?

          共 3175字,需瀏覽 7分鐘

           ·

          2022-01-14 07:32

          點(diǎn)擊關(guān)注公眾號(hào),Java干貨及時(shí)送達(dá)??


          在講到使用hash還是string存儲(chǔ)的選擇前,先了解Redis的hash和string結(jié)構(gòu)。

          以下資料引自老錢的Redis深度歷險(xiǎn)。

          string

          string和hash都是Redis的一種數(shù)據(jù)結(jié)構(gòu)。string結(jié)構(gòu)常用來緩存用戶信息,通常將用戶信息結(jié)構(gòu)體使用JSON序列化成字符串,然后將序列化后的字符串存入Redis進(jìn)行緩存。

          String數(shù)據(jù)結(jié)構(gòu)

          Redis的字符串是動(dòng)態(tài)字符串,可以修改,內(nèi)部結(jié)構(gòu)類似于Java的ArrayList,采用預(yù)分配冗余空間的方式來減少內(nèi)存的頻繁分配。

          如上圖鎖實(shí),內(nèi)部為當(dāng)前字符串實(shí)際分配的空間capacity,一般高于實(shí)際字符串長(zhǎng)度len。使用的指令有set, get, mset, mget等

          hash

          Redis的hash相當(dāng)于Java的HashMap,內(nèi)部結(jié)構(gòu)實(shí)現(xiàn)與HashMap一致,即數(shù)組+鏈表結(jié)構(gòu)

          hash數(shù)據(jù)結(jié)構(gòu)

          不過Redis的hash的值只能是字符串,rehash方式不一樣,為了提高性能,Redis保留新舊兩個(gè)hash結(jié)構(gòu),采用漸進(jìn)式rehash策略,查詢時(shí)會(huì)同事查詢兩個(gè)hash結(jié)構(gòu),在后續(xù)的定時(shí)任務(wù)中以及hash操作指令中,循序漸進(jìn)將舊hash的內(nèi)容遷移到xinhash中,直至完全取代舊hash。hash移除最后一個(gè)元素后會(huì)自動(dòng)被刪除,內(nèi)存被回收。

          前面說到string適合存儲(chǔ)用戶信息,而hash結(jié)構(gòu)也可以存儲(chǔ)用戶信息,不過是對(duì)每個(gè)字段單獨(dú)存儲(chǔ),因此可以在查詢時(shí)獲取部分字段的信息,節(jié)省網(wǎng)絡(luò)流量。

          因此就引出了這篇文章,存儲(chǔ)結(jié)構(gòu)體信息是用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?

          該用戶也是同樣的疑問,因?yàn)橹档拈L(zhǎng)度是不確定的,所以不知道采用string還是hash存儲(chǔ)更有效率。

          這個(gè)問題底下有個(gè)開發(fā)者回答的非常好,這里翻譯出來供大家一起學(xué)習(xí)討論,如果有更好的方案,歡迎提出來 首先,答者建議參考redis官方的內(nèi)存優(yōu)化的文章:https://redis.io/topics/memory-optimization,用來理解官方的開發(fā)者是內(nèi)存優(yōu)化方面基于什么考慮。

          之后,答者列出了四個(gè)方案并給出了各個(gè)方案的利弊

          1. 存儲(chǔ)整個(gè)對(duì)象,其中JSON序列化過的字符串作為key

          INCR?id:users
          SET?user:{id}?'{"name":"Fred","age":25}'
          SADD?users?{id}
          • 優(yōu)勢(shì):可以認(rèn)為是“最佳實(shí)踐”,因?yàn)槊總€(gè)對(duì)象都是全特性的key,JSON解析特別塊,尤其是一次性查詢很多個(gè)字段的時(shí)候
          • 劣勢(shì):如果只查詢一個(gè)字段,速度就顯得比較慢了

          2. 在hash中存儲(chǔ)每個(gè)對(duì)象的屬性

          INCR?id:users
          HMSET?user:{id}?name?"Fred"?age?25
          SADD?users?{id}
          • 優(yōu)勢(shì):這也可以認(rèn)為是最佳時(shí)間。每個(gè)對(duì)象都是一個(gè)全特性的key。不需要解析JSON字符串
          • 劣勢(shì):如果要查詢對(duì)象的全部字段會(huì)比較慢。嵌套類型的對(duì)象(即對(duì)象里面還包著對(duì)象)無法輕易存儲(chǔ)

          3. 將對(duì)象轉(zhuǎn)化為JSON字符串,用hash結(jié)構(gòu)存儲(chǔ)

          INCR?id:users
          HMSET?users?{id}?'{"name":"Fred","age":25}'

          這個(gè)方案可以僅用兩個(gè)key,不需要很多key。但是沒法對(duì)每個(gè)用戶對(duì)象設(shè)置TTL(Time to Live,剩余生存時(shí)間),因?yàn)閷?duì)象僅僅是hash中的一個(gè)字段,而不是全特性的key

          • 優(yōu)勢(shì):JSON解析很快,尤其是一次查詢多個(gè)字段時(shí),對(duì)主key的命名空間污染更少
          • 劣勢(shì):如果要存儲(chǔ)很多對(duì)象,那么內(nèi)存使用和方案1相當(dāng)。當(dāng)只需要查詢一個(gè)字段時(shí),會(huì)比方案2速度慢。答者不認(rèn)為這是一個(gè)“最佳實(shí)踐”

          4. 存儲(chǔ)對(duì)象的每個(gè)屬性作為單獨(dú)的key

          INCR?id:users
          SET?user:{id}:name?"Fred"
          SET?user:{id}:age?25
          SADD?users?{id}

          根據(jù)上面的文章,即redis內(nèi)存優(yōu)化,這個(gè)方案不推薦(除非對(duì)象的屬性需要專門設(shè)置TTL或者別的設(shè)置)

          • 優(yōu)勢(shì):對(duì)象的屬性是全特征key,對(duì)于應(yīng)用來說比較好處理
          • 劣勢(shì):慢,內(nèi)存消耗更大,不是一個(gè)“最佳實(shí)踐”。對(duì)主key的命名空間有很大污染

          總的來說,方案4是最不推薦的,方案1和方案2非常相似,也很常見。答者更推薦方案1,因?yàn)檫@個(gè)方案允許存儲(chǔ)更復(fù)雜的對(duì)象(也就是說對(duì)象可以有很多層嵌套)。方案3通常用在對(duì)命名空間比較有要求的場(chǎng)景下,比如說不想要太多key,不關(guān)心TTL等參數(shù)。

          參考資料

          《Redis深度歷險(xiǎn)》

          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

          版權(quán)聲明:本文為CSDN博主「布魯斯1990」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。

          1.?技術(shù)總監(jiān)需要會(huì)些什么?

          2.?伴魚大數(shù)據(jù)權(quán)限系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)

          3.?HTTP Host 頭攻擊,這是什么鬼?

          4.?Spring Boot 整合 阿里開源中間件 Canal 實(shí)現(xiàn)數(shù)據(jù)增量同步!

          最近面試BAT,整理一份面試資料Java面試BATJ通關(guān)手冊(cè),覆蓋了Java核心技術(shù)、JVM、Java并發(fā)、SSM、微服務(wù)、數(shù)據(jù)庫(kù)、數(shù)據(jù)結(jié)構(gòu)等等。

          獲取方式:點(diǎn)“在看”,關(guān)注公眾號(hào)并回復(fù)?Java?領(lǐng)取,更多內(nèi)容陸續(xù)奉上。

          PS:因公眾號(hào)平臺(tái)更改了推送規(guī)則,如果不想錯(cuò)過內(nèi)容,記得讀完點(diǎn)一下在看,加個(gè)星標(biāo),這樣每次新文章推送才會(huì)第一時(shí)間出現(xiàn)在你的訂閱列表里。

          點(diǎn)“在看”支持一下吧??!

          瀏覽 28
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  五月天乱伦网 | 国产无码操逼视频 | 91视频内射 | 天天搞天天搞 | 亚洲中文字幕免费在线 |