Redis学习--理解内存

内存消耗
  • 内存使用统计
    info memory
info memory详细解释

当mem_fragmentation_ratio>1时,说明used_memory_rss-used_memory多出的部分内存并没有用于数据存储,而是被内存碎片所消耗,如果两者相差很大,说明碎片率严重。
当mem_fragmentation_ratio<1时,这种情况一般出现在操作系统把Redis内存交换(Swap)到硬盘导致,出现这种情况时要格外关注,由于硬盘速度远远慢于内存,Redis性能会变得很差,甚至僵死。

  • 内存消耗划分
    自身内存+对象内存(内存占用最大的一块)+缓冲内存+内存碎片(数据对齐,安全重启)


    Redis内存消耗划分
  • 子进程内存消耗
    1.Redis产生的子进程并不需要消耗1倍的父进程内存,实际消耗根据期间写入命令量决定,但是依然要预留出一些内存防止溢出。
    2.需要设置sysctl vm.overcommit_memory=1允许内核可以分配所有的物理内存,防止Redis进程执行fork时因系统剩余内存不足而失败。
    3.排查当前系统是否支持并开启THP,如果开启建议关闭,防止copy-onwrite期间内存过度消耗。
内存管理
  • 设置内存上限
    Redis使用maxmemory参数限制最大可用内存。

1.用于缓存场景,当超出内存上限maxmemory时使用LRU等删除策略释放空间。
2.防止所用内存超过服务器物理内存。

服务器分配4个4GB的Redis进程
  • 动态调整内存上限
    Redis的内存上限可以通过config set maxmemory进行动态修改,即修改最大可用内存。
  • 内存回收策略

删除到达过期时间的键对象。
内存使用达到maxmemory上限时触发内存溢出控制策略。

1.删除过期键对象
惰性删除:惰性删除用于当客户端读取带有超时属性的键时,如果已经超过键设置的过期时间,会执行删除操作并返回空
定时任务删除:Redis内部维护一个定时任务,默认每秒运行10次(通过配置hz控制),采用了自适应算法,根据键的过期比例、使用快慢两种速率模式回收键.


定时任务删除过期键逻辑
  • 内存溢出控制策略(Redis支持6种策略)
    1)noeviction:默认策略,不会删除任何数据,拒绝所有写入操作并返回客户端错误信息(error)OOM command not allowed when used memory,此时Redis只响应读操作。
    2)volatile-lru:根据LRU算法删除设置了超时属性(expire)的键,直到腾出足够空间为止。如果没有可删除的键对象,回退到noeviction策略。
    3)allkeys-lru:根据LRU算法删除键,不管数据有没有设置超时属性,直到腾出足够空间为止。
    4)allkeys-random:随机删除所有键,直到腾出足够空间为止。
    5)volatile-random:随机删除过期键,直到腾出足够空间为止。
    6)volatile-ttl:根据键值对象的ttl属性,删除最近将要过期数据。如果没有,回退到noeviction策略。
内存优化
  • redisObject对象


    redisObject内部结构
  • 缩减键值对象
    key长度:如在设计键时,在完整描述业务情况下,键值越短越好。如user:{uid}:friends:notify:{fid}可以简化为u:{uid}:fs:nt:{fid}。
    value长度:值对象缩减比较复杂,常见需求是把业务对象序列化成二进制数组放入Redis。


    Java常见序列化组件占用内存空间对比

    使用GZIP压缩后的json可降低约60%的空间。推荐使用Google的Snappy压缩工具,在特定的压缩率情况下效率远远高于GZIP等传统压缩工具

  • 共享对象池
    共享对象池是指Redis内部维护[0-9999]的整数对象池。创建大量的整数类型redisObject存在内存开销,每个redisObject内部结构至少占16字节,甚至超过了整数自身空间消耗。所以Redis内存维护一个[0-9999]的整数对象池,用于节约内存。
    注:当设置maxmemory并启用LRU相关淘汰策略如:volatile-lru,allkeys-lru时,Redis禁止使用共享对象池
  • 字符串优化
    1.字符串结构


    字符串结构体SDS

    2.预分配机制


    字符串内存预分配测试

    尽量减少字符串频繁修改操作如append、setrange,改为直接使用set修改字符串,降低预分配带来的内存浪费和内存碎片化。
    3.字符串重构
    使用字符串和hash结构测试内存表现
  • 编码优化
    type和encoding对应关系表

    hash、list、set、zset内部编码可以按照需要进行配置
    ziplist编码:
    ziplist内部结构

    使用ziplist压缩编码的原则:追求空间和时间的平衡。(降低内存占用)
    intset编码:
    intset编码是集合(set)类型编码的一种,内部表现为存储有序、不重复的整数集。
    intset内部结构
  • 控制键的数量


    客户端维护哈希分组降低键规模

    hash的field可用于记录原始key字符串,方便哈希查找
    hash的value保存原始值对象,确保不要超过hash-max-ziplist-value限制。

总结

1)Redis实际内存消耗主要包括:键值对象、缓冲区内存、内存碎片。
2)通过调整maxmemory控制Redis最大可用内存。当内存使用超出时,根据maxmemory-policy控制内存回收策略。
3)内存是相对宝贵的资源,通过合理的优化可以有效地降低内存的使用量,内存优化的思路包括:

  • 精简键值对大小,键值字面量精简,使用高效二进制序列化工具。
  • 使用对象共享池优化小整数对象。
  • 数据优先使用整数,比字符串类型更节省空间。
  • 优化字符串使用,避免预分配造成的内存浪费。
  • 使用ziplist压缩编码优化hash、list等结构,注重效率和空间的平衡。
  • 使用intset编码优化整数集合。
  • 使用ziplist编码的hash结构降低小对象链规模。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容

  • 参考来源 Redis的内存优化 Redis所有的数据都在内存中,而内存又是非常宝贵的资源。对于如何优化内存使用一直...
    秦汉邮侠阅读 1,286评论 0 2
  • Redis的内存优化 声明:本文内容来自《Redis开发与运维》一书第八章,如转载请声明。 Redis所有的数据都...
    meng_philip123阅读 18,887评论 2 29
  • 声明:本文内容来自《Redis开发与运维》一书第八章,如转载请声明。Redis所有的数据都在内存中,而内存又是非常...
    yoqu阅读 1,497评论 0 2
  • 转载:可能是目前最详细的Redis内存模型及应用解读 Redis是目前最火爆的内存数据库之一,通过在内存中读写数据...
    meng_philip123阅读 1,437评论 1 22
  • 人与人交往,更多的不是改变对方,而是接受对方,如果光想着改变对方,那不是生活,那是战争。命运不是一个机遇问题,而是...
    登泓听香阅读 174评论 0 0