- 把大量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中,......
- 也可使用分组hash:如下,每100个用户ID共享一个hash key
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不会像测试代码这么夸张,但是提升还是有的。