首页 > 数据库 >Redis数据库笔记——内存分配器

Redis数据库笔记——内存分配器

时间:2025-01-04 15:32:50浏览次数:3  
标签:数据库 Redis 碎片 内存 分配器 jemalloc

大家好,这里是Good Note,关注 公主号:Goodnote,专栏文章私信限时Free。本文详细介绍Redis数据库的内存分配器,这是redis为什么这么快的原因,以及其作为内存数据库的内存管理策略。

在这里插入图片描述

文章目录

Redis 的内存分配器

Redis 的内存管理设计对性能和内存利用率有重要影响。其内存分配依赖底层的内存分配器和自身的一些优化机制。

内存分配器的作用

Redis 是一个基于内存的数据库,需要频繁地进行内存分配和释放操作。内存分配器的性能和设计直接影响 Redis 的整体性能。

  • 内存分配器的主要职责
    • 高效分配和释放内存。
    • 尽量减少内存碎片。
    • 提供线程安全的并发支持(多线程场景)。

Redis 支持的内存分配器

Redis 支持多种内存分配器,常见的有以下三种:

分配器优点缺点使用场景
jemalloc高性能、低碎片率、多线程支持小对象内存利用率稍逊于 tcmallocRedis 默认,推荐使用
libc简单易用,系统默认性能和碎片控制较差非高并发、低性能需求场景
tcmalloc极高并发性能、多线程优化对小对象内存利用不如 jemalloc 精细极高并发场景,可替代 jemalloc

Redis 的内存分配器设计和优化是其性能的重要保障。正确选择分配器并监控内存使用,可进一步提升系统稳定性和效率。

jemalloc
  • 默认分配器
    • 自 Redis 3.0 起,默认使用 jemalloc(jemalloc 是一款高性能内存分配器)。
  • 特点
    • 减少内存碎片:将内存分配按大小分类管理,分配和释放更加高效。
    • 并发优化:支持多线程并发分配,适合高并发场景。
    • 内存使用稳定:分配和释放的内存模式减少了碎片化问题。
  • 优点
    • 在高并发场景下性能优异。
    • 适合 Redis 的长连接、多命令操作模式。
  • 缺点
    • 对小对象内存的利用率可能不如其他分配器(如 tcmalloc)。
libc malloc
  • 简介
    • 标准 C 库中提供的默认内存分配器。
  • 特点
    • 实现简单,系统默认支持。
    • 内存碎片化问题较严重,不适合 Redis 的高并发场景。
  • 使用场景
    • 适合非高性能需求的场景。
  • 优点
    • 开发和使用简单,无需额外配置。
  • 缺点
    • 在高并发场景下性能较差。
    • 内存碎片化问题明显,不适合 Redis 的长时间运行场景。
tcmalloc
  • 简介

    • Google 开发的高效内存分配器。
  • 特点

    • 性能比 jemalloc 更高,但对小对象分配的内存利用率不如 jemalloc。
    • 适用于极高并发场景。每个线程有独立的内存分配缓存,减少线程间的锁竞争。
  • 使用场景

    • 在一些高并发业务中,可能会替代 jemalloc。
  • 优点

    • 高性能,适合 Redis 在超高并发下的使用。
  • 缺点

    • 对小对象内存管理不如 jemalloc 精细,可能会浪费内存。

Redis 内存分配器的选择

Redis 默认使用 jemalloc,兼顾性能和碎片化控制,是推荐的内存分配器。

选择其他分配器步骤
  1. 更改编译选项
    • 在 Redis 源码目录下,编译时指定 MALLOC 参数即可选择内存分配器。
    • 示例:
      make MALLOC=libc      # 使用 libc malloc
      make MALLOC=tcmalloc  # 使用 tcmalloc
      
  2. 查看当前分配器
    • 编译完成后,通过 ldd redis-server 命令查看当前分配器:
      ldd redis-server | grep malloc
      

jemalloc 的优势

作为默认分配器,jemalloc 在 Redis 中表现优异,具体优势包括:
jemalloc的优势体现在减小内存碎片方面。

jemalloc 在 64 位系统中,将内存空间划分为小、大、巨大三个范围;每个范围内又划分了许多小的内存块单位;当 Redis 存储数据时,会选择大小最合适的内存块进行存储。size单位是字节。

在这里插入图片描述

1. 减少内存碎片

  • jemalloc 按内存块大小将内存分为不同类别(class),分配时选择最合适的类别,避免内存碎片化。

2. 线程本地缓存

  • jemalloc 为每个线程维护独立的分配缓存,减少线程间竞争。

3. 内存分配效率高

  • jemalloc 的分配算法更适合 Redis 的高并发特性,可以快速分配和释放内存。

4. 内存统计

  • jemalloc 提供了详细的内存统计工具,可通过 Redis 的 DEBUG 命令查看:
    redis-cli DEBUG malloc-stats
    

Redis 内存管理机制

除了底层的内存分配器,Redis 还采用了多种机制优化内存使用:

内存预分配

  • Redis 会为某些数据结构(如 SDS)预先分配一定的内存,避免频繁的内存分配操作。
  • 优势
    • 提升性能,减少频繁分配和释放内存的开销。
    • 动态扩容:当内存不足时,会按一定比例扩展,减少扩容次数。

内存碎片

  • 问题
    • Redis 在分配和释放内存时,会出现碎片化问题。
  • 指标
    • jemalloc 内置了优化机制,通过内存池减少碎片。
    • 提供 INFO MEMORY 命令,可通过 mem_fragmentation_ratio 指标监控内存碎片率。
      mem_fragmentation_ratio:1.05  # 碎片率 1.05,表示有 5% 的碎片
      
      • 低于 1.2:正常。
      • 高于 1.5:可能存在严重碎片,需分析和优化。
  • 优化方案
    • 如果发现碎片率过高(如超过 1.5),可以尝试以下几种优化方法:
      1. 重启 Redis:重启 Redis 会清理内存中的碎片,重新进行内存分配。
      2. 调整 jemalloc 配置:优化 jemalloc 的参数设置,以提高内存使用效率。
      3. 定期清理空闲内存:在 Redis 长时间运行后,可以使用redis-cli memory purge 手动触发 jemalloc 的内存清理操作,减少碎片化。

内存淘汰机制

当 Redis 内存占用达到上限时,会根据设置的淘汰策略移除一些数据。

  • 常见策略
  1. 针对设置了过期时间的键

    • volatile-lru:仅对设置了过期时间的键,淘汰最近最少使用的键。
    • volatile-ttl:仅对设置了过期时间的键,淘汰剩余时间最短的键。
    • volatile-random:仅对设置了过期时间的键,随机淘汰。
    • volatile-lfu:仅对设置了过期时间的键,淘汰访问频率最低的键。
  2. 针对所有键

    • allkeys-lru:对所有键,淘汰最近最少使用的键。
    • allkeys-random:对所有键,随机淘汰。
    • allkeys-lfu:对所有键,淘汰访问频率最低的键。
  3. 无淘汰策略

    • noeviction:不进行淘汰,当内存超限时直接返回错误。

压缩内存结构

  • Redis 内部使用紧凑型数据结构(如 ziplist、intset)来节省内存。
  • 特点
    • 小规模数据(如小列表、小哈希)会使用压缩存储结构,减少内存开销。

Redis 内存优化建议

Redis 内存监控

Redis 提供了多种命令监控内存使用情况:

  1. 查看内存使用情况

    INFO MEMORY
    

    输出示例:

    used_memory:1048576          # 已使用的内存
    used_memory_peak:2097152     # 内存峰值
    mem_fragmentation_ratio:1.02 # 内存碎片率
    
  2. 查看键的内存占用

    MEMORY USAGE key
    
  3. 查看内存分配统计
    使用 jemalloc 的 jemalloc.stats.print

    redis-cli -p 6379 debug jemalloc stats
    

开启最大内存限制

  • 配置 maxmemory 参数,避免超出物理内存,报OOM(Out of Memory)错误。

分布式存储

  • 在高内存使用场景下,采用 Redis Cluster 扩展容量。

历史文章

MySQL数据库

  1. MySQL数据库笔记——数据库三范式
  2. MySQL数据库笔记——存储引擎(InnoDB、MyISAM、MEMORY、ARCHIVE)
  3. MySQL数据库笔记——常见的几种锁分类
  4. MySQL数据库笔记——索引介绍
  5. MySQL数据库笔记——事务介绍
  6. MySQL数据库笔记——索引结构之B+树
  7. MySQL数据库笔记——索引潜规则(回表查询、索引覆盖、索引下推)
  8. MySQL数据库笔记——索引潜规则(最左前缀原则)
  9. MySQL数据库笔记——常见慢查询优化方式
  10. MySQL数据库笔记——日志介绍
  11. MySQL数据库笔记——多版本并发控制MVCC
  12. MySQL数据库笔记——主从复制

Redis

  1. Redis数据库笔记——数据结构类型
  2. Redis数据库——Redis雪崩、穿透、击穿
  3. Redis数据库——内存淘汰机制

标签:数据库,Redis,碎片,内存,分配器,jemalloc
From: https://blog.csdn.net/haopingbiji/article/details/144915641

相关文章

  • Redis数据库——内存淘汰机制
    本文详细介绍Redis的8种内存淘汰机制。文章目录过期键删除策略内存淘汰机制内存限制设置常见策略Redis3.0的淘汰机制——近似LRU算法Redis4.0的新增的淘汰机制——LFU算法过期键删除策略Redis为管理内存,对设置了过期时间的键采用了以下三种删除策略......
  • 分披萨,关键在于吃货可能取左或者取右,利用max(递归调用左边,递归调用右边),相当于暴力获取
    #include<bits/stdc++.h>usingnamespacestd;intn;//披萨个数intpizza[500];//n个披萨大小longcache[500][500];intcheck(intid){  if(id<0)    id=n-1;//若取走披萨第一块的左边,则循环相当于最后一块  if(id>=n)  {    id=0;//......
  • IAP篇一 —— FLASH内存划分 & Target设置 附Bootloader
    目录前言一、存储器映射                1、外设寄存器                2、运存                3、用户代码区                        1、Mainmemory                ......
  • Python--内存分析工具汇总
    gdb下载libpython.py文件到服务器目录,比如:/root/utils/libpython.py进入gdb命令,加载好libpython(gdb)python>importsys>sys.path.insert(0,"/root/utils")>importlibpython>end(gdb)pypy-btpy-downpy-localspy-u......
  • 【内存安全】无文件恶意软件如何在不留痕迹的情况下运行
    在不断变化的网络安全领域中,威胁行为者总是在开发新的、更有效的方法来破坏系统。从基本的计算机病毒到如今复杂且持续性的威胁,恶意软件已经发展得极为迅速。随着无文件恶意软件的不断发展,恶意软件已逐渐成为传统恶意软件的更危险替代品,它使用基于文件的有效载荷在被黑客入侵的......
  • WinMemoryCleaner 电脑内存清理工具
    告别卡顿,让电脑飞起来!这款免费的RAM清理器利用了本机Windows功能来清理内存区域。有时候,程序在运行结束后并不会释放分配给它的内存,这会导致计算机的性能下降。换句话说,当你使用WindowsMemoryCleaner来优化内存时,可以继续进行其他工作,而无需浪费时间重新启动系统。该应用......
  • Redis 实现分布式锁
    文章目录引言一、Redis的两种原子操作1.1Redis的原子性1.2单命令1.3Lua脚本1.4对比单命令与Lua脚本二、Redis实现分布式锁2.1分布式锁的概念与需求2.1.1什么是分布式锁?2.1.2分布式锁的常见应用场景2.2基于Redis的分布式锁实现2.2.1锁的获取与释放2.2.2......
  • Linux实验报告14-Linux内存管理实验
    目录一:实验目的二:实验内容1、编辑模块的源代码mm_viraddr.c2、编译模块 3、编写测试程序mm_test.c 4、编译测试程序mm_test.c  5、在后台运行mm_test6、验证mm_viraddr模块一:实验目的(1)掌握内核空间、用户空间,虚拟地址空间的概念;(2)掌握linux内核中内存管理......
  • docker安装redis5
    1、拉取镜像dockerpullredis:5.02、docker运行容器dockerrun--nameredis5--networksome-network-dredis:5.03、docker-compose3.1、在当前目录下,创建conf目录,并添加redis.conf配置文件redis配置文件,可从:https://mirrors.huaweicloud.com/redis/下载相应的版......
  • Spring Boot引起的“堆外内存泄漏”排查及经验总结11
    背景为了更好地实现对项目的管理,我们将组内一个项目迁移到MDP框架(基于SpringBoot),随后我们就发现系统会频繁报出Swap区域使用量过高的异常。笔者被叫去帮忙查看原因,发现配置了4G堆内内存,但是实际使用的物理内存竟然高达7G,确实不正常。JVM参数配置是“-XX:MetaspaceSize=256M-......