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

97a9290e8d62ba84fa249c718ac27216377.jpg

实行一段程序,模拟添加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("设置完成");
}

5c1409fdf9d9ac0e9deded78630991b260a.jpg

然后清空数据,重启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("设置完成");
}

28c213fd00bc789ee37bce044f7cf64f793.jpg

什么!!!说好的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("设置完成");
}

9e862476dfd2208d3af647a2609c33cb24a.jpg

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("设置完成");
}

eea7eb53bfff80f5f2e3afa8a5e323987d0.jpg

新的赖皮思路下,5.99M比8.03M 节省了25%+。实际上KV不会像测试代码这么夸张,但是提升还是有的。

转载于:https://my.oschina.net/u/2382040/blog/2236871

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值