redis大key对持久化的影响

2024-06-18 19:36
文章标签 redis key 持久 影响

本文主要是介绍redis大key对持久化的影响,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

我在“redis持久化方式——AOF\RDB”中详细介绍了redis持久化的策略,一言蔽之,就是将数据库的内存数据保存在磁盘文件中,本文讲解大key对redis持久化的影响

什么是大key?

redis中的数据以key——value形式存储,大key指的是一个key对应的value占用空间较大,那么叫大value不就好了?对于一个key-value键值对,它的唯一标识是key,所以用大key形容一个键值对中的value占用空间大

大key会造成什么影响?

redis在持久化的过程中,核心的操作是数据的复制,大key会造成数据复制时间过长

大key对AOF、AOF重写的影响

1.AOF是逐条命令进行复制的,我们复习一下AOF的具体过程:server每执行一次写命令,就将该命令写入aof缓冲区,写入磁盘的时机由三种策略决定,分别是(1.每条新命令都写入磁盘 2.每秒将缓冲区的命令写入磁盘 3.由操作系统决定)

  • Always 策略就是每次写入 AOF 文件数据后,就执行 fsync() 函数;

  • Everysec 策略就会创建一个异步任务来执行 fsync() 函数;

  • No 策略就是永不执行 fsync() 函数;

  • 当使用 Always 策略的时候,如果写入是一个大 Key,主线程在执行 fsync() 函数的时候,阻塞的时间会比较久,因为当写入的数据量很大的时候,数据同步到硬盘这个过程是很耗时的

    当使用 Everysec 策略的时候,由于是异步执行 fsync() 函数,所以大 Key 持久化的过程(数据同步磁盘)不会影响主线程。

    当使用 No 策略的时候,由于永不执行 fsync() 函数,所以大 Key 持久化的过程不会影响主线程。

2.由于redis主线程执行命令操作和写入aof缓冲区操作是串行的,如果一条命令中有大key,在写入命令到aof缓冲区时会阻塞主线程相当长一段时间,这段时间内服务器无法响应其它请求

3.AOF重写是在aof文件大于64M时触发的,如果aof文件写入大key,很快就会触发AOF重写,主进程fork出子进程进行AOF重写操作,fork时会复制父进程的页表给子进程,fork操作会阻塞主进程,如果此时aof文件过大,页表也会很大,复制页表的操作将会很耗时,也会阻塞主进程一段时间

4.大key对RDB的影响在于bgsave创建子进程时对父进程页表的复制操作

5.AOF和RDB创建子进程进行持久化时,除了复制页表会造成性能下降,还有一点:父进程修改页表中的内存数据,会触发写时复制,由于fork时父子进程的页表都被置为只读,当父进程修改内存页时,造成异常,触发写保护中断,中断处理程序先将要被修改的内存页复制一份给子进程,再执行父进程的修改操作,这里的复制操作也比较耗时

大 key 除了会影响持久化之外,还会有以下的影响。

  • 客户端超时阻塞。由于 Redis 执行命令是单线程处理,然后在操作大 key 时会比较耗时,那么就会阻塞 Redis,从客户端这一视角看,就是很久很久都没有响应。
  • 引发网络阻塞。每次获取大 key 产生的网络流量较大,如果一个 key 的大小是 1 MB,每秒访问量为 1000,那么每秒会产生 1000MB 的流量,这对于普通千兆网卡的服务器来说是灾难性的。
  • 阻塞工作线程。如果使用 del 删除大 key 时,会阻塞工作线程,这样就没办法处理后续的命令。
  • 内存分布不均。集群模型在 slot 分片均匀情况下,会出现数据和查询倾斜情况,部分有大 key 的 Redis 节点占用内存多,QPS 也会比较大。

如何避免大key造成的影响?

1.最好在设计阶段,就把大 key 拆分成一个一个小 key。或者,定时检查 Redis 是否存在大 key

2.如果该大 key 是可以删除的,不要使用 DEL 命令删除,因为该命令删除过程会阻塞主线程,而是用 unlink 命令(Redis 4.0+)删除大 key,因为该命令的删除过程是异步的,不会阻塞主线程。

推荐学习 https://xxetb.xetslk.com/s/p5Ibb

这篇关于redis大key对持久化的影响的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1072917

相关文章

ITMS-90339: Deprecated Info.plist Key

The Info.plist contains a key 'UIApplicationExitsOnSuspend' in bundle 在info.plist中找到这个key——UIApplicationExitsOnSuspend,然后删掉就可以了。确保没问题的话也跑一下看是否可以能在后台运行。 需要先转换一下,才能找到对应的key

持久层 技术选型如何决策?JPA,Hibernate,ibatis(mybatis)

转自:http://t.51jdy.cn/thread-259-1-1.html 持久层 是一个项目 后台 最重要的部分。他直接 决定了 数据读写的性能,业务编写的复杂度,数据结构(对象结构)等问题。 因此 架构师在考虑 使用那个持久层框架的时候 要考虑清楚。 选择的 标准: 1,项目的场景。 2,团队的技能掌握情况。 3,开发周期(开发效率)。 传统的 业务系统,通常业

Windows/macOS/Linux 安装 Redis 和 Redis Desktop Manager 可视化工具

本文所有安装都在macOS High Sierra 10.13.4进行,Windows安装相对容易些,Linux安装与macOS类似,文中会做区分讲解 1. Redis安装 1.下载Redis https://redis.io/download 把下载的源码更名为redis-4.0.9-source,我喜欢跟maven、Tomcat放在一起,就放到/Users/zhan/Documents

chart 完成拓扑图单节点拖拽不影响其他节点位置

就是做这种的功能,箭头原本是可以动态重复移动的,但不知道哪里问题导致没箭头了,然后补了个edgeSymbol: ['','arrow'], 字段,才增加了箭头。 拖拽某个节点,只有关联到的线条会跟着变动其他的节点位置不变。 参考 https://gallery.echartsjs.com/editor.html?c=x8Fgri22P9 https://echarts.baidu.com/exa

为什么要做Redis分区和分片

Redis分区(Partitioning)和分片(Sharding)是将数据分布在多个Redis实例或多个节点上的做法。这种技术用于提高性能、可扩展性和可用性。以下是执行Redis分区和分片的主要原因: 1. **提高吞吐量**:    - 通过将数据分散到多个节点,可以并行处理更多的操作,从而提高整体吞吐量。 2. **内存限制**:    - 单个Redis实例的内存是有限的。分区允许数据

如何理解redis是单线程的

写在文章开头 在面试时我们经常会问到这样一道题 你刚刚说redis是单线程的,那你能不能告诉我它是如何基于单个线程完成指令接收与连接接入的? 这时候我们经常会得到沉默,所以对于这道题,笔者会直接通过3.0.0源码分析的角度来剖析一下redis单线程的设计与实现。 Hi,我是 sharkChili ,是个不断在硬核技术上作死的 java coder ,是 CSDN的博客专家 ,也是开源

Redis-在springboot环境下执行lua脚本

文章目录 1、什么lua2、创建SpringBoot工程3、引入相关依赖4、创建LUA脚本5、创建配置类6、创建启动类7、创建测试类 1、什么lua “Lua”的英文全称是“Lightweight Userdata Abstraction Layer”,意思是“轻量级用户数据抽象层”。 2、创建SpringBoot工程 3、引入相关依赖 <?xml version

redis切换数据库的方法【jedis】

package com.test;import redis.clients.jedis.Jedis;public class readredis {public static void main(String[] args) {// 连接本地的 Redis 服务Jedis jedis = new Jedis("127.0.0.1", 6379);jedis.select(10);String v

Redis 高性能基本操作

单元素操作是基础 单元素操作,是指每一种集合类型对单个数据实现增删改查 例如,Hash 类型的 HGET、HSET 和 HDEL,Set 类型的 SADD、SREM、SRANDMEMBER 等这些操作的复杂度由集合采用的数据结构决定,例如,HGET、HSET 和 HDEL 是对哈希表做操作,所以它们的复杂度都是 O(1)Set 类型用哈希表作为底层数据结构时,它的 SADD、SREM、SRAN

redis高级用法

redis 慢日志查询 配置参数 slowlog-log-slower-than 10000 #单位微秒 slowlog-max-len 选项指定服务器最多保存多少条慢查询日志 redis-cli slowlog get #获取慢日志1) 1) (integer) 4 # 日志的唯一标识符(uid)2) (integer) 1378781447 # 命令执