美文网首页
第8章 理解内存

第8章 理解内存

作者: leon4ever | 来源:发表于2018-05-25 18:15 被阅读16次

    理解Redis内存消耗,管理和优化。

    1. 内存消耗

    1.1 内存使用统计

    通过info memory命令获取内存相关指标,重点指标:

    used_memory_rss  //操作系统角度Redis进程占用的物理内存总量
    used_memory     //Redis内部存储的所有数据内存占用量
    mem_fragmentation_ratio    //内存碎片率 >1时说明多出的内存被内存碎片消耗,<1时则要注意操作系统swap到硬盘
    

    1.2 内存消耗划分

    Redis内存消耗划分.jpg
    • 对象内存:存储用户所有key-value数据
    • 缓冲内存:客户端缓冲,复制积压缓冲区,AOF缓冲区
    • 内存碎片:默认内存分配器:jemalloc

    1.3 子进程内存消耗

    • Redis产生的子进程并不需要1倍的父进程内存(copy-on-write),实际消耗根据写入命令量决定
    • 需要设置sysctl vm.overcommit_memory=1允许内核可以分配所有物理内存,放置fork失败
    • 排查当前系统是否开启THP,建议关闭,防止内存过度消耗

    2. 内存管理

    2.1 设置内存上限

    • 用于缓存场景,超出上限时使用LRU释放空间
    • 防止所用内存超过服务器物理内存

    2.2 动态调整内存上限

    config set maxmemory
    

    动态修改内存,伸缩配置

    2.3 内存回收策略

    • 删除到达过期时间的键对象:惰性删除(客户端读取时检查删除)/定时任务删除
    • 内存溢出控制策略:
      1. noeviction:默认,拒绝写入
      2. volatile-lru:LRU删除超时键
      3. allkeys-lru:LRU删除所有键
      4. allkeys-random:随机删除所有键
      5. volatile-random:随机删除过期键
      6. volatile-ttl:删除最近将要过期数据

    注意:频繁执行回收内存成本很高,如果有从节点会同步,导致写放大

    3. 内存优化

    3.1 redisObject对象

    redisObject内部结构.jpg
    • type:数据类型
    • encoding:内部编码类型
    • lru:最后一次被访问的时间
    • refcount字段:记录当前对象被引用的次数
    • *ptr字段:与对象的数据内容相关

    3.2 缩减键值对象

    降低Redis内存使用最直接的方法:缩减key和value的长度
    选择高效的序列化工具

    3.3 共享对象池

    共享对象池是指Redis内部维护[0-9999]整数对象池。创建大量的整数类型redisObject存在内存开销。
    使用共享对象池,相同的数据内存使用降低30%以上。

    3.4 字符串优化

    Redis有自己内部的动态字符串:


    字符串结构体SDS.jpg

    由于预分配机制,同样的数据追加后内存消耗非常严重。(追加后预分配一倍容量)
    字符串重构:对json这种,可以使用hash这样的二级结构来饥饿省内存,支持字段的部分读取修改

    3.5 编码优化

    不同编码实现效率和空间的平衡
    编码类型转换过程不可逆,只能从小内存编码向大内存编码转换。

    3.6 控制键的数量

    hash结构降低键数量分析

    1. 根据键规模在客户端通过分组映射到一组hash对象中
    2. hash的field可用于记录原始key字符串
    3. hash的value保存原始值结构

    hash键和field键的设计:

    1. 键的离散度高时,按照字符串位截取
    2. 键离散度低,用哈希算法打散键,哈希field存储键的原始值
    3. 尽量减少hash键和field的长度,如使用部分键内容

    相关文章

      网友评论

          本文标题:第8章 理解内存

          本文链接:https://www.haomeiwen.com/subject/bpmujftx.html