MST

星途 面试题库

面试题:Redis内存优化技巧之高级难度

假设Redis实例内存使用持续增长,接近物理内存上限,你会采取哪些优化手段来降低内存使用?从数据结构优化、配置参数调整等方面进行阐述。
27.2万 热度难度
数据库Redis

知识考点

AI 面试

面试题答案

一键面试

数据结构优化

  1. 字符串优化
    • 对于短字符串,Redis采用embstr编码方式存储,这种方式比raw编码更节省内存。确保尽可能让短字符串使用embstr编码,比如通过合理设置redis.conf中的hash-max-ziplist-entrieshash-max-ziplist-value等相关参数(对于包含短字符串的哈希结构),当哈希对象的元素个数和元素大小在一定范围内时,会使用压缩列表(ziplist)这种紧凑的数据结构存储,节省内存。
    • 避免不必要的长字符串存储,如果长字符串内容可拆分,考虑拆分成多个短字符串分别存储,在需要时再组合。
  2. 哈希结构优化
    • 尽量使用哈希结构存储相关数据集合,因为哈希结构在存储大量相关字段时比多个独立的键值对更节省内存。例如,将用户的多个属性(如姓名、年龄、地址等)存储在一个哈希结构中,而不是为每个属性创建一个单独的键值对。
    • 合理设置哈希结构存储的临界值参数,如hash-max-ziplist-entrieshash-max-ziplist-value,当哈希对象元素个数和元素值大小在设定范围内时,Redis会使用压缩列表存储哈希对象,大大节省内存。
  3. 列表结构优化
    • 如果列表中的元素是简单的整数或短字符串,且列表长度较短,可以考虑使用ziplist编码方式。通过设置list-max-ziplist-entrieslist-max-ziplist-value参数来控制列表何时使用ziplist编码。当列表元素个数和元素值大小满足条件时,Redis会采用更紧凑的ziplist存储,减少内存占用。
    • 对于只需要存储最新元素的场景,可以使用固定长度的列表,当新元素加入时,移除旧元素,避免列表无限增长导致内存占用过高。
  4. 集合结构优化
    • 对于包含少量整数元素的集合,使用intset(整数集合)编码方式更节省内存。合理设置set-max-intset-entries参数,当集合中的元素个数在这个范围内且都是整数时,Redis会采用intset编码存储集合,减少内存开销。
    • 如果集合元素是字符串,尽量保持元素的短小,避免长字符串元素导致内存浪费。
  5. 有序集合结构优化
    • 对于元素个数较少且成员和分数都比较小的有序集合,Redis会使用ziplist编码。通过设置zset-max-ziplist-entrieszset-max-ziplist-value参数来控制有序集合何时使用ziplist编码。这样在满足条件时,会以更紧凑的方式存储有序集合,降低内存使用。
    • 定期清理有序集合中不再需要的元素,避免有序集合不断增长占用过多内存。

配置参数调整

  1. 内存淘汰策略
    • 合理设置maxmemory-policy参数,根据业务需求选择合适的内存淘汰策略。例如,如果业务允许部分数据丢失,可以选择volatile-lru(在设置了过期时间的键中,使用LRU算法淘汰键)或allkeys-lru(在所有键中,使用LRU算法淘汰键)策略,优先淘汰最近最少使用的键,以释放内存。如果业务要求数据不能丢失,但可以接受缓存穿透等情况,可选择noeviction策略,当内存达到上限时,拒绝写入操作,但这样可能导致部分请求失败,需谨慎使用。如果业务对时效性要求不高,可选择volatile-ttl策略,优先淘汰剩余时间(TTL)短的键。
  2. 过期时间设置
    • 为键合理设置过期时间,避免长期占用内存。对于一些时效性较强的数据,如缓存的网页数据、验证码等,设置合适的过期时间,过期后Redis会自动删除这些键,释放内存。
    • 可以通过批量设置过期时间的方式,提高效率。例如,在批量插入数据时,同时为一批相关键设置相同的过期时间。
  3. 碎片整理
    • 开启内存碎片整理功能,通过设置activerehashing yes,Redis会定期对内存进行碎片整理,减少内存碎片,提高内存利用率。但需要注意的是,开启此功能可能会对性能有一定影响,需根据实际业务情况评估。
  4. 客户端连接优化
    • 合理设置timeout参数,设置客户端连接的超时时间。对于长时间不活跃的客户端连接,及时关闭,避免占用不必要的内存资源。
    • 限制客户端连接数,通过设置maxclients参数,防止过多的客户端连接导致内存耗尽。根据服务器的资源和业务需求,设置一个合理的客户端连接上限。