1. 程式人生 > >redis的opsForHash帶來的記憶體空間優化

redis的opsForHash帶來的記憶體空間優化

  • 把大量value為string的普通key-value抽象為分組的小hash的field-value,建議field總個數<1000,value的長度<512位元組,value越小,越省空間(最好50位元組以內)

key = username0000 value =strs 

...

key = username9999 value =strs 

  • 以上可重構為10組hash key,每組1000個field

key = username0 field = 000 value = str ... field =999 value =str 

...

key = username9 field = 000 value = str ... field =999 value =str 

  • 對於只含可計算的field的Hash:
    • 也可使用分組hash:如下,每100個使用者ID共享一個hash key
      • key=userId/100, field1=userId%100, field1Value=str, field2=userId%100, field2Value=str, ...
      • 即:userId為1~100的所有使用者的userId-value鍵值對都儲存在key=0的field-value中,而101~200則存在key=1中,......

https://blog.csdn.net/yunhaibin/article/details/8999429

https://www.cnblogs.com/susufufu/p/7875210.html

開始測試。進入redis-cli.exe,輸入info獲取資訊,看到初始化後的 used_memory_human:676.65K

實行一段程式,模擬新增String資料

public void setLotsKV() {
    RedisManager redisManager = new RedisManager();
    System.out.println("開始設定");
    for (int i = 0; i < 50000; i++) {
        String k = "k" + i;
        String v = "v" + i;
        redisManager.jedis.set(k, v);
    }
    System.out.println("設定完成");
}

然後清空資料,重啟redis,再新增模擬新增hash資料

public void setLotsHashKV() {
    RedisManager redisManager = new RedisManager();
    System.out.println("開始設定");
    HashMap<String, String> hashMap = new HashMap<>();
    for (int i = 0; i < 50000; i++) {
        String k = i + "";
        String v = i + "";
        hashMap.put(k, v);
    }
    redisManager.jedis.hmset("k", hashMap);
    System.out.println("設定完成");
}

什麼!!!說好的hash結構省記憶體呢。你騙我!!!!並沒有的想要的結果。如果不做任何處理,hash會比string消耗更多的記憶體。

換一種思路, 推測如果簡單的kv ,hash在kv上的優化所得記憶體,還沒有自己資料結構消耗的大。那麼,把k 和 v變複雜再測試一下。

新的模擬String

public void setLotsKV() {
    RedisManager redisManager = new RedisManager();
    System.out.println("開始設定");
    for (int i = 0; i < 50000; i++) {
        String k = "abcdefghijklmnopqrstuvwxyzK" + i;
        String v = "abcdefghijklmnopqrstuvwxyzV" + i;
        redisManager.jedis.set(k, v);
    }
    System.out.println("設定完成");
}

public void setLotsHashKV() {
    RedisManager redisManager = new RedisManager();
    System.out.println("開始設定");
    HashMap<String, String> hashMap = new HashMap<>();
    for (int i = 0; i < 50000; i++) {
        String k = "K" + i;
        String v = "V" + i;
        hashMap.put(k, v);
    }
    redisManager.jedis.hmset("abcdefghijklmnopqrstuvwxyz", hashMap);
    System.out.println("設定完成");
}

新的賴皮思路下,5.99M比8.03M 節省了25%+。實際上KV不會像測試程式碼這麼誇張,但是提升還是有的。