redis 查看所有key内存和Key为什么不易过大

Redis教程分享之Redis内存容量的预估和优化 | 爱酷学习网博客
当前位置: &
14,037 阅读此文人 -
Redis内存容量的预估和优化
Redis是个内存全集的数据库不存在部分数据在磁盘部分数据在内存里的情况所以提前预估和节约内存非常重要本文将以最常用的和两类数据结构在内存分配器下的内存容量预估和节约内存的方法
先说说传说中解决内存问题的默认分配器功能和非常的相识在版本被引入在中 提到内节约的内存使用相比的需要在每个内存外附加一个额外的字节内存块可以通过 函数获得指针实际指向的内存大小这样里的每个或者都可以节约个字节不少阿
下面是左边是用户申请内存范围右边是实际申请的内存大小这张表后面会用到
size class:4
size class:8
– 16
size class:16
– 32
size class:32
– 48
size class:48
– 64
size class:64
– 80
size class:80
– 96
size class:96
size class:112
size class:128
size class:192
size class:256
size class:320
size class:384
size class:448
size class:512
size class:768
size class:1024
size class:1280
size class:1536
size class:1792
size class:2048
size class:2304
size class:2560
string类型看似简单但还是有几个可优化的点先来看一个简单的命令所添加的数据结构
一个命令最终中间会的我们不考虑会产生个对象一个字节一个用于存储还有 一个字节还有一个存储的对象除了包含字符串本生之外还有一个和额外的一个字节作为字符串结尾共个字节
51 sds sdsnewlen(const void *init, size_t initlen) {
struct sdshdr *
sh = zmalloc(sizeof(struct sdshdr)+initlen+1);
<div class=crayon-num data-line=crayon-591bba<div class="crayon-num crayon-striped-num" data-line=crayon-591bba<div class=crayon-num data-line=crayon-591bba<div class="crayon-num crayon-striped-num" data-line=crayon-591bba<div class=crayon-num data-line=crayon-591bba<div class="crayon-num crayon-striped-num" data-line=crayon-591bba<div class=crayon-num data-line=crayon-591bba
51 sds sdsnewlen(const void *init, size_t initlen) {&52
struct sdshdr *sh;&53&54
sh = zmalloc(sizeof(struct sdshdr)+initlen+1);
39 struct sdshdr {
char buf[];
<div class=crayon-num data-line=crayon-591bba<div class="crayon-num crayon-striped-num" data-line=crayon-591bba<div class=crayon-num data-line=crayon-591bba<div class="crayon-num crayon-striped-num" data-line=crayon-591bba<div class=crayon-num data-line=crayon-591bba<div class="crayon-num crayon-striped-num" data-line=crayon-591bba<div class=crayon-num data-line=crayon-591bba<div class="crayon-num crayon-striped-num" data-line=crayon-591bba<div class=crayon-num data-line=crayon-591bba<div class="crayon-num crayon-striped-num" data-line=crayon-591bba<div class=crayon-num data-line=crayon-591bba
39 struct sdshdr {&40
int len;&41
int free;&42
char buf[];&43&};
根据那张表这个命令最终申请的内存为一共字节注意如果或者的字符串长度字节超过字节则实际申请的内存大小字节
提一下常见的优化方法
尽量使为纯数字
这样字符串会转化成类型减少内存的使用
37 void setCommand(redisClient *c) {
c-&argv[2] = tryObjectEncoding(c-&argv[2]);
setGenericCommand(c,0,c-&argv[1],c-&argv[2],NULL);
<div class=crayon-num data-line=crayon-591bba<div class="crayon-num crayon-striped-num" data-line=crayon-591bba<div class=crayon-num data-line=crayon-591bba<div class="crayon-num crayon-striped-num" data-line=crayon-591bba<div class=crayon-num data-line=crayon-591bba<div class="crayon-num crayon-striped-num" data-line=crayon-591bba<div class=crayon-num data-line=crayon-591bba
37 void setCommand(redisClient *c) {&38
c-&gt;argv[2] = tryObjectEncoding(c-&gt;argv[2]);&39
setGenericCommand(c,0,c-&gt;argv[1],c-&gt;argv[2],NULL);&40 }
object.c =======
o-&encoding = REDIS_ENCODING_INT;
sdsfree(o-&ptr);
o-&ptr = (void*)
<div class=crayon-num data-line=crayon-591bba<div class="crayon-num crayon-striped-num" data-line=crayon-591bba<div class=crayon-num data-line=crayon-591bba<div class="crayon-num crayon-striped-num" data-line=crayon-591bba<div class=crayon-num data-line=crayon-591bba
o-&gt;encoding = REDIS_ENCODING_INT;&276
sdsfree(o-&gt;ptr);&277
o-&gt;ptr = (void*) value;
可以看到被释放了数字被存储在指针位上所以对于就只需要字节的内存
如果数字小于宏默认则这个也都节省了使用启动时的
269 if (server.maxmemory == 0 && value &= 0 && value & REDIS_SHARED_INTEGERS &&
pthread_equal(pthread_self(),server.mainthread)) {
decrRefCount(o);
incrRefCount(shared.integers[value]);
return shared.integers[value];
1234567891011
269 if (server.maxmemory == 0 &amp;&amp; value &gt;= 0 &amp;&amp; value &lt; REDIS_SHARED_INTEGERS &amp;&amp;&270
pthread_equal(pthread_self(),server.mainthread)) {&271
decrRefCount(o);&272
incrRefCount(shared.integers[value]);&273
return shared.integers[value];&274 }
这样一个就只需要字节连也省了所以对于都是小数字的应用适当调大这个宏可以很好的节约内存
出去之外的逐渐变大也需要消耗内存的元素是个指针而的大小是超过个数向上求整的的次方对于个如果过后就需要个
开始类型的容量预估测试脚本如下
#! /bin/bash
redis-cli info|grep used_memory:
for (( start = 10000; start & 30000; start++ ))
redis-cli set a$start baaaaaaaa$start & /dev/null
redis-cli info|grep used_memory:
12345678910111213
#! /bin/bash&redis-cli info|grep used_memory:&for (( start = 10000; start &lt; 30000; start++ ))&do&redis-cli set a$start baaaaaaaa$start &gt; /dev/null&done&redis-cli info|grep used_memory:
根据上面的总结我们得出公式
string类型的内存大小 键值个数 大小 大小 包含的大小 包含的大小个数
下面是我们的预估值
&&& 20000 * (16 + 16 + 16 + 32) + 32768 * 4
运行一下测试脚本
hoterran@~/Projects/redis-2.4.1$ bash redis-mem-test.sh
used_memory:564352
used_memory:2295424
计算一下差值
&&& 2295424 &#
都是说明预估非常的准确
已经解释的 效果可以大量的节约内存的使用对于一个普通的和只需要额外的个字节来 存储另外的也只需要额外的个字节头尾来存储的个数和结束符
zipmap类型的内存大小 个数 大小 大小 包含的大小 的总大小个数
开始容量预估测试个其中每个里包含个这里的长度为字节
#! /bin/bash
redis-cli info|grep used_memory:
for (( start = 100; start & 200; start++ ))
for (( start2 = 100; start2 & 400; start2++ ))
redis-cli hset test$start a$start2 &#21; & /dev/null
redis-cli info|grep used_memory:
这里是同时申请的的大小是字节根据上面可以看出实际申请的内存为另外的是所以总的预估大小为
&&& 100 * (16 + 16 + 16 + 2560) + 128 * 4
运行一下上面的脚本
hoterran@~/Projects/redis-2.4.1$ bash redis-mem-test-zipmap.sh
used_memory:555916
used_memory:817228
计算一下差值
&&& 817228 &#
是的完全一样预估很准确
另外扯扯的一个缺陷用于记录个数的只有一个字节超过个后则无法记录需要遍 历整个才能获得的个数而我们现在常把设置为这样超过个 之后每次效率都很差
if (zm[0] & ZIPMAP_BIGLEN) {
len = zm[0];
//&span style="font-family: 宋体;"&小于&/span&&span style="font-family: Times New R"&254,&/span&&span style="font-family: 宋体;"&直接返回结果&/span&
unsigned char *p = zipmapRewind(zm);
//&span style="font-family: 宋体;"&遍历&/span&&span style="font-family: Times New R"&zipmap&/span&
while((p = zipmapNext(p,NULL,NULL,NULL,NULL)) != NULL) len++;
/* Re-store length if small enough */
if (len & ZIPMAP_BIGLEN) zm[0] =
<div class=crayon-num data-line=crayon-591bba<div class="crayon-num crayon-striped-num" data-line=crayon-591bba<div class=crayon-num data-line=crayon-591bba<div class="crayon-num crayon-striped-num" data-line=crayon-591bba<div class=crayon-num data-line=crayon-591bba<div class="crayon-num crayon-striped-num" data-line=crayon-591bba<div class=crayon-num data-line=crayon-591bba<div class="crayon-num crayon-striped-num" data-line=crayon-591bba<div class=crayon-num data-line=crayon-591bba<div class="crayon-num crayon-striped-num" data-line=crayon-591bba<div class=crayon-num data-line=crayon-591bba<div class="crayon-num crayon-striped-num" data-line=crayon-591bba<div class=crayon-num data-line=crayon-591bba<div class="crayon-num crayon-striped-num" data-line=crayon-591bba<div class=crayon-num data-line=crayon-591bba<div class="crayon-num crayon-striped-num" data-line=crayon-591bba<div class=crayon-num data-line=crayon-591bba
if (zm[0] &lt; ZIPMAP_BIGLEN) {&355
len = zm[0];
//&span style="font-family: 宋体;"&小于&/span&&span style="font-family: Times New R"&254,&/span&&span style="font-family: 宋体;"&直接返回结果&/span&&356
} else {&357
unsigned char *p = zipmapRewind(zm);
//&span style="font-family: 宋体;"&遍历&/span&&span style="font-family: Times New R"&zipmap&/span&&358
while((p = zipmapNext(p,NULL,NULL,NULL,NULL)) != NULL) len++;&359&360
/* Re-store length if small enough */&361
if (len &lt; ZIPMAP_BIGLEN) zm[0] = len;&362
简单把设置为个字节可以存储个可以解决这个问题,这会破坏的兼容性这个功能改进推迟到版本另外这个缺陷可能是的机器消耗过高的原因之一
你喜欢下面的文章吗!Do you like the following articles?
爱酷学习网博客 ,
IT视频教程交流学习
扫描二维码,手机访问网站【求解答】redis自动过期的key占内存的问题【redis吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:1,127贴子:
【求解答】redis自动过期的key占内存的问题收藏
redis中有一个很大的key,自动过期后所占内存和未过期时占的内存一样吗?求高人解答
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或帐号:密码:下次自动登录{url:/nForum/slist.json?uid=guest&root=list-section}{url:/nForum/nlist.json?uid=guest&root=list-section} 产生错误的可能原因:指定的文章不存在或链接错误}

我要回帖

更多关于 redis 模糊查询key 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信