Redis内存这样优化,性能炸裂

目录

  • 背景
  • Redis 内存管理
  • Redis 内存优化
  • 内存优化案例
  • 总结

背景

使用过 Redis 的同学应该都知道,它基于键值对(key-value)的内存数据库,所有数据存放在内存中,内存在 Redis 中扮演一个核心角色,所有的操作都是围绕它进行。

我们在实际维护过程中经常会被问到如下问题,比如数据怎么存储在 Redis 里面能节约成本、提升性能?Redis内存告警是什么原因导致?

本文主要是通过分析 Redis 内存结构、介绍内存优化手段,同时结合生产案例,帮助大家在优化内存使用,快速定位 Redis 相关内存异常问题。

Redis 内存管理

本章详细介绍 Redis 是怎么管理各内存结构的,然后主要介绍几个占用内存可能比较多的内存结构。首先我们看下 Redis 的内存模型。

Redis内存这样优化,性能炸裂_第1张图片

内存模型如上图:

  • **used_memory:**Redis 内存占用中最主要的部分,Redis 分配器分配的内存总量(单位是KB)(在编译时指定编译器,默认是 jemalloc),主要包含自身内存(字典、元数据)、对象内存、缓存,lua 内存。
  • **自身内存:**自身维护的一些数据字典及元数据,一般占用内存很低。
  • **对象内存:**所有对象都是 Key-Value 型,Key 对象都是字符串,Value 对象则包括 5 种类(String,List,Hash,Set,Zset),5.0 还支持 stream 类型。
  • **缓存:**客户端缓冲区(普通 + 主从复制 + pubsub)以及 aof 缓冲区。
  • **Lua 内存:**主要是存储加载的 Lua 脚本,内存使用量和加载的 Lua 脚本数量有关。
  • **used_memory_rss:**Redis 主进程占据操作系统的内存(单位是 KB),是从操作系统角度得到的值,如 top、ps 等命令。
  • **内存碎片:**如果对数据的更改频繁,可能导致 redis 释放的空间在物理内存中并没有释放,但 redis 又无法有效利用,这就形成了内存碎片。
  • **运行内存:**运行时消耗的内存,一般占用内存较低,在 10M 内。
  • **子进程内存:**主要是在持久化的时候,aof rewrite 或者 rdb 产生的子进程消耗的内存,一般也是比较小。

| 对象内存

对象内存存储 Redis 所有的 key-value 型数据类型,key 对象都是 string 类型,value 对象主要有五种数据类型 String、List、Hash、Set、Zset,不同类型的对象通过对应的编码各种封装,对外定义为 RedisObject 结构体。

RedisObject 都是由字典(Dict)保存的,而字典底层是通过哈希表来实现的。通过哈希表中的节点保存字典中的键值对,结构如下:

Redis内存这样优化,性能炸裂_第2张图片

来源:书籍《Redis 设计与实现》

为了达到极大的提高 Redis 的灵活性和效率,Redis 根据不同的使用场景来对一个对象设置不同的编码,从而优化某一场景下的效率。

各类对象选择编码的规则如下:

string(字符串):

  • **int:*整数且数字长度小于 20,直接记录在 ptr 里面
  • **embstr:**连续分配的内存(字符串长度小于等于 44 字节的字符串)
  • **raw:**动态字符串,大于 44 个字节的字符串,同时字符长度小于 512 M,512M 是字符串的大小限制

list(列表):

  • **ziplist:**元素个数小于 hash-max-ziplist-entries 配置(默认 512 个),同时所有值都小于 hash-max-ziplist-value 配置(默认 64 个字节)
  • **linkedlist:**当列表类型无法满足 ziplist 的条件时,Redis 会使用 linkedlist 作为列表的内部实现
  • **quicklist:**Redis 3.2 版本引入了 quicklist 作为 list 的底层实现,不再使用 linkedlist 和 ziplist 实现

set(集合):

  • **intset:**元素都是整数且元素个数小于 set-max-intset-entries 配置(默认 512 个)
  • **hashtable:**集合类型无法满足 intset 的条件时就会使用 hashtable

hash(hash列表):

  • **ziplist:**元素个数小于 hash-max-ziplist-entries 配置(默认 512 个),同时任意一个 value 的长度都小于 hash-max-ziplist-v

你可能感兴趣的:(redis,lua,缓存,java,spring)