提一下string常见的优化方法
尽量使value为纯数字
这样字符串会转化成int类型减少内存的使用.
redis.c
=========
37 void setCommand(redisClient *c) {
38 c->argv[2] = tryObjectEncoding(c->argv[2]);
39 setGenericCommand(c,0,c->argv[1],c->argv[2],NULL);
40 }
object.c =======
275 o->encoding = REDIS_ENCODING_INT;
276 sdsfree(o->ptr);
277 o->ptr = (void*) value;
=========
37 void setCommand(redisClient *c) {
38 c->argv[2] = tryObjectEncoding(c->argv[2]);
39 setGenericCommand(c,0,c->argv[1],c->argv[2],NULL);
40 }
object.c =======
275 o->encoding = REDIS_ENCODING_INT;
276 sdsfree(o->ptr);
277 o->ptr = (void*) value;
可以看到sds被释放了,数字被存储在指针位上,所以对于set hello 1111111就只需要48字节的内存.
调整REDIS_SHARED_INTEGERS
如果value数字小于宏REDIS_SHARED_INTEGERS(默认10000),则这个redisObject也都节省了,使用redis Server启动时的share Object.
object.c
=======
269 if (server.maxmemory == 0 && value >= 0 && value < REDIS_SHARED_INTEGERS &&
270 pthread_equal(pthread_self(),server.mainthread)) {
271 decrRefCount(o);
272 incrRefCount(shared.integers[value]);
273 return shared.integers[value];
274 }
=======
269 if (server.maxmemory == 0 && value >= 0 && value < REDIS_SHARED_INTEGERS &&
270 pthread_equal(pthread_self(),server.mainthread)) {
271 decrRefCount(o);
272 incrRefCount(shared.integers[value]);
273 return shared.integers[value];
274 }
这样一个set hello 111就只需要32字节,连redisObject也省了.所以对于value都是小数字的应用,适当调大REDIS_SHARED_INTEGERS这个宏可以很好的节约内存.
出去kv之外,dict的bucket逐渐变大也需要消耗内存,bucket的元素是个指针(dictEntry**), 而bucket的大小是超过key个数向上求整的2的n次方,对于1w个key如果rehash过后就需要16384个bucket.
开始string类型的容量预估测试, 脚本如下
#! /bin/bash
redis-cli info|grep used_memory:
for (( start = 10000; start < 30000; start++ ))
do
redis-cli set a$start baaaaaaaa$start > /dev/null
done
redis-cli info|grep used_memory:
redis-cli info|grep used_memory:
for (( start = 10000; start < 30000; start++ ))
do
redis-cli set a$start baaaaaaaa$start > /dev/null
done
redis-cli info|grep used_memory:
根据上面的总结我们得出string公式
string类型的内存大小 = 键值个数 * (dictEntry大小 + redisObject大小 + 包含key的sds大小 + 包含value的sds大小) + bucket个数 * 4
下面是我们的预估值
>>> 20000 * (16 + 16 + 16 + 32) + 32768 * 4
1731072
1731072
运行一下测试脚本
hoterran@~/Projects/redis-2.4.1$ bash redis-mem-test.sh
used_memory:564352
used_memory:2295424
used_memory:564352
used_memory:2295424
计算一下差值
>>> 2295424 - 564352
1731072
1731072
都是1731072,说明预估非常的准确, ^_^