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数据

扫描二维码关注公众号,回复: 4331349 查看本文章
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不会像测试代码这么夸张,但是提升还是有的。

猜你喜欢

转载自my.oschina.net/u/2382040/blog/2236871