当前位置: 首页 > article >正文

Redis的内存预分配策略

        Redis的内存预分配策略是一种优化手段,旨在减少频繁的内存分配和释放操作对性能的影响。以下是对Redis在使用各数据结构类型时内存变化以及触发底层数据结构变化条件的详细分析:

 

一、内存预分配策略概述

        Redis通过预先分配足够的内存,可以提高操作效率,尤其是在高并发场景下。Redis在某些数据结构(如字符串、列表、哈希等)存储数据时,不是每次都按照精确的内存需求分配,而是会额外预留一部分内存空间。这样做可以减少频繁的内存分配系统调用,提高数据结构扩展时的性能,并降低内存碎片化的风险。

二、各数据结构类型的内存变化

  1. 字符串(String)

    • Redis的字符串类型基于简单动态字符串(SDS)实现,支持动态扩容。
    • 当字符串长度超过当前分配的内存容量时,SDS会进行扩容。扩容后的新内存大小通常为当前长度的两倍,但也会根据具体情况进行调整。
    • 当字符串缩短时,预分配的空间不会立刻释放,但可以复用。
  2. 哈希(Hash)

    • Redis的哈希类型可以使用ziplist或hashtable存储。
    • 当ziplist的键值对数量或单个键值长度超过限制时,或者当hashtable的负载因子(填充率)超过阈值时,会自动触发底层存储结构的切换。
    • hashtable在扩容时,通常会按照两倍的大小进行扩展,并使用渐进式rehash分批次迁移数据,以降低性能抖动。
  3. 列表(List)

    • Redis的列表类型在底层使用quicklist(快速列表)存储,每个节点是一个ziplist。
    • 当新增元素导致ziplist的容量不足时,会触发扩容。如果ziplist达到配置的最大容量限制,则quicklist会拆分出一个新的节点。
    • 扩容是成比例的,通常为当前容量的两倍,以减少未来的扩容频率。
  4. 集合(Set)

    • Redis的集合类型可以使用intset(整数集合)或hashtable存储。
    • 当插入的元素类型超出intset的当前范围(如从int16扩展为int32)或集合中的元素数量或类型复杂度超出intset的范围时,会触发从intset到hashtable的转换。
    • hashtable在扩容时,也会按照两倍的大小进行扩展。
  5. 有序集合(Sorted Set)

    • Redis的有序集合可以使用ziplist或zskiplist(跳跃表)存储。
    • 当有序集合使用ziplist存储且现有内存空间不足以容纳新元素时,或者集合中的元素数量超过一定阈值(如128个)时,会触发从ziplist到zskiplist的转换。
    • zskiplist在扩容时,会通过动态调整索引层数来维持性能。

三、触发底层数据结构变化的条件

  1. 字符串(String)

    • 扩容条件:字符串长度超过当前分配的内存容量。
    • 缩容(复用)条件:字符串缩短时,预分配的空间不会立刻释放,但可以复用。
  2. 哈希(Hash)

    • 从ziplist切换到hashtable的条件:
      • ziplist的键值对数量超过限制(如512个)。
      • ziplist的单个键值长度超过限制(如64字节)。
      • hashtable的负载因子超过阈值(如1.0)。
    • hashtable扩容条件:负载因子超过阈值。
    • hashtable缩容条件:负载因子降到过低(如小于0.1)时,会触发缩容。
  3. 列表(List)

    • 扩容条件:新增元素导致ziplist的容量不足。
    • 拆分节点条件:ziplist达到配置的最大容量限制。
  4. 集合(Set)

    • 从intset切换到hashtable的条件:
      • 插入的元素类型需要更大的存储空间(如从int16升级到int32)。
      • 集合中的元素数量或类型复杂度超出intset的范围。
    • hashtable扩容条件:负载因子超过阈值。
  5. 有序集合(Sorted Set)

    • 从ziplist切换到zskiplist的条件:
      • 有序集合中的元素数量超过一定阈值(如128个)。
      • 有序集合中的任意元素长度超过一定阈值(如64字节)。
      • 新增元素导致内存空间不足。
    • zskiplist扩容条件:通过动态调整索引层数来维持性能。

        综上所述,Redis的内存预分配策略结合动态扩容机制,有效提高了性能并降低了内存分配开销。同时,Redis会根据不同的数据结构类型和存储需求,灵活地调整底层存储结构以适应数据的变化。


http://www.kler.cn/a/472320.html

相关文章:

  • jenkins 使用 ssh-agent向windows进行部署
  • flink cdc oceanbase(binlog模式)
  • Linux下实时监测双网卡的默认网卡并重新设置默认网卡
  • Python 中几个库的安装与测试
  • 嵌入式技术之Linux(Ubuntu) 一
  • 解决HBuilderX报错:未安装内置终端插件,是否下载?或使用外部命令行打开。
  • Ungoogled Chromium127 编译指南 MacOS篇(六)- 获取源代码
  • 用Rust构建高性能WebAssembly模块:性能调优与实际案例
  • 【网络安全技术与应用】(选修)实验4 网络扫描
  • android 启动页倒计时页面编写
  • 【Qt】QtConcurrent
  • 【UE5 C++课程系列笔记】21——弱指针的简单使用
  • 回归预测 | MATLAB实ELM-Adaboost多输入单输出回归预测
  • Mono里运行C#脚本23—mono_jit_exec
  • Python 批量生成Word 合同
  • xss-labs(level11-20)【通关技巧】
  • el-table 使用el-form 表单验证
  • STM32学习(十)
  • 嵌入式入门Day38
  • Android Process 问题:NoSuchMethodError,No static method myProcessName()
  • HTML5实现好看的博客网站、通用大作业网页模板源码
  • 第19章 数据库备份与恢复
  • 基于单片机的观赏类水草养殖智能控制系统的设计(论文+源码)
  • 采用标准化的方式开展设计-研发中运用设计模式
  • 中国科技统计年鉴EXCEL版(2021-2023年)-社科数据
  • SAP 01-初识AMDP(ABAP-Managed Database Procedure)