如何优化 Redis 内存使用

如何优化 Redis 内存使用

  • 一、简介
    • 1.1 简介
    • 1.2 内存优化意
  • 二、内存使用分析
    • 2.1 Redis内存使用机制
    • 2.2 Redis内存使用瓶颈分析
  • 三、Redis 内存使用优化
    • 3.1 数据压缩
      • 3.1.1 压缩规则
      • 3.1.2 压缩策略
    • 3.2 内存回收
      • 3.2.1 内存淘汰策略
      • 3.2.2 定期清除过期数据
    • 3.3 性能优化
      • 3.3.1 合理设置缓存失效时间
      • 3.3.2 使用内存优化工具
  • 四、应对方案
    • 4.1 内存升级
    • 4.2 数据分片
  • 五、Redis高级优化
    • 5.1 预热技术
    • 5.2 持久化技术
      • 5.2.1 RDB
      • 5.2.2 AOF

一、简介

1.1 简介

Redis 是一个快速的非关系型数据存储系统,其特点是支持多种数据结构以及高性能。Redis 可用于缓存、队列、发布/订阅、排行榜等多种应用场景。

1.2 内存优化意

Redis 将所有数据存储在内存中,因此内存的合理使用至关重要。合理优化内存使用可以提升 Redis 的性能,增加 Redis 所能处理的数据量,并减少 Redis 发生宕机的可能性。

二、内存使用分析

2.1 Redis内存使用机制

Redis 内存使用主要包括以下两个方面:

  1. 服务器内存的基本使用:在 Redis 服务启动后,Redis 会向操作系统申请一部分内存,用于服务器的运行和维护连接、客户端信息等。
  2. 数据库键值对的内存分配:当往 Redis 中添加键值对时,Redis 会根据 value 的大小决定使用内存类型以及分配内存的方式。当单个键值对的大小超过了一定阈值时,Redis 会将该键值对保存到磁盘上的临时文件中,从而节省内存空间。

2.2 Redis内存使用瓶颈分析

Redis 内存使用的瓶颈主要包括以下三个方面:

  1. 操作系统限制:在 32 位操作系统下,Redis 可使用的最大内存约为 3GB,而在 64 位操作系统下,则不受此限制。
  2. Redis 内存配置:Redis 配置中的 maxmemory 参数用于控制 Redis 可以使用的最大内存量。如果将此参数配置过小,导致 Redis 没有足够内存来存储键值对,将会产生 Out Of Memory 错误。
  3. Redis 数据结构:使用不同的数据结构也影响了 Redis 内存使用的瓶颈。例如,在 Redis 中,使用哈希表比使用列表更节省内存。因此,在实际应用场景中,应尽量优先选择适合当前业务场景的数据结构,以便最大化地利用内存资源。
public class RedisOptimization {private static Jedis jedis;public static void main(String[] args) {jedis = new Jedis("localhost", 6379);// 内存优化optimizeMemoryUsage();}/*** Redis 内存使用优化*/public static void optimizeMemoryUsage() {// 设置最大内存jedis.configSet("maxmemory", "4gb");// 查看内存使用情况String memoryUsage = jedis.info("memory");System.out.println(memoryUsage);}
}

三、Redis 内存使用优化

3.1 数据压缩

3.1.1 压缩规则

Redis 提供了多种数据类型,每种类型在进行数据压缩时需要遵循不同的规则。根据数据类型的特点,Redis 压缩规则如下:

  • 字符串类型:字符串类型的数据无法进行压缩。
  • 列表类型:如果列表中的所有元素都是整数类型,将会在内存中以紧凑型整数数组的形式存储,比普通列表类型占用更少的空间。
  • 集合类型:如果集合中的所有元素都是整数类型,将会在内存中以紧凑型整数数组的形式存储,比普通集合类型占用更少的空间。
  • 散列类型:如果散列中的所有元素都是短小的字符串类型,将会使用 Quicklist 存储,可以减小内存占用。
  • 有序集合类型:如果有序集合中的成员元素和分值都是整数类型的话,则使用紧凑型整数数组存储,比普通有序集合类型占用更少的空间。

3.1.2 压缩策略

对于需要压缩的数据,在 Redis 中支持多种压缩策略,如下:

  • quicklist 压缩:对于长度较长的链表结构,可以转化为 Quicklist 结构再进行压缩。
  • RDB 文件压缩:内存快照 RDB 文件可以使用 Gzip、LZF、Snappy 等算法进行压缩,减小存储空间。
  • LRU 内存淘汰:可以选择只清除近期最少使用的数据,同时防止大量数据被清除导致的缓存穿透。

3.2 内存回收

3.2.1 内存淘汰策略

Redis 支持多种内存淘汰策略来回收内存,具体如下:

  • noeviction:不允许回收内存,当内存不足时操作会报错。
  • allkeys-lru:从所有的键(Redis 的数据结构)中选择最少使用的那个回收,等同于"Least Recently Used"算法。
  • allkeys-random:随机回收所有的键。
  • volatile-lru:从设置过过期时间的键值对中,选择最近最少使用的那个回收。
  • volatile-random:随机从设置过过期时间的键值对中删除一个键。
  • volatile-ttl:根据键值对的 TLL,回收时间最近的键值对。

3.2.2 定期清除过期数据

Redis 内置了定期清除过期数据的机制。可以通过配置文件中的maxmemory-policymaxmemory-samples参数来进行设置。

3.3 性能优化

3.3.1 合理设置缓存失效时间

合理的设置缓存失效时间可以避免缓存被长时间占用而导致内存浪费。根据业务特点可以选择不同的失效策略,如先进先出、最少使用等策略。

3.3.2 使用内存优化工具

Redis 内置了多个内存优化工具,可以通过 redis-cli 命令来使用这些工具,如下:

  • info memory:查看 Redis 内存使用情况。
  • slowlog get:查看慢查询记录。
  • monitor:实时查看 Redis 的操作日志。

四、应对方案

4.1 内存升级

如果当前 Redis 内存使用过高,可以考虑将 Redis 机器的内存升级,但需要注意 Redis 单进程最大支持512MB的内存,如果超过这个限制,需要采用数据分片来降低内存的使用量。

4.2 数据分片

数据分片是一种常用的 Redis 内存优化策略,即将大规模的数据分为多个小块进行处理。不同的数据块可以存储在不同的 Redis 实例中,从而降低单个 Redis 的内存使用量。不过数据分片需要注意数据一致性和读写同步问题。

五、Redis高级优化

5.1 预热技术

预热技术是指在Redis启动后,提前将一些热点数据加载到内存中,从而减少用户访问时的响应时间。具体实现可以通过定时任务或者手动触发,将数据查询出来并写入Redis中,留下足够的时间让Redis将数据加载到内存中。

5.2 持久化技术

Redis中有两种持久化技术,分别为RDB和AOF。

5.2.1 RDB

RDB即Redis Database,是一个快照(snapshot)的形式,通过将所有数据写入磁盘生成.Snapshot文件进行持久化;同时支持将快照文件进行压缩,缩小文件体积。RDB方式相对于AOF方式可以更好地进行缓存恢复,但是可能会丢失一部分最近的写操作。

5.2.2 AOF

AOF即Append-Only File,是将Redis执行的所有写操作追加到文件(默认名为appendonly.aof)中进行持久化,这些写操作包括SET、DEL等命令。AOF方式相对于RDB方式可以更好地保证数据的安全性,但是在数据量比较大时,AOF文件的体积也会变得很大,同时对于缓存的恢复效率也有一定影响。

public class RedisService {// Redis连接池配置信息private static final JedisPoolConfig POOL_CONFIG = new JedisPoolConfig();// Redis服务器IP地址private static String ADDR = "localhost";// Redis的端口号private static int PORT = 6379;// 访问密码private static String AUTH = null;// 可用连接实例的最大数目,默认值为8private static int MAX_ACTIVE = 8;// 控制一个pool最多有多少个状态为idle(空闲的)的jedis实例,默认值也是8private static int MAX_IDLE = 8;// 等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时private static int MAX_WAIT = -1;// 连接超时的时间private static int TIMEOUT = 3000;// 在borrow一个jedis实例时,是否需要验证,若为true则所有jedis实例均是可用的private static boolean TEST_ON_BORROW = true;// 初始化Redis连接池private static JedisPool jedisPool = null;static {try {POOL_CONFIG.setMaxTotal(MAX_ACTIVE);POOL_CONFIG.setMaxIdle(MAX_IDLE);POOL_CONFIG.setMaxWaitMillis(MAX_WAIT);POOL_CONFIG.setTestOnBorrow(TEST_ON_BORROW);jedisPool = new JedisPool(POOL_CONFIG, ADDR, PORT, TIMEOUT, AUTH);} catch (Exception e) {e.printStackTrace();}}/*** 获取jedis实例* * @return*/public synchronized static Jedis getJedis() {try {if (jedisPool != null) {Jedis resource = jedisPool.getResource();return resource;} else {return null;}} catch (Exception e) {e.printStackTrace();return null;}}/*** 释放资源* * @param jedis*/public static void returnResource(final Jedis jedis) {if (jedis != null) {jedisPool.returnResource(jedis);}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/30854.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实验室如何选择适合的LIMS实验室管理系统

实验室信息管理系统(LIMS)是从20世纪70年代末开始发展起来的,距今在国外已发展40多年。国内发展历史约20多年,且前十几年国内市场上主要是国外进口的LIMS产品,存在价格高、产品重,实施周期长等水土不服的情况。近十年开始&#xf…

ctf中linux内核态的漏洞挖掘与利用系列(一)

说明 该系列文章主要是从ctf比赛入手,针对linux内核上的漏洞分析、挖掘与利用做讲解,本篇文章主要介绍内核漏洞利用所需的前置知识以及准备工作。 linux内核态与用户态的区别 以 Intel CPU 为例,按照权限级别划分,Intel把 CPU指…

深入浅出对话系统——检索式对话系统进阶方法

引言 本文介绍检索式对话系统进阶方法,主要介绍两篇论文工作。 Fine-grained Post-training for Improving Retrieval-based Dialogue Systems 这里的post-training是定义在pre-training和fine-turning中间的阶段,具体的思想是用一些特定领域的数据去…

thymeleaf做一个简单的表单

前期环境 做一个信息提交和图片上传的表单。 主要技术&#xff1a; mysql 数据库 2.springboot 框架 3.前台 thymeleaf模板 4.数据库连接 spring jpa 载入controller层 RequestMapping("/dictoryChange")public String dicitoryChange(Model model){List<Catalo…

Springboot中创建拦截器

目录 目的 实现过程 1、创建拦截器 2、注册拦截器 完整代码 目的 在Springboot项目中创建拦截器&#xff0c;在进入Controller层之前拦截请求&#xff0c;可对拦截到的请求内容做响应处理&#xff0c;如&#xff1a;校验请求参数、验证证书等操作&#xff1b; 实现过程 1、创…

vivado tcl创建工程和Git管理

一、Tcl工程创建 二、Git版本管理 对于创建完成的工程需要Git备份时&#xff0c;不需要上传完整几百或上G的工程&#xff0c;使用tcl指令创建脚本&#xff0c;并只将Tcl脚本上传&#xff0c;克隆时&#xff0c;只需要克隆tcl脚本&#xff0c;使用vivado导入新建工程即可。 优…

如何获取vivado IP列表

TCL命令如下&#xff1a; set fid [open "vivado_included_ip_[version -short].csv" w] puts $fid "Name;Version" set ip_catalog [get_ipdefs *] foreach ip $ip_catalog{ set ipname [get_property DISPLAY_NAME [get_ipdefs $ip]]set iplib [get_p…

Java基础篇--基本数据类型

目录 前言&#xff1a; 内置数据类型 类型默认值 示例: 内置数据类型转换 自动类型转换&#xff08;隐式类型转换&#xff09;&#xff1a; 强制类型转换&#xff08;显式类型转换&#xff09;&#xff1a; 隐含强制类型转换&#xff1a; 引用类型 前言&#xff1a; …

7个最先进的3D模型生成式AI大模型【AIGC】

AI正在不同的行业中出现&#xff0c;我们对 3D 资产生成的前景感到兴奋。 对于游戏开发商和工作室来说&#xff0c;3D 资产通常是开发过程中最棘手的部分之一&#xff0c;容易出现瓶颈。 生产一个模型的成本从 60 美元到 1500 美元不等&#xff0c;需要 2 到 10 周的时间来回制…

禁止输入空格和汉字,以及纯符号

1.禁止输入空格和汉字,以及纯符号 2、可以输入纯数字、纯字母、字母数字的组合、字母符号的组合、符号数字的组合、符号字母数字的组合 <el-form-item :prop"tableData.${$index}.strbatchcode" :rules"!!row.blnbatch ? rules.strbatchcode :rules.strbat…

多个配置WebMvcConfigurationSupport失效问题

最近在项目中用类继承WebMvcConfigurationSupport实现拦截器 Configuration RequiredArgsConstructor public class SpringWebSupport extends WebMvcConfigurationSupport {private final ProjectInterceptor projectInterceptor;// 拦截器 //设置拦截器对象和拦截请求Ove…

tomcat p12证书另存为nginx .crt证书和.key私钥

tomcat p12证书另存为nginx .crt证书和.key私钥 Tomcat使用的.pfx或.keystore文件都是私钥及公钥证书一起的&#xff0c;通过pin保证安全&#xff1b;nginx只需要使用.pem或.crt公钥证书文件和.key私钥即可&#xff0c;如果原ssl证书不方便重新下载&#xff0c;在已有tomcat证…

Vue3 + Ts + Vite 封装一套企业级axiso全流程

前期回顾 从零搭建 Vue3 VIte Ts 项目 —— 并集成eslint 、prettier、stylelint、husky、lint-staged、pinia、axios、loding、动态路由…_彩色之外的博客-CSDN博客 实现功能&#xff1a; 取消重复请求&#xff1a;完全相同的接口在上一个pending状态时&#xff0c;自动取…

企业服务器被devos勒索病毒攻击后怎么处理,devos勒索病毒如何攻击的

众所周知&#xff0c;科学技术是第一生产力&#xff0c;科学技术的发展给企业与人们的生活带来了极大变化&#xff0c;但随之而来的网络安全威胁也不断增加。最近&#xff0c;我们收到很多企业的求助&#xff0c;企业的计算机服务器遭到了devos勒索病毒的攻击&#xff0c;导致企…

Python中的__code__属性

在Python中&#xff0c;每个函数都有一个__code__属性。这个属性是一个引用到代码对象&#xff0c;它包含了与该函数相关的Python字节码及其他相关信息。代码对象在Python中是用来存储可执行代码的基本单元&#xff0c;它们包含了字节码、常量、变量名等相关的数据。 以下是与…

oracle积累增量和差异增量

积累增量和差异增量&#xff1a; 对于 RMAN 来说&#xff0c;积累增量备份和差异增量备份都是增量备份的一种形式&#xff0c;它们之间的区别在于备份的范围和备份集的方式。 积累增量备份&#xff1a;在进行积累增量备份时&#xff0c;RMAN 会备份自最后一次完全备份或增量备…

NGINX——负载均衡

负载均衡————>通过反向代理来实现 nginx反向代理的七层代理和四层代理 七层代理&#xff1a; 七层代理时最常用的反向代理方式&#xff0c;其只能配置在nginx的配置文件的http模块中&#xff0c;而且方法名称必须要定义成“upstream”模块&#xff0c;注意不能写在se…

使用Druid,以jdbc方式配置多数据源

文章目录 背景示例代码&#xff08;结合实际进行配置&#xff09;总结 背景 当使用Spring Boot项目并需要多数据源时&#xff0c;你可以使用Druid连接池来配置和管理多个数据源。以下是一个示例的配置和代码&#xff0c;以说明如何实现多数据源&#xff1a; 示例代码&#xf…

【Mybatis】调试查看执行的 SQL 语句

1. 问题场景&#xff1a; 记录日常开发过程中 Mybatis 调试 SQL 语句&#xff0c;想要查看Mybatis 中执行的 SQL语句&#xff0c;导致定位问题困难 2. 解决方式 双击shift找到mybatis源码中的 MappedStatement的getBoundSql()方法 public BoundSql getBoundSql(Object para…

selenium爬虫,配置谷歌浏览器的driver

用selenium爬虫时&#xff0c;明明已经安装了selenium模块&#xff0c;程序却运行不了。在使用selenium之前必须先配置浏览器对应版本的webdriver 本文主要涉及驱动有问题driver 网上有很多手动的方法&#xff08;查看谷歌浏览的版本然后在其他博主分享的webdriver中下载与自己…