【项目经验】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从工程中下线并对业务迁移过程中遇到的一些问题和总结到的业内常用的方法,希望能为读者朋友带来帮助。

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

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

相关文章

nginx的前世今生(二)

书接上回: 上回书说到,nginx的前世今生,这回我们继续说 3.缓冲秘籍,洪流控水 Nginx的缓冲区是其处理数据传输和提高性能的关键设计之一,主要用于暂存和管理进出的数据流,以应对不同组件间速度不匹配的问题…

池化整合多元数据库,zData X 一体机助力证券公司IT基础架构革新

引言 近期,云和恩墨 zData X 多元数据库一体机(以下简称 zData X)在某证券公司的OA、短信和CRM业务系统中成功上线,标志着其IT基础架构完成从集中式存储向池化高性能分布式存储的转变。zData X 成功整合了该证券公司使用的达梦、O…

Windows php 安装 Memcached扩展、php缺失 Memcached扩展、Class ‘Memcached‘ not found

在Windows系统下如何安装 php Memcached 扩展 下载dll文件 pecl地址:https://pecl.php.net/package/memcached 根据版本进行选择 : 解压下载的文件后得到了这么样的文件结构: 配置 移动dll文件到相应文件位置 重点: libme…

FreeRTOS队列集(1-15)

队列集定义:def 队列集只允许任务间传递消息为同一种数据类型,如果需要在任务间传递不同数据类型的消息时,就可以使用队列集。 用于对多个信号量进行监听,其中不管哪一个消息到来,都可以让任务退出阻塞状态 假设&am…

如何利用MCU自动测量单元提高大坝安全监测效率

大坝作为重要的水利基础设施,其安全性直接关系到人民群众的生命财产安全和社会的稳定发展。因此,对大坝进行实时、准确的安全监测至关重要。近年来,随着微控制器单元(MCU)技术的不断发展,其在大坝安全监测领域的应用也越来越广泛。…

springboot配置WebMvcConfigurationSupport

一、在spring里有四个mvc配置类 1、mvc配置类 WebMvcConfigurer WebMvcConfigurerAdapter WebMvcConfigurationSupport WebMvcAutoConfiguration 2、WebMvcConfigurer为接口 3、WebMvcConfigurerAdapter是WebMvcConfigurer的实现类,且大部分为空方法,…

微服务架构面试题(二)

1. 请简述微服务中各组件的作用 ? 微服务架构中的组件各自扮演着关键的角色,它们协同工作以构建高效、可扩展和灵活的系统。以下是一些核心组件及其作用: 服务注册与发现组件:如Eureka,负责让其他服务知道当前服务的…

使用 Flask、Gunicorn 与 Shell 脚本构建高效 Web 应用部署流程

在使用 Flask 作为 Web 应用框架,并使用 Gunicorn 作为 WSGI 容器,使用shell 脚本来管理应用的启动、重启和停止。 启动脚本 start.sh: #!/bin/bash# 设置应用名称和端口 APP_NAME"my_flask_app" PORT8000# 设置 Flask 应用的路径…

【PCL】教程 supervoxel_clustering执行超体聚类并可视化点云数据及其聚类结果

[done, 417.125 ms : 307200 points] Available dimensions: x y z rgba 源点云milk_cartoon_all_small_clorox.pcd > Loading point cloud... > Extracting supervoxels! Found 423 supervoxels > Getting supervoxel adjacency 这段代码主要是使用PCL(Po…

【Linux】创建/扩容swap交换空间swap优化

一、当前交换空间大小 目前交换空间大小为2G 二、创建swap交换空间 #创建大小为2G的交换空间 [roothadoop01 data1]# dd if/dev/zero of/data1/swapfile bs1M count2048 #将文件设置为交换空间 [roothadoop01 data1]# mkswap /data1/swapfile #启用交换空间 [roothadoop01 da…

【Python】pandas.cut()函数的用法

pandas.cut() 函数是一个非常有用的工具,用于将数值型数据按照指定的分箱或区间进行分割,从而将连续的数值变量转换为离散的类别变量。这在数据分析和机器学习的特征工程中尤其有用,因为它可以帮助揭示不同区间内的数据分布特征,或…

【Qt问题】Qt Creator 如何链接第三方库

往期回顾 【QT问题】 Qt信号函数如果重名,调用怎么处理-CSDN博客 【Qt问题】Qt中文乱码问题解决方案(详细汇总)-CSDN博客 【Qt问题】Qt常用快捷键汇总-CSDN博客 【Qt问题】Qt Creator 如何链接第三方库 一、为什么会使用第三方库 在编写代码…

Java Web 开发 - 掌握拦截器和监听器

目录 深入了解Java Web的拦截器和监听器 拦截器(Interceptor) 拦截器的使用场景 拦截器实例 思维导图 ​编辑 监听器(Listener) 监听器的使用场景 监听器类型 监听器实例 思维导图​编辑 总结 深入了解Java Web的拦截器…

在UI界面中播放视频_unity基础开发教程

在UI界面中播放视频_unity基础开发教程 前言操作步骤结语 前言 之前我写过一篇在场景中播放视频的文章,但是在开发中有时候也会在UI的界面中播放视频,这期我们做一下在UI的界面中播放视频。 操作步骤 首先在场景中创建一个Raw Image,UI->…

DAO是什么?有什么用途?

DAO(Decentralized Autonomous Organization,去中心化自治组织)是一种基于区块链技术的组织形式,它没有中央管理层,而是通过智能合约和区块链上的代码来运作。DAO 的决策过程是透明的,通常由组织的成员通过…

java学习笔记11

20. 字符串类 字符串是指一连串的字符,它是由许多单个字符连接而成。字符串可以包含任意字符,这些字符必须包含在一对双引号""之内,例如:“abc”.java中封装了3个字符串类,分别是String类、StringBuffer类、StringBuilder类,都在java.lang包中。20.1 String类的…

孤独的城市公路(增加开始结束页面)

致敬 裴总 缺点 没有一个车没有背景音乐后期都会添加 为什么裴总良心 裴总真良心 还有音乐 还是3D 还有开始按钮 还能game 还有结尾 还有结尾提示 import arcadeSCREEN_WIDTH 700 SCREEN_HEIGHT 700 SCREEN_TITLE "孤独的城市公路" MOVEMENT_SPEED 5 …

go http框架下的静态资源代理实现(压缩,缓存验证自定义)

之前在这一篇文章里说了我的第一版静态资源代理,后面我又完善了一下: 上一种方案的问题: 首页未加入自定义代理中依赖了gin框架的file()方法反复访问本地文件,访问文件系统是很消耗性能的 所以本次我做了改进,思路是…

0418EmpTomCat项目 初次使用ajax实现局部动态离职

0418EmpTomCat项目包-CSDN博客 数据库字段: 员工部门表 分页查询; 多条件查询; 添加新员工; ajax点击离职操作效果:

【CTF Web】BUUCTF BUU CODE REVIEW 1 Writeup(代码审计+PHP弱类型漏洞+MD5的0e绕过+反序列化)

BUU CODE REVIEW 1 1 https://github.com/glzjin/buusec_2019_code_review_1 解法 <?php /*** Created by PhpStorm.* User: jinzhao* Date: 2019/10/6* Time: 8:04 PM*/highlight_file(__FILE__);class BUU {public $correct "";public $input ""…