标签:
近来遇到一个问题,使用redis的哈希对象存储数据,发现redis的内存耗用是单纯存进去的数据的两倍多,希望能够找到有效的方法缩减这部分多出来的空间。
经过一番研究,是由于存储的时候,具体的存储结构使用的是hashtable来存储的,hashtable使用的内存大小是数据的两倍。一开始的时候怀疑是SDS预留出来的空间,但是经过测试,发现SDS在初始创建对象的时候是不会预留空间的,只会在出现修改的情况下预留出一倍的空间(数据小于1M时)。具体去查看源代码去查找问题,奈何功底太差,呵呵,没看出在什么地方还有预留的空间。希望知道的人不吝赐教。
由于我们的数据不是太大,仅仅只是value值的长度比默认的 hash-max-ziplist-value 多出了20个字节。所以,就在考虑着增大这个值,使用ziplist来存储数据。结果证明,确实是比hashtable少用了一半的空间。也就是说内存方面的问题确实可以通过这个问题解决,虽然没有弄明白hashtable多用出来的空间用在了什么地方。
但是,还有一个问题需要考虑,那就是ziplist每次添加或者删除元素都会出现内存移动的问题,那么ziplist的效率是否跟hashtable会有比较大的差距。于是就有了下边的测试:
1. 测试机器
centos虚拟机,2G内存。
2. redis版本
redis-2.8.19,aof与rdb全部关闭。
3. 测试程序
java,使用20个线程连接redis操作数据。
4. 数据
数据量在140w大小,每条数据含有4条记录,与实际情况相近偏大一点。每条记录key为20个字节,value为86个字节。
5. 结果
除初始化使用了140条数据,剩余的操作都是使用了20w的数据。
初始化(140w数据) | hmset | hgetall | hmset + hgetall | hdel | hset | 内存消耗 | |
hashtable | 168秒 | 24秒 | 24秒 | 49秒 | 24秒 | 23秒 | 1.29G |
ziplist | 166秒 | 24秒 | 24秒 | 47秒 | 23秒 | 23秒 | 620M |
看上面的结果,hashtable与ziplist在数据量很小的情况下,基本上性能是相差不多的,可以在数据量很小的情况下使用ziplist来缩小使用的内存,性能上是没有太大问题的。
分析其原因,应该是使用ziplist仅仅只是在操作记录的时候进行了一次的memmove,但是由于数据太小,消耗也就很小了。
当然,这个我暂时还没有测试单条数据在大数据量的情况下的性能,在这种情况下性能是否还相差不多就不好说了。
如果上面的测试存在问题,请不吝赐教。
Redis中hash之ziplist与hashtable性能简单对比
标签:
原文地址:http://www.cnblogs.com/dearway/p/4439111.html