Redis生产实践中相关疑问记录

news/2024/12/23 19:02:13/

1. Redis相关疑问

redis100_redis_2">1.1. redis内存使用率100% 就等同于redis不可用吗?

正常使用情况下,不是。

redis有【缓存淘汰机制】,Redis 在内存使用率达到 100% 时不会直接崩溃。相反,它依赖内存淘汰策略来释放内存,确保系统的稳定性。

详细参见:Redis maxmemory-policy: Eviction policy

默认配置的策略volatile_lru
volatile-lru行为: 使用 LRU(Least Recently Used,最近最少使用)算法驱逐键。volatile-lru 仅驱逐设有过期时间的键,allkeys-lru 则驱逐所有键。适用场景: 缓存场景,不介意丢失一些数据。

确保你根据实际需求配置适当的内存淘汰策略,以便在内存达到上限时,系统能够稳定地处理新请求,而不会出现写操作失败的情况(只要不是noeviction)

理论上SET GET都应该能正常操作才对(先不考虑其他复杂命令)。尽管 Redis 本身不会轻易崩溃,但如果内存耗尽且没有淘汰策略或者淘汰策略未能生效,Redis 可能拒绝新的写操作,并返回错误:OOM command not allowed when used memory > 'maxmemory’如果系统的配置或者操作系统的内存管理不当,可能会导致 Redis 进程被操作系统杀死。
在这里插入图片描述

rediskey_16">1.2. redis如何删除过期的key?

过期 key 的自动删除机制。它是 Redis 用来回收内存空间的常用机制,应用广泛,本身就会引起 Redis 操作阻塞,导致性能变慢,所以,你必须要知道该机制对性能的影响。

Redis 键值对的 key 可以设置过期时间。默认情况下,Redis 每 100 毫秒会删除一些过期 key,具体的算法如下:

  1. 采样:ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP 个数的 key,并将其中过期的 key 全部删除;

  2. 如果超过 25% 的 key 过期了,则重复删除的过程,直到过期 key 的比例降至 25% 以下。
    ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP 是 Redis 的一个参数,默认是 20,那么,一秒内基本有 200 个过期 key 会被删除。
    这一策略对清除过期 key、释放内存空间很有帮助。如果每秒钟删除 200 个过期 key,并不会对 Redis 造成太大影响。

    但是,如果触发了上面这个算法的第二条,Redis 就会一直删除以释放内存空间。注意,删除操作是阻塞的(Redis 4.0 后可以用异步线
    程机制来减少阻塞影响)。所以,一旦该条件触发,Redis 的线程就会一直执行删除,这样一来,就没办法正常服务其他的键值操作了,
    就会进一步引起其他键值操作的延迟增加,Redis 就会变慢。

    那么,算法的第二条是怎么被触发的呢?其中一个重要来源,就是频繁使用带有相同时间参数的 EXPIREAT 命令设置过期 key,这就
    会导致,在同一秒内有大量的 key 同时过期。

    可以类比JVM频繁GC造成的性能影响。

redis_35">1.3. redis的内存组成?

在这里插入图片描述

使用info memory进行分析的示例

#Memoryused_memory:1072693248
used_memory_human:1023.99
Mused_memory_rss:1090519040
used_memory_rss_human:1.02
Gused_memory_peak:1072693248
used_memory_peak_human:1023.99
Mused_memory_peak_perc:100.00%
used_memory_overhead:1048576000
used_memory_startup:1024000
used_memory_dataset:23929848
used_memory_dataset_perc:2.23%
allocator_allocated:1072693248
allocator_active:1090519040
allocator_resident:1090519040
total_system_memory:16777216000
total_system_memory_human:16.00
Gused_memory_lua:37888
used_memory_lua_human:37.89
Kused_memory_scripts:1024000
used_memory_scripts_human:1.00
Mmaxmemory:1073741824
maxmemory_human:1.00
Gmaxmemory_policy:noeviction
allocator_frag_ratio:1.02
allocator_frag_bytes:17825792
allocator_rss_ratio:1.00
allocator_rss_bytes:0
rss_overhead_ratio:1.00
rss_overhead_bytes:0
mem_fragmentation_ratio:1.02
mem_fragmentation_bytes:17825792
mem_not_counted_for_evict:0
mem_replication_backlog:0
mem_clients_slaves:0
mem_clients_normal:1048576000
mem_aof_buffer:0
mem_allocator:jemalloc-5.1.0
active_defrag_running:0
lazyfree_pending_objects:0

分析和解释

从上面的 INFO memory 输出中,我们可以看到一些关键信息,这些信息表明大部分内存被缓冲区占用殆尽:

1.内存使用情况:

  • used_memory: 1072693248 (1.02 GB)

  • maxmemory: 1073741824 (1.00 GB)

    上面的输出表明,当前内存使用几乎达到了配置的最大内存限制,内存已接近耗尽。

2.缓冲区占用:

  • used_memory_overhead: 1048576000 (1.00 GB)

    这个值表示 Redis 开销的内存,包括缓冲区、连接和其他元数据。在这种情况下,大部分 used_memory (1.02 GB) 被
    used_memory_overhead (1.00 GB) 占用,这意味着大部分内存都被缓冲区等开销占据。

3.数据集占用:

  • used_memory_dataset: 23929848 (23.93 MB)

  • used_memory_dataset_perc: 2.23%

    这里显示,实际存储的数据只占了非常少的一部分内存(约 23.93 MB),而绝大部分内存被缓冲区占据。

4.客户端缓冲区:

  • mem_clients_normal: 1048576000 (1.00 GB)

    这表明普通客户端连接占用了约 1.00 GB 内存,这通常意味着输出缓冲区可能已经接近或达到了设定的限制。

5.内存碎片:

  • allocator_frag_ratio: 1.02

  • mem_fragmentation_ratio: 1.02

    碎片率不高,表明内存被合理使用但被缓冲区占用过多。

总结
从上面的例子可以看出,Redis 的内存几乎被缓冲区占用殆尽。以下是具体的结论:

  • 当前内存使用 (used_memory) 已经接近最大内存限制 (maxmemory),即 1.02 GB 接近 1.00 GB 的限制。
  • 内存开销 (used_memory_overhead) 很大,主要被客户端普通连接使用(可能是输出缓冲区),而实际的数据仅占用了很少的内存。
  • 分配器和 RSS 碎片率 (allocator_frag_ratio 和 mem_fragmentation_ratio) 较低,表明碎片不是问题。

redis_118">1.4. redis为什么要有缓冲区?

缓冲区的功能其实很简单,主要就是用一块内存空间来暂时存放命令数据,以免出现因为数据和命令的处理速度慢于发送速度而导致的数据丢失和性能问题。

Redis Server 的输出大小通常是不可控制的。存在bigkey的时候,就会产生体积庞大的返回数据。另外也有可能因为执行了太多命令,导致产生返回数据的速率超过了往客户端发送的速率,导致服务器堆积大量消息,从而导致输出缓冲区越来越大,占用过多内存,甚至导致系统崩溃。Redis 通过设置 client-output-buffer-limit来保护系统安全。

Redis工作原理-单客户端视角简单版:

在这里插入图片描述

Redis工作原理-单客户端视角复杂版:

在这里插入图片描述

Redis工作原理-多客户端视角简单版(含缓冲区)。

在这里插入图片描述

redis_128">1.5. redis的性能边界

Redis的性能是有边界的,不能盲目相信所谓的高性能。真正理解性能须使用benchmark。

  • 计算资源
    使用通配符、Lua并发、1对多的PUBSUB、热点Key等会大量消耗计算资源,集群架构下还会导致访问倾斜,无法有效利用所有数据分片。

  • 存储资源
    Streaming慢消费、大Key等会占用大量存储资源,集群架构下还会导致数据倾斜,无法有效利用所有数据分片。

  • 网络资源
    扫描全库(KEYS命令)、大Value、大Key的范围查询(如HGETALL命令)等会消耗大量的网络资源,且极易引发线程阻塞。

    重要
    Redis的高并发能力不等同于高吞吐能力,例如将大Value存在Redis里以期望提升访问性能,此类场景往往不会有特别大的收益,反而会影响Redis整体的服务能力。
    在这里插入图片描述
    在这里插入图片描述

附录

业务部署规范
Key设计规范
SDK使用规范
命令使用规范
运维管理规范


http://www.ppmy.cn/news/1557540.html

相关文章

数据结构---------二叉树前序遍历中序遍历后序遍历

以下是用C语言实现二叉树的前序遍历、中序遍历和后序遍历的代码示例&#xff0c;包括递归和非递归&#xff08;借助栈实现&#xff09;两种方式&#xff1a; 1. 二叉树节点结构体定义 #include <stdio.h> #include <stdlib.h>// 二叉树节点结构体 typedef struct…

了解 SpringMVC 请求流程

文章目录 1. Spring 基础 - SpringMVC 请求流程1.1 引入1.2 什么是 MVC1.3 什么是 Spring MVC1.4 请求流程核心架构的具体流程步骤补充 1.5 案例**Maven 包引入****业务代码的编写**DaoServiceControllerwebapp 下的 web.xmlspringmvc.xmlJSP 视图 2. Spring 进阶 - Dispatcher…

39.在 Vue3 中使用 OpenLayers 导出 GeoJSON 文件及详解 GEOJSON 格式

一、引言 在 Web 地图开发领域&#xff0c;Vue3 作为一款流行的前端框架&#xff0c;结合强大的 OpenLayers 地图库&#xff0c;能够实现丰富多样的地图功能。其中&#xff0c;将地图数据以 GeoJSON 格式导出是一项常见且实用的需求&#xff0c;本文将深入探讨如何在 Vue3 环境…

【day11】面向对象编程进阶(继承)

概述 本文深入探讨面向对象编程的核心概念&#xff0c;包括继承、方法重写、this和super关键字的使用&#xff0c;以及抽象类和方法的定义与实现。通过本文的学习&#xff0c;你将能够&#xff1a; 理解继承的优势。掌握继承的使用方法。了解继承后成员变量和成员方法的访问特…

iPhone恢复技巧:如何从 iPhone 恢复丢失的照片

在计算机时代&#xff0c;我们依靠手机来捕捉和存储珍贵的回忆。但是&#xff0c;如果您不小心删除或丢失了手机上的照片怎么办&#xff1f;这真的很令人沮丧和烦恼&#xff0c;不是吗&#xff1f;好吧&#xff0c;如果您在 iPhone 上丢失了照片&#xff0c;您不必担心&#xf…

大模型技术优化负载均衡:AI驱动的智能化运维

在现代信息技术环境中&#xff0c;负载均衡是确保系统稳定、高效运行的关键技术。随着大模型技术&#xff08;Large Model Technology, LMT&#xff09;的发展&#xff0c;AI驱动的智能化负载均衡成为了优化系统性能、提升用户体验的重要手段。本文将详细介绍如何使用Python实现…

CSS系列(22)-- 容器查询详解

前端技术探索系列&#xff1a;CSS 容器查询详解 &#x1f4e6; 致读者&#xff1a;探索组件级响应式设计 &#x1f44b; 前端开发者们&#xff0c; 今天我们将深入探讨 CSS 容器查询&#xff08;Container Queries&#xff09;&#xff0c;这项新特性让我们能够基于容器大小…

阿里开源最强数字人工具 EchoMimicV2,本地部署(一)

背景 EchoMimicV2是阿里推出的半身人体AI数字人项目,基于参考图片、音频剪辑和手部姿势序列生成高质量动画视频,确保音频内容与半身动作的一致性。现在本地部署,安装体验一下。 下载代码 git clone GitHub - antgroup/echomimic_v2: EchoMimicV2: Towa…