【项目经验】Redis Sentinel从工程中下线并对业务迁移-(二)

2024-04-30 06:20

本文主要是介绍【项目经验】Redis Sentinel从工程中下线并对业务迁移-(二),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        在上篇文章【项目经验】Redis Sentinel从工程中下线并对业务迁移-进行中-CSDN博客有说到迁移的计划。最近一直按照计划进行迁移,期间遇到了不少问题。总结如下:

一、key未设置过期时间

        redis基于内存存储,主要作用是缓存。当大量的key未设置过期时间时,redis内存空间的利用率会降低,执行效率也会受影响。

弊端:

1. 内存占用

        最直接的弊端是可能会造成内存使用持续增长。如果没有过期机制自动删除不再需要的数据,随着时间推移,Redis实例可能会消耗越来越多的内存。这最终可能导致内存溢出,影响Redis服务的稳定性和性能。

2. 资源管理困难

        不设置过期时间使得手动管理Redis中的数据变得复杂。需要额外的机制或策略来监控和控制数据量,避免不必要的数据累积。

3. 性能下降

        随着数据量的增加,查找、读取或写入操作的效率可能会降低,因为更多的内存消耗意味着更频繁的磁盘交换(如果开启了虚拟内存)。此外,大量的无期限数据可能导致缓存命中率下降,从而降低了Redis作为高性能缓存的优势。

4. 影响其他业务

        如果Redis用作多个应用或服务的共享缓存,未过期的key可能会挤占其他应用需要缓存的空间,影响整体系统的资源分配和效率。

5. 风险增加

        在极端情况下,如服务器硬件故障或重启前,未过期的key会全部写入磁盘(如果配置了持久化),延长了恢复过程,增加了数据丢失的风险。

6. 淘汰策略受限

        Redis提供了多种内存淘汰策略(如LRU、LFU等),用于在内存不足时决定哪些数据应该被移除。但当大多数或所有key都没有过期时间时,这些策略的效果会大打折扣,可能无法有效地释放内存给更重要的数据使用。

如何解决?

         根据业务的特点设置合理的过期时间,并检查从redis中获取不到时,从表中或接口获取源数据的方案是否仍然可行。

        因为之前没有过期时间,业务中的数据大概率一直从redis中获得的,如果表或接口的源数据发生了变更,业务可能并无感知。此时key过期,查询源数据,可能导致业务无法正常执行。

二、big key

        目前排查结束未发现big key,但有一些value缓存的是对象信息,而且未设置过期时间,同时业务中只使用了其中某几个属性值。后续我将把这些属性信息查出来单独缓存和超时时间,并停止对缓存对象的使用。

        虽然没发现big key,我们也再聊一下big key的识别、弊端和解决方案。

如何找到big key?

1. 使用MEMORY USAGE命令
        直接在Redis命令行界面使用MEMORY USAGE key_name命令,可以查看指定Key的内存占用情况。通过遍历并比较各个Key的内存使用量,可以找出占用内存较多的大Key。

2. Redis自带的--bigkeys 选项
        虽然实际中--bigkeys并不是一个直接可用的Redis命令,可以使用类似功能的脚本或客户端工具来扫描数据库并统计不同类型中最大的Key。对于字符串类型,此方法能直接反映出value的字节大小;对于集合、列表、有序集合、哈希等复杂类型,则主要统计元素数量,可能需要进一步的分析来确定实际占用的内存大小。

3. 使用Redis客户端工具
        利用如redis-cli、Redigo等客户端工具,编写脚本来遍历所有Key,并计算它们的大小进行排序。这样可以系统地识别出占用内存最多的大Key。

4. 手动或自动化脚本扫描
        编写脚本使用SCAN命令安全地遍历Redis中的Key空间,结合MEMORY USAGE或其他方法计算每个Key的大小,然后根据大小阈值标记出大Key。这种方法可以灵活定制扫描和评估逻辑。

5. 分析RDB文件
        在Redis执行备份生成的RDB文件中,也可以分析Key的大小。虽然这通常不作为实时监控的手段,但在离线分析或计划性维护时,通过解析RDB文件可以获取详细的Key信息。

6.  使用第三方工具
        工具如RdbTools、RedisInsight等提供了图形界面和高级分析功能,可以帮助更容易地识别大Key,同时提供数据可视化和优化建议。

        选择合适的方法时,应考虑操作的便利性、准确性以及对Redis服务运行时的影响。在生产环境中,特别注意避免因扫描操作引起的服务压力。

弊端:

1. 内存使用不均衡

        在Redis Cluster集群环境下,大Key可能导致数据分区不均,因为数据是基于Key的哈希值分布的。这会引起某些节点内存使用过高,而其他节点则相对空闲,破坏了集群的负载均衡能力。

2. 阻塞问题

        由于Redis采用单线程模型处理客户端请求,操作大Key(如HGETALL、SMEMBERS等命令)可能非常耗时。这不仅会导致该操作期间其他快速操作被阻塞,还可能引起客户端超时,严重影响系统的响应时间和吞吐量。

3. 故障切换风险

        长时间的阻塞操作可能触发如Sentinel(Redis的高可用组件)的故障转移机制,即便实际上Redis服务器并未发生故障,这会进一步影响服务的稳定性。

4. 备份和恢复效率

        大Key的存在会增加Redis数据备份(如RDB快照)的时间和存储空间需求,同时在数据恢复时也会消耗更多时间,延长了故障恢复窗口。

5. 性能瓶颈

        频繁访问大Key会占用大量网络带宽,尤其是在网络条件不佳的情况下,可能导致网络拥塞,进一步影响Redis的性能。

6. 管理难度

        大Key使得内存管理更加复杂,可能导致内存碎片化严重,影响内存的有效利用,同时也给内存优化和问题排查带来挑战。

7. 潜在的数据丢失风险

        在一些极端情况下,如Redis实例突然崩溃且没有配置持久化,大Key中的数据可能来不及保存到磁盘,从而导致数据丢失。

如何解决?

1. 拆分Key
        将大的数据结构拆分成多个小的Key。例如,一个包含大量元素的Hash或Set可以拆分为多个小的Hash或Set。
        对于列表类型的Key,如果元素过多,可以考虑按时间或元素数量进行切分,存储到多个列表中。

2. 使用分片
        在设计阶段,考虑使用客户端分片或Redis Cluster自动分片功能,将数据分散到多个Redis实例上,避免单个Key过大影响整个实例。

3. 优化数据模型
        重新审视和优化数据模型,减少冗余数据,使用更高效的数据结构。
        对于频繁查询但不经常更新的数据,考虑使用缓存穿透技术,直接从客户端或另一层缓存中读取,减轻Redis负担。

4. 设置过期时间
        为大Key设置合理的过期时间,确保不再需要的数据能够自动被清理。

5.  使用Redis Modules
        对于特定场景,如时间序列数据,可以考虑使用Redis Modules,如RedisTimeSeries,它为特定类型的数据提供了更高效的存储和查询方式。

6.  监控与自动化
        实施定期监控和自动化脚本,及时发现并处理大Key,比如使用Redis自带的监控工具或第三方监控系统,结合脚本自动拆分大Key。

7.  限制操作
         对于操作大Key的命令(如HGETALL, SMEMBERS等),限制其在低峰时段使用或直接禁止使用,转而使用更细粒度的命令(如HSCAN, SSCAN)分批处理数据。

8. 数据压缩
        在不影响业务逻辑的前提下,对存储的数据进行适当的压缩,减少内存占用。

9.  调整Redis配置
        根据实际情况调整Redis的配置参数,如增加内存限制、优化持久化策略等,以更好地适应大Key带来的挑战。

三、找不到读取方或找不到写入方

背景:

        我们的工程是从一个大的module工程中独立出来的,当时可能迁的着急,导致迁出了很多冗余的代码。这次redis迁移过程,整理出了没有写入或者读取方的key,经过排查,和当时工程迁移有关。

如何解决?

        这些key需要发出来挨个和各组对,看其他组是否还在使用。如果多组共用在一个业务中,看看如何拆分;如果大家都不使用了,就得下掉了。

        也给我们后面编程提了醒,在代码设计时,要避免这种问题产生,秉持高内聚,低耦合的原则,并且“如无必要,不增实体”。

总结:

        以上是Redis Sentinel从工程中下线并对业务迁移过程中遇到的一些问题和总结到的业内常用的方法,希望能为读者朋友带来帮助。

这篇关于【项目经验】Redis Sentinel从工程中下线并对业务迁移-(二)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

使用Sentinel自定义返回和实现区分来源方式

《使用Sentinel自定义返回和实现区分来源方式》:本文主要介绍使用Sentinel自定义返回和实现区分来源方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Sentinel自定义返回和实现区分来源1. 自定义错误返回2. 实现区分来源总结Sentinel自定

一文教你如何将maven项目转成web项目

《一文教你如何将maven项目转成web项目》在软件开发过程中,有时我们需要将一个普通的Maven项目转换为Web项目,以便能够部署到Web容器中运行,本文将详细介绍如何通过简单的步骤完成这一转换过程... 目录准备工作步骤一:修改​​pom.XML​​1.1 添加​​packaging​​标签1.2 添加

tomcat多实例部署的项目实践

《tomcat多实例部署的项目实践》Tomcat多实例是指在一台设备上运行多个Tomcat服务,这些Tomcat相互独立,本文主要介绍了tomcat多实例部署的项目实践,具有一定的参考价值,感兴趣的可... 目录1.创建项目目录,测试文China编程件2js.创建实例的安装目录3.准备实例的配置文件4.编辑实例的

Redis 中的热点键和数据倾斜示例详解

《Redis中的热点键和数据倾斜示例详解》热点键是指在Redis中被频繁访问的特定键,这些键由于其高访问频率,可能导致Redis服务器的性能问题,尤其是在高并发场景下,本文给大家介绍Redis中的热... 目录Redis 中的热点键和数据倾斜热点键(Hot Key)定义特点应对策略示例数据倾斜(Data S

springboot集成Deepseek4j的项目实践

《springboot集成Deepseek4j的项目实践》本文主要介绍了springboot集成Deepseek4j的项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录Deepseek4j快速开始Maven 依js赖基础配置基础使用示例1. 流式返回示例2. 进阶

SpringBoot项目启动报错"找不到或无法加载主类"的解决方法

《SpringBoot项目启动报错找不到或无法加载主类的解决方法》在使用IntelliJIDEA开发基于SpringBoot框架的Java程序时,可能会出现找不到或无法加载主类com.example.... 目录一、问题描述二、排查过程三、解决方案一、问题描述在使用 IntelliJ IDEA 开发基于

redis+lua实现分布式限流的示例

《redis+lua实现分布式限流的示例》本文主要介绍了redis+lua实现分布式限流的示例,可以实现复杂的限流逻辑,如滑动窗口限流,并且避免了多步操作导致的并发问题,具有一定的参考价值,感兴趣的可... 目录为什么使用Redis+Lua实现分布式限流使用ZSET也可以实现限流,为什么选择lua的方式实现

Redis中管道操作pipeline的实现

《Redis中管道操作pipeline的实现》RedisPipeline是一种优化客户端与服务器通信的技术,通过批量发送和接收命令减少网络往返次数,提高命令执行效率,本文就来介绍一下Redis中管道操... 目录什么是pipeline场景一:我要向Redis新增大批量的数据分批处理事务( MULTI/EXE

Redis中高并发读写性能的深度解析与优化

《Redis中高并发读写性能的深度解析与优化》Redis作为一款高性能的内存数据库,广泛应用于缓存、消息队列、实时统计等场景,本文将深入探讨Redis的读写并发能力,感兴趣的小伙伴可以了解下... 目录引言一、Redis 并发能力概述1.1 Redis 的读写性能1.2 影响 Redis 并发能力的因素二、

SpringBoot项目使用MDC给日志增加唯一标识的实现步骤

《SpringBoot项目使用MDC给日志增加唯一标识的实现步骤》本文介绍了如何在SpringBoot项目中使用MDC(MappedDiagnosticContext)为日志增加唯一标识,以便于日... 目录【Java】SpringBoot项目使用MDC给日志增加唯一标识,方便日志追踪1.日志效果2.实现步