设为首页 收藏本站
查看: 797|回复: 0

[经验分享] redis 内存优化

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2016-7-21 09:24:18 | 显示全部楼层 |阅读模式


最近做的一个系统大量使用redis,我们将大量的用户信息存放在redis中,内存一申请就是几百G,体量也是相当庞大。所以我们也在不断的想方法优化减少redis的内存使用,把我们的优化实践也分享出来。
采用Hash代替<K,V>键值对存储

因为是存放用户维度的数据,用户id(uid)往往会作为key,而一个用户会有多个信息,比如年龄,生日等等,比较容易想到的存储结构会采用Hash,将一个用户的多个信息作为hash里的不同field来存放
善用Hash,List,ZSet的ziplist压缩特性

Redis针对Hash,List,ZSet都实现了ziplist的压缩存储,可以通过配置最大元素不超过512,每个元素大小不超过64bytes,来判断是否要采用 !ziplist压缩格式 存储。

注意:虽然这个ziplist是否启用做成了配置参数,但对这个配置参数的修改要谨慎,因为ziplist是一个连续的数组空间,查找效率不是O(1)的,如果设置元素超过512太多,可能导致查找效率降低,反而影响性能。那为什么Redis会采用512*64bytes这样的默认配置呢?据说是这个大小可以被加载进CPU的Cache里,所以即使不是O(1),查找效率也是很快的。
优先使用数字类型,比String类型省空间

在Redis的内部,不管是数字类型,String类型,都会统一用一个叫redisObject的对象做一层封装:

typedef struct redisObject {    unsigned type:4;    unsigned encoding:4;    unsigned lru:LRU_BITS; /* lru time (relative to server.lruclock) */
    int refcount;    void *ptr;
} robj;

可见,一个简简单单的”hello world”在redis里都不是直接11个bytes就搞定的,还有很多附加的属性,比如引用计数(内存回收)refcount,lru清理等信息。

但如果使用了上面提到的ziplist,redis对ziplist里元素做了裁剪,让数据更紧凑,所以针对数字,做了一些特别处理:

* |11000000| - 1 byte* Integer encoded as int16_t (2 bytes).
* |11010000| - 1 byte* Integer encoded as int32_t (4 bytes).
* |11100000| - 1 byte* Integer encoded as int64_t (8 bytes).
* |11110000| - 1 byte* Integer encoded as 24 bit signed (3 bytes).
* |11111110| - 1 byte* Integer encoded as 8 bit signed (1 byte).
* |1111xxxx| - (with xxxx between 0000 and 1101) immediate 4 bit integer.
* Unsigned integer from 0 to 12. The encoded value is actually from* 1 to 13 because 0000 and 1111 can not be used, so 1 should be
* subtracted from the encoded 4 bit value to obtain the right value.

先用1byte来表示不同的encode,针对大小不同的数字,分别采用不一样的内存空间来存储,比如0-127就是2个字节,128-32768就是4个字节等等。所以算下来,和String相比,大部分情况下更省内存。

另外,如果不是采用ziplist的存储方式,而是直接用redisObject这样相对庞大的对象存储呢?

如果能用数字,还是尽量使用数字类型,并且是小于10000的数字最好,因为:

#define OBJ_SHARED_INTEGERS 10000

redis考虑到redisObject这个庞大的对象占用过多内存的因素,将10000以下数字的redisObject做了一个对象池,其他地方都通过指针(4/8bytes)引用这个池里的redisObject,而不是各自存一份。

注: 以上都是针对Redis 3.2之前版本的分析,因为Redis 3.2对内存优化这部分做了很多改进,具体的改进点还未了解清楚。

最后,对坚持看完的同学送上一个非常有用的Redis内存分析工具: redis-rdb-tools,结合bgsave的dump文件,分析redis里的数据,可以看到底层存储是用的什么数据结构,占用了多少空间等信息。




运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-247206-1-1.html 上篇帖子: redis.conf配置详细解析 下篇帖子: redis cluster 添加 删除 重分配 节点
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表