Redis实践
Redis实践
使用复杂度高的命令
如果在使用Redis时,发现访问延迟突然增大,如何进行排查?
首先,第一步,建议你去查看一下Redis的慢日志。Redis提供了慢日志命令的统计功能,我们通过以下设置,就可以查看有哪些命令在执行时延迟比较大。
首先设置Redis的慢日志阈值,只有超过阈值的命令才会被记录,这里的单位是微妙,例如设置慢日志的阈值为5毫秒,同时设置只保留最近1000条慢日志记录:
# 命令执行超过5毫秒记录慢日志
CONFIG SET slowlog-log-slower-than 5000
# 只保留最近1000条慢日志
CONFIG SET slowlog-max-len 1000
设置完成之后,所有执行的命令如果延迟大于5毫秒,都会被Redis记录下来,我们执行SLOWLOG get 5
查询最近5条慢日志:
127.0.0.1:6379> SLOWLOG get 5
1) 1) (integer) 32693 # 慢日志ID2) (integer) 1593763337 # 执行时间3) (integer) 5299 # 执行耗时(微妙)4) 1) "LRANGE" # 具体执行的命令和参数2) "user_list_2000"3) "0"4) "-1"
2) 1) (integer) 326922) (integer) 15937633373) (integer) 50444) 1) "GET"2) "book_price_1000"
...
通过查看慢日志记录,我们就可以知道在什么时间执行哪些命令比较耗时,如果你的业务经常使用O(n)以上复杂度的命令,例如sort
、sunion
、zunionstore
,或者在执行O(n)命令时操作的数据量比较大,这些情况下Redis处理数据时就会很耗时。
如果你的服务请求量并不大,但Redis实例的CPU使用率很高,很有可能是使用了复杂度高的命令导致的。
存储大key
如果查询慢日志发现,并不是复杂度较高的命令导致的,例如都是SET
、DELETE
操作出现在慢日志记录中,那么你就要怀疑是否存在Redis写入了大key的情况。
Redis在写入数据时,需要为新的数据分配内存,当从Redis中删除数据时,它会释放对应的内存空间。
如果一个key写入的数据非常大,Redis在分配内存时也会比较耗时。同样的,当删除这个key的数据时,释放内存也会耗时比较久。
你需要检查你的业务代码,是否存在写入大key的情况,需要评估写入数据量的大小,业务层应该避免一个key存入过大的数据量。
那么有没有什么办法可以扫描现在Redis中是否存在大key的数据吗?
Redis也提供了扫描大key的方法:
redis-cli -h <span class="katex--inline"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>h</mi><mi>o</mi><mi>s</mi><mi>t</mi><mo>−</mo><mi>p</mi></mrow><annotation encoding="application/x-tex">host -p </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7778em;vertical-align:-0.0833em;"><span class="mord mathnormal">h</span><span class="mord mathnormal">os</span><span class="mord mathnormal">t</span><span class="mspace" style="margin-right:0.2222em;"><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"><span class="mord mathnormal">p</span></span></span></span></span>port --bigkeys -i 0.01
</span></span></span></span>
使用上面的命令就可以扫描出整个实例key大小的分布情况,它是以类型维度来展示的。
需要注意的是当我们在线上实例进行大key扫描时,Redis的QPS会突增,为了降低扫描过程中对Redis的影响,我们需要控制扫描的频率,使用i
参数控制即可,它表示扫描过程中每次扫描的时间间隔,单位是秒。
使用这个命令的原理,其实就是Redis
在内部执行scan
命令,遍历所有key
,然后针对不同类型的key
执行strlen
、llen
、hlen
、scard
、zcard
来获取字符串的长度以及容器类型(list/dict/set/zset)
的元素个数。
而对于容器类型的key,只能扫描出元素最多的key
,但元素最多的key
不一定占用内存最多,这一点需要我们注意下。不过使用这个命令一般我们是可以对整个实例中key的
分布情况有比较清晰的了解。
针对大key
的问题,Redis
官方在4.0版本推出了lazy-free
的机制,用于异步释放大key
的内存,降低对Redis
性能的影响。
即使这样,我们也不建议使用大key,大key在集群的迁移过程中,也会影响到迁移的性能
集中过期
有时你会发现,平时在使用Redis
时没有延时比较大的情况,但在某个时间点突然出现一波延时,而且报慢的时间点很有规律,例如某个整点,或者间隔多久就会发生一次。
如果出现这种情况,就需要考虑是否存在大量key集中过期的情况。
如果有大量的key在某个固定时间点集中过期,在这个时间点访问Redis时,就有可能导致延迟增加。
解决方案是,在集中过期时增加一个随机时间,把这些需要过期的key的时间打散即可 。
伪代码可以这么写:
# 在过期时间点之后的5分钟内随机过期掉
redis.expireat(key, expire_time + random(300))
实例内存达到上限
有时我们把Redis当做纯缓存使用,就会给实例设置一个内存上限maxmemory
,然后开启LRU淘汰策略。
当实例的内存达到了maxmemory
后,你会发现之后的每次写入新的数据,有可能变慢了。
导致变慢的原因是,当Redis内存达到maxmemory
后,每次写入新的数据之前,必须先踢出一部分数据,让内存维持在maxmemory
之下。
这个踢出旧数据的逻辑也是需要消耗时间的,而具体耗时的长短,要取决于配置的淘汰策略:
- allkeys-lru:不管key是否设置了过期,淘汰最近最少访问的key
- volatile-lru:只淘汰最近最少访问并设置过期的key
- allkeys-random:不管key是否设置了过期,随机淘汰
- volatile-random:只随机淘汰有设置过期的key
- allkeys-ttl:不管key是否设置了过期,淘汰即将过期的key
- noeviction:不淘汰任何key,满容后再写入直接报错
- allkeys-lfu:不管key是否设置了过期,淘汰访问频率最低的key(4.0+支持)
- volatile-lfu:只淘汰访问频率最低的过期key(4.0+支持)
我们最常使用的一般是allkeys-lru
或volatile-lru
策略,它们的处理逻辑是,每次从实例中随机取出一批key
(可配置),然后淘汰一个最少访问的key
,之后把剩下的key
暂存到一个池子中,继续随机取出一批key
,并与之前池子中的key
比较,再淘汰一个最少访问的key
。以此循环,直到内存降到maxmemory
之下。
如果使用的是allkeys-random
或volatile-random
策略,那么就会快很多,因为是随机淘汰,那么就少了比较key
访问频率时间的消耗了,随机拿出一批key
后直接淘汰即可,因此这个策略要比上面的LRU
策略执行快一些。
fork耗时严重
如果你的Redis开启了自动生成RDB和AOF重写功能,那么有可能在后台生成RDB和AOF重写时导致Redis的访问延迟增大,而等这些任务执行完毕后,延迟情况消失。
遇到这种情况,一般就是执行生成RDB和AOF重写任务导致的。
生成RDB
和AOF
都需要父进程fork
出一个子进程进行数据的持久化,在fork
执行过程中,父进程需要拷贝内存页表给子进程,如果整个实例内存占用很大,那么需要拷贝的内存页表会比较耗时,此过程会消耗大量的CPU
资源,在完成fork
之前,整个实例会被阻塞住,无法处理任何请求,如果此时CPU
资源紧张,那么fork
的时间会更长,甚至达到秒级。这会严重影响Redis
的性能。
我们可以执行info
命令,查看最后一次fork
执行的耗时latest_fork_usec
,单位微妙。这个时间就是整个实例阻塞无法处理请求的时间。
要想避免这种情况,我们需要规划好数据备份的周期,建议在从节点上执行备份,而且最好放在低峰期执行。如果对于丢失数据不敏感的业务,那么不建议开启RDB
和AOF
重写功能。
另外,fork的耗时也与系统有关,如果把Redis部署在虚拟机上,那么这个时间也会增大。所以使用Redis时建议部署在物理机上,降低fork的影响。
使用Swap
如果你发现Redis突然变得非常慢,每次访问的耗时都达到了几百毫秒甚至秒级,那此时就检查Redis
是否使用到了Swap
,这种情况下Redis
基本上已经无法提供高性能的服务。
我们知道,操作系统提供了Swap机制,目的是为了当内存不足时,可以把一部分内存中的数据换到磁盘上,以达到对内存使用的缓冲。
但当内存中的数据被换到磁盘上后,访问这些数据就需要从磁盘中读取,这个速度要比内存慢太多!
尤其是针对Redis这种高性能的内存数据库来说,如果Redis中的内存被换到磁盘上,对于Redis这种性能极其敏感的数据库,这个操作时间是无法接受的。
我们需要检查机器的内存使用情况,确认是否确实是因为内存不足导致使用到了Swap
。
如果确实使用到了Swap
,要及时整理内存空间,释放出足够的内存供Redis
使用,然后释放Redis
的Swap
,让Redis
重新使用内存。
释放Redis
的Swap
过程通常要重启实例,为了避免重启实例对业务的影响,一般先进行主从切换,然后释放旧主节点的Swap
,重新启动服务,待数据同步完成后,再切换回主节点即可。
可见,当Redis
使用到Swap
后,此时的Redis
的高性能基本被废掉,所以我们需要提前预防这种情况。
我们需要对Redis机器的内存和Swap使用情况进行监控,在内存不足和使用到Swap时及时报警出来,及时进行相应的处理 。
网卡负载过高
特点就是从某个时间点之后就开始变慢,并且一直持续。这时你需要检查一下机器的网卡流量,是否存在网卡流量被跑满的情况。
网卡负载过高,在网络层和TCP层就会出现数据发送延迟、数据丢包等情况。Redis的高性能除了内存之外,就在于网络IO,请求量突增会导致网卡负载变高。
相关文章:
Redis实践
Redis实践 使用复杂度高的命令 如果在使用Redis时,发现访问延迟突然增大,如何进行排查? 首先,第一步,建议你去查看一下Redis的慢日志。Redis提供了慢日志命令的统计功能,我们通过以下设置,就…...

【Lora模型推荐】Stable Diffusion创作具有玉石翡翠质感的图标设计
站长素材AI教程是站长之家旗下AI绘图教程平台 海量AI免费教程,每日更新干货内容 想要深入学习更多AI绘图教程,请访问站长素材AI教程网: AI教程_深度学习入门指南 - 站长素材 (chinaz.com) logo版权归各公司所有!本笔记仅供AIGC…...
vscode 远程开发
目录 vscode 远程连接 选择 Python 环境 vscode 远程连接 按 CtrlShiftP 打开命令面板。输入并选择 Remote-SSH: Open SSH Configuration File...。选择 ~/.ssh/config 文件(如果有多个选项)。在打开的文件中添加或修改你的 SSH 配置。 这个可以右键…...

前端Vue组件化实践:打造灵活可维护的地址管理组件
随着前端技术的不断演进,复杂度和开发难度也随之上升。传统的一体化开发模式使得每次小小的修改或功能增加都可能牵一发而动全身,严重影响了开发效率和维护成本。组件化开发作为一种解决方案,通过模块化、独立化的开发方式,实现了…...

虚幻引擎ue5游戏运行界面白茫茫一片,怎么处理
根剧下图顺序即可调节游戏运行界面光照问题: 在大纲里找到post,然后选中它,找到Exposure 把最低亮度和最高亮度的0改为1即可...

《代理选择与反爬虫策略探究:如何优化网络爬虫效率与稳定性》
代理IP如何选以及常见反爬策略 为什么需要代理? 因为有的网站会封IP,用户如果没有登录,那IP就是身份标识,如果网站发现用户行为异常就非常可能封IP 什么是代理IP 就是让一个人帮你转交请求,帮你转交的人对面不熟&a…...
Kotlin Flow 防抖 节流
防抖和节流是针对响应跟不上触发频率这类问题的两种解决方案。 一:防抖(debounce)的概念: 防抖是指当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次, 如果设定时间到来之前&#x…...
Android Studio下载与安装
Android Studio下载与安装_android studio下载安装-CSDN博客...
【LC刷题】DAY24:122 55 45 1005
122. 买卖股票的最佳时机 II class Solution { public:int maxProfit(vector<int>& prices) {int result 0;for(int i 1; i < prices.size(); i ){result max(prices[i] - prices[ i - 1], 0);}return result;} };55. 跳跃游戏 link class Solution { public…...

从零开始的python学习生活2
接上封装 class Phone:__volt0.5def __keepsinglecore(self):print("让cpu以单核运行")def if5G(self):if self.__volt>1:print("5G通话已开启")else:self.__keepsinglecore()print("电量不足,无法使用5G通话,已经设置为单…...

【并发编程】进程 线程 协程
进程(Process)、线程(Thread)和协程(Coroutine)构成了计算机科学中实现任务并发执行的三种核心抽象机制。通常,为了提高程序的执行效率,开发者会根据应用场景和性能需求,…...
Vue的生命周期函数有哪些?详细说明
Vue.js 的生命周期函数包括以下几个阶段,每个阶段都有相应的钩子函数可以用来在特定时机执行自定义的逻辑。这些生命周期钩子函数使得我们可以在组件的不同阶段进行操作,从而管理组件的状态和行为。 1. beforeCreate: - 描述:…...
大语言模型应用--AI工程化落地
文章目录 大语言模型概述什么是大语言模型什么是机器学习什么是深度学习 理解大语言模型历史沿革关键 AIGC系统AI工程化项目的落地落地的方法Prompt工程(第一阶段)RAG检索(第二阶段)训练特定功能模型(第三阶段…...
我会什么开发技能
java我会什么? 一、并发编程 1、并发编程:jdk中的courren包只能够类实现(seamplore,CountDownLaunch,Pharse,CycliBarrier,CompletableFuture),AQS的原理,线…...

Run LoongArch64 Alpine VM on x86_64
一、Build from source(build on x86_64) Obtain the latest libvirt, virt-manager, and qemu source code, compile and install them. 1.1 Build libvirt from source sudo apt-get update sudo apt-get install augeas-tools bash-completion debhelper-compat dh-apparm…...
4层负载均衡和7层负载均衡
四层负载均衡(Layer 4 Load Balancing)指的是在网络传输层(TCP/IP模型中的第四层)进行负载均衡的技术。四层负载均衡通常使用IP地址、端口号和协议等信息来将网络流量分配到多个服务器上。它主要关心网络层的信息,不涉…...

前端Vue组件化实践:打造仿京东天猫商品属性选择器组件
在前端开发领域,随着业务需求的日益复杂和技术的不断进步,传统的整体式应用开发模式已逐渐显得捉襟见肘。面对日益庞大的系统,每次微小的功能修改或增加都可能导致整个逻辑结构的重构,形成牵一发而动全身的困境。为了解决这一问题…...

智慧城市3d数据可视化系统提升信息汇报的时效和精准度
在信息大爆炸的时代,数据的力量无可估量。而如何将这些数据以直观、高效的方式呈现出来,成为了一个亟待解决的问题。为此,我们推出了全新的3D可视化数据大屏系统,让数据“跃然屏上”,助力您洞察先机,决胜千…...

Git 详解(原理、使用)
git 快速上手请看这篇博客 Git 快速上手 1. 什么是 Git Git 是目前最主流的一个版本控制器,并且是分布式版本控制系统,可以控制电脑上所有格式的文档 版本控制器:记录每次修改以及版本迭代的管理系统 对于文本文件,可以记录每次…...
android11为开机动画添加铃声(语音)
一、碰到的问题 1、第一次开机无铃声 2、开机时铃声和动画不同步,开头的铃声会丢失 3、开机时铃声/动画不能完全播放完 二、解决 以下为添加的patch /开机铃声不同步,语音第一段无声 diff --git a/media/libmediaplayerservice/MediaPlayerService…...

Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...

ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...
Kafka主题运维全指南:从基础配置到故障处理
#作者:张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1:主题删除失败。常见错误2:__consumer_offsets占用太多的磁盘。 主题日常管理 …...

论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving
地址:LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂,正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...