<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存儲結(jié)構(gòu)體信息是用hash還是string?

          共 2495字,需瀏覽 5分鐘

           ·

          2021-11-08 11:17

          你知道的越多,不知道的就越多,業(yè)余的像一棵小草!

          你來,我們一起精進!你不來,我和你的競爭對手一起精進!

          編輯:業(yè)余草

          blog.csdn.net/u010145219

          推薦:https://www.xttblog.com/?p=5290

          現(xiàn)在的程序員,已經(jīng)越來越離不開 Redis 了。那么在使用 Redis 過程中,我需要存儲一個結(jié)構(gòu)體,我應(yīng)該是選擇使用 hash 呢?還是字符串?大家可以線思考思考再往下閱讀本文。

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

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

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

          Redis 的字符串是動態(tài)字符串,可以修改,內(nèi)部結(jié)構(gòu)類似于 Java 的 ArrayList,采用預(yù)分配冗余空間的方式來減少內(nèi)存的頻繁分配。如上圖鎖實,內(nèi)部為當前字符串實際分配的空間 capacity,一般高于實際字符串長度 len。使用的指令有 set, get, mset, mge t等。

          hash

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

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

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

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

          因此就引出了這篇文章,存儲結(jié)構(gòu)體信息是用 hash 還是 string?
          以下信息出自 StackOverflow,《Redis strings vs Redis hashes to represent JSON: efficiency?》:https://stackoverflow.com/questions/16375188/redis-strings-vs-redis-hashes-to-represent-json-efficiency

          存儲結(jié)構(gòu)體信息是用 hash 還是 string

          該用戶也是同樣的疑問,因為值的長度是不確定的,所以不知道采用 string 還是 hash 存儲更有效率。

          這個問題底下有個開發(fā)者回答的非常好,這里翻譯出來供大家一起學(xué)習討論,如果有更好的方案,歡迎提出來。

          首先,答者建議參考 redis 官方的內(nèi)存優(yōu)化的文章:https://redis.io/topics/memory-optimization,用來理解官方的開發(fā)者是內(nèi)存優(yōu)化方面基于什么考慮。

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

          1. 存儲整個對象,其中 JSON 序列化過的字符串作為 key。
          INCR?id:users
          SET?user:{id}?'{"name":"Fred","age":25}'
          SADD?users?{id}

          優(yōu)勢:可以認為是“最佳實踐”,因為每個對象都是全特性的 key,JSON 解析特別塊,尤其是一次性查詢很多個字段的時候

          劣勢:如果只查詢一個字段,速度就顯得比較慢了。?? ? 2. 在 hash 中存儲每個對象的屬性

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

          優(yōu)勢:這也可以認為是最佳時間。每個對象都是一個全特性的 key。不需要解析 JSON 字符串。

          劣勢:如果要查詢對象的全部字段會比較慢。嵌套類型的對象(即對象里面還包著對象)無法輕易存儲。

          1. 將對象轉(zhuǎn)化為 JSON 字符串,用 hash 結(jié)構(gòu)存儲。
          INCR?id:users
          HMSET?users?{id}?'{"name":"Fred","age":25}'

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

          優(yōu)勢:JSON 解析很快,尤其是一次查詢多個字段時,對主 key 的命名空間污染更少。

          劣勢:如果要存儲很多對象,那么內(nèi)存使用和方案 1 相當。當只需要查詢一個字段時,會比方案 2 速度慢。答者不認為這是一個“最佳實踐”。

          1. 存儲對象的每個屬性作為單獨的 key
          INCR?id:users
          SET?user:{id}:name?"Fred"
          SET?user:{id}:age?25
          SADD?users?{id}

          根據(jù)上面的文章,即 redis 內(nèi)存優(yōu)化https://redis.io/topics/memory-optimization,這個方案不推薦(除非對象的屬性需要專門設(shè)置 TTL 或者別的設(shè)置。

          優(yōu)勢:對象的屬性是全特征 key,對于應(yīng)用來說比較好處理

          劣勢:慢,內(nèi)存消耗更大,不是一個“最佳實踐”。對主 key 的命名空間有很大污染

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

          瀏覽 78
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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>
                  一级性AAAA生活 | 久久99久久久久久久久久久 | 亚洲天堂综合网 | 色伊人大香蕉 | 在线视频中文字幕一区 |