【项目经验】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

相关文章

Redis 的 SUBSCRIBE命令详解

《Redis的SUBSCRIBE命令详解》Redis的SUBSCRIBE命令用于订阅一个或多个频道,以便接收发送到这些频道的消息,本文给大家介绍Redis的SUBSCRIBE命令,感兴趣的朋友跟随... 目录基本语法工作原理示例消息格式相关命令python 示例Redis 的 SUBSCRIBE 命令用于订

Three.js构建一个 3D 商品展示空间完整实战项目

《Three.js构建一个3D商品展示空间完整实战项目》Three.js是一个强大的JavaScript库,专用于在Web浏览器中创建3D图形,:本文主要介绍Three.js构建一个3D商品展... 目录引言项目核心技术1. 项目架构与资源组织2. 多模型切换、交互热点绑定3. 移动端适配与帧率优化4. 可

sky-take-out项目中Redis的使用示例详解

《sky-take-out项目中Redis的使用示例详解》SpringCache是Spring的缓存抽象层,通过注解简化缓存管理,支持Redis等提供者,适用于方法结果缓存、更新和删除操作,但无法实现... 目录Spring Cache主要特性核心注解1.@Cacheable2.@CachePut3.@Ca

Redis实现高效内存管理的示例代码

《Redis实现高效内存管理的示例代码》Redis内存管理是其核心功能之一,为了高效地利用内存,Redis采用了多种技术和策略,如优化的数据结构、内存分配策略、内存回收、数据压缩等,下面就来详细的介绍... 目录1. 内存分配策略jemalloc 的使用2. 数据压缩和编码ziplist示例代码3. 优化的

redis-sentinel基础概念及部署流程

《redis-sentinel基础概念及部署流程》RedisSentinel是Redis的高可用解决方案,通过监控主从节点、自动故障转移、通知机制及配置提供,实现集群故障恢复与服务持续可用,核心组件包... 目录一. 引言二. 核心功能三. 核心组件四. 故障转移流程五. 服务部署六. sentinel部署

基于Redis自动过期的流处理暂停机制

《基于Redis自动过期的流处理暂停机制》基于Redis自动过期的流处理暂停机制是一种高效、可靠且易于实现的解决方案,防止延时过大的数据影响实时处理自动恢复处理,以避免积压的数据影响实时性,下面就来详... 目录核心思路代码实现1. 初始化Redis连接和键前缀2. 接收数据时检查暂停状态3. 检测到延时过

SpringBoot通过main方法启动web项目实践

《SpringBoot通过main方法启动web项目实践》SpringBoot通过SpringApplication.run()启动Web项目,自动推断应用类型,加载初始化器与监听器,配置Spring... 目录1. 启动入口:SpringApplication.run()2. SpringApplicat

Redis实现分布式锁全过程

《Redis实现分布式锁全过程》文章介绍Redis实现分布式锁的方法,包括使用SETNX和EXPIRE命令确保互斥性与防死锁,Redisson客户端提供的便捷接口,以及Redlock算法通过多节点共识... 目录Redis实现分布式锁1. 分布式锁的基本原理2. 使用 Redis 实现分布式锁2.1 获取锁

Redis中哨兵机制和集群的区别及说明

《Redis中哨兵机制和集群的区别及说明》Redis哨兵通过主从复制实现高可用,适用于中小规模数据;集群采用分布式分片,支持动态扩展,适合大规模数据,哨兵管理简单但扩展性弱,集群性能更强但架构复杂,根... 目录一、架构设计与节点角色1. 哨兵机制(Sentinel)2. 集群(Cluster)二、数据分片

Springboot项目构建时各种依赖详细介绍与依赖关系说明详解

《Springboot项目构建时各种依赖详细介绍与依赖关系说明详解》SpringBoot通过spring-boot-dependencies统一依赖版本管理,spring-boot-starter-w... 目录一、spring-boot-dependencies1.简介2. 内容概览3.核心内容结构4.