Redis之内存

1.  内存消耗

    1.  如何查看内存统计

        info memory

        

 

 

        重点关注指标:used_memory_rss和used_memory以及它们的比值mem_fragmentation_ratio

        当mem_fragmentation_ratio>1,说明多出的部分内存没有用于数据存储,而是被内存碎片所消耗,如果两者相差很大,说明碎片率严重。

        当mem_fragmentation_ratio<1,这种情况一般出现在操作系统把Redis内存交换到硬盘导致,出现这种情况时要格外关注,由于磁盘速度远远慢于内存,Redis性能会变得很差,甚至僵死。

    2.  内存消耗划分

        

 

          1.  自身内存  忽略不计

          2.  对象内存  占用最大

              size of keys + size of values

              键对象都是字符串,应该避免使用过长的键

              值对象包含5种数据类型:字符串,哈希,列表,集合,有序集合

          3.  缓冲内存

              1.  客户端缓冲  所有接入到Redis服务器TCP连接的输入输出缓冲

                  1.  输入缓冲

                      输入缓冲最大1G

                  2.  输出缓冲    

                      通过参数client-output-buffer-limit控制

                      client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds>

                      1.  普通客户端

                          normal 0 0 0,如果有大量慢连接客户端接入时这部分内存消耗就不能消耗了,可以设置maxclients做限制

                      2.  从客户端

                          slave 268435456 67108864 60 主从节点不要部署在较差的网络环境下,如异地跨机房环境

                      3.  订阅客户端                                                  

              2.  复制积压缓冲区

                  repl-backlog-size  默认为1MB

                  主节点只有一个,可以修改为较大的缓冲区空间

              3.  AOF缓冲区

                  用于在Redis重写期间保存最近的写入命令  

          4.  内存碎片

              1.  Redis默认的内存分配器采用jemalloc

                  小:8byte,16byte,32byte,48byte 

                  大:4KB,8KB,12KB...

                  巨大:4MB,8MB,12MB...  

                  正常的碎片率在1.03左右

              2.  容易产生碎片的场景

                  1.  频繁做更新操作,例如频繁对已存在的键执行append,setrange等更新操作

                  2.  大量过期键删除,键对象过期删除后,释放的空间无法得到充分利用,导致碎片率上升

                  3.  存储的数据长短差异较大

              3.  出现高内存碎片的解决方式

                  数据对齐

                    数据尽量采用数字类型或者固定长度字符串

                  安全重启              

          5.  子进程内存消耗

              需要设置sysctl vm.overcommit_memory=1

              关闭THP

2.  内存管理

    1.  设置内存上限

        防止所用内存超过物理内存

        通过redis.conf文件配置maxmemory参数

    2.  动态设置内存

        config set maxmemory

        config get maxmemory

    3.  内存回收策略

        1.  删除到达过期时间的键对象

            1.  惰性删除

                客户端访问带有过期属性的keys,会执行删除并返回空。但是如果过期keys不访问,就不会被删除。                

            2.  定时任务删除

                              

        2.  内存使用达到maxmemory上限时触发内存溢出控制策略            

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策略。

3.  内存优化

    1.  控制字符串长度,减少创建redisObject内存分配次数

    2.  缩减键和值的长度

        对于key的优化

          使用单词简写方式优化内存占用

        对于value的优化

          过滤不必要的数据:想办法去掉一些不必要的属性

          精简数据:比如用户的会员类型:0,1,2,不要用VIP字符串

          数据压缩:对数据的内容进行压缩,比如:GZIP,Snappy

          使用性能好,内存占用小的序列化方式:protostuff,kryo

    3.  共享对象池

    4.  字符串优化

    5.  编码优化

    6.  控制键的数量

    7.  碎片优化
         

 

posted @ 2022-03-09 10:24  奋斗史  阅读(136)  评论(0)    收藏  举报