Redis的慢查询

许多存储系统(例如 MySQL)提供慢查询日志帮助开发和运维人员定位系统存在的慢操作。所谓慢查询日志就是系统在命令执行前后计算每条命令的执行时间,当超过预设阀值,就将这条命令的相关信息(例如:发生时间,耗时,命令的详细信息)记录下来,Redis也提供了类似的功能。

Redis客户端执行一条命令分为如下4个部分:

  • 发送命令
  • 命令排队
  • 执行命令
  • 返回结果

需要注意,慢查询只统计步骤3的时间,所以没有慢查询并不代表客户端没有超时问题。因为有可能是命令的网络问题或者是命令在Redis在排队,所以不是说命令执行很慢就说是慢查询,而有可能是网络的问题或者是Redis服务非常繁忙(队列等待长)。

慢查询配置

1、动态设置

慢查询的阈值默认值是10毫秒。
参数:slowlog-log-slower-than就是时间预设阀值,它的单位是微秒(1秒=1000毫秒=1 000 000微秒),默认值是10 000,假如执行了一条“很慢”的命令(例如keys *),如果它的执行时间超过了10 000微秒,也就是10毫秒,那么它将被记录在慢查询日志中。
查看slowlog-log-slower-than

config get slowlog-log-slower-than

更新slowlog-log-slower-than

config set slowlog-log-slower-than 20000 

使用config set完后,若想将配置持久化保存到Redis.conf,要执行config rewrite

config rewrite

查看慢查询

 #设置慢查询时间阈值为10微秒config set slowlog-log-slower-than 10#查看所有的keykeys *#查看慢查询个数slowlog len#展示慢查询信息(查询2个慢查询)slowlog get 2


慢查询日志重置

slowlog reset

Pipeline

前面慢查询的时候提到过时间消耗,其中1(发送命令)4(返回结果)花费的时间称为Round Trip Time (RTT,往返时间),也就是数据在网络上传输的时间。

Redis提供了批量操作命令(例如mget、mset等),有效地节约RTT。

但大部分命令是不支持批量操作的,例如要执行n次 hgetall命令,并没有mhgetall命令存在,需要消耗n次RTT。

#设置一个hash对象json
hset json a 1 b 2#获取json的属性a
hget json a
#湖区json的属性b
hget json b#一次性获取json对象
hgetall json

举例:Redis的客户端和服务端可能部署在不同的机器上。例如客户端在本地(上海),Redis服务器在阿里云的北京,两地直线距离约为1200公里,那么1次RTT时间=1200 x2/ ( 300000×2/3 ) =12毫秒,(光在真空中传输速度为每秒30万公里,这里假设光纤为光速的2/3 )。而Redis命令真正执行的时间通常在微秒(1000微妙=1毫秒)级别,所以才会有Redis 性能瓶颈是网络这样的说法。

Pipeline(流水线)机制能改善上面这类问题,它能将一组 Redis命令进行组装,通过一次RTT传输给Redis,再将这组Redis命令的执行结果按顺序返回给客户端,没有使用Pipeline执行了n条命令,整个过程需要n次RTT。

使用Pipeline 执行了n次命令,整个过程需要1次RTT。

 public void plSet(List<String> keys,List<String> values) {Jedis jedis = null;try {jedis = jedisPool.getResource();Pipeline pipelined = jedis.pipelined();for(int i=0;i<keys.size();i++){pipelined.set(keys.get(i),values.get(i));}pipelined.sync();} catch (Exception e) {throw new RuntimeException("执行Pipeline设值失败!",e);} finally {jedis.close();}}/**逐个set和利用pipeline的处理时间对比*/public void testPipeline() {long setStart = System.currentTimeMillis();for (int i = 0; i < TEST_COUNT; i++) { //单个的操作redisString.set("testStringM:key_" + i, String.valueOf(i));}long setEnd = System.currentTimeMillis();System.out.println("非pipeline操作"+TEST_COUNT+"次字符串数据类型set写入,耗时:" + (setEnd - setStart) + "毫秒");List<String> keys = new ArrayList<>(TEST_COUNT);List<String> values= new ArrayList<>(TEST_COUNT);for (int i = 0; i < keys.size(); i++) {keys.add("testpipelineM:key_"+i);values.add(String.valueOf(i));}long pipelineStart = System.currentTimeMillis();redisPipeline.plSet(keys,values);long pipelineEnd = System.currentTimeMillis();System.out.println("pipeline操作"+TEST_COUNT+"次字符串数据类型set写入,耗时:" + (pipelineEnd - pipelineStart) + "毫秒");}
非pipeline操作10000次字符串数据类型set写入,耗时:4934毫秒
pipeline操作10000次字符串数据类型set写入,耗时:7毫秒

事务

Redis提供了简单的事务功能,将一组需要一起执行的命令放到multiexec两个命令之间。multi 命令代表事务开始,exec命令代表事务结束。另外discard命令是回滚。

multi
sadd sa 1
sadd sb 2
exec


当没有执行exec的时候,开启另外一个redis-cli,利用SISMEMBER确认关键字是否存在

sismember sa 1
(integer) 0

当执行完exec的时候,开启另外一个redis-cli,利用SISMEMBER确认关键字是否存在

sismember sa 1
(integer) 1

Redis的事务原理

事务是Redis实现在服务器端的行为,用户执行MULTI命令时,服务器会将对应这个用户的客户端对象设置一个特殊的状态,在这个状态下后续用户执行的查询命令不会被真的执行,而是被服务器缓存起来,直到用户执行EXEC命令为止,服务器会将这个用户对应的客户端对象中缓存的命令按照提交的顺序依次执行

Redis的watch命令

有些应用场景需要在事务之前,确保事务中的key没有被其他客户端修改过,才执行事务,否则不执行(类似乐观锁)。Redis 提供了watch命令来解决这类问题。
在这里插入图片描述
可以看到“客户端-1”在执行multi之前执行了watch命令,“客户端-2”在“客户端-1”执行exec之前修改了key值,造成客户端-1事务没有执行(exec结果为nil)。

Redis客户端中的事务使用代码:

 public final static String RS_TRANS_NS = "rts:";@Autowiredprivate JedisPool jedisPool;public List<Object> transaction(String... watchKeys){Jedis jedis = null;try {jedis = jedisPool.getResource();if(watchKeys.length>0){/*使用watch功能*/String watchResult = jedis.watch(watchKeys);if(!"OK".equals(watchResult)) {throw new RuntimeException("执行watch失败:"+watchResult);}}Transaction multi = jedis.multi();multi.set(RS_TRANS_NS+"test1","a1");multi.set(RS_TRANS_NS+"test2","a2");multi.set(RS_TRANS_NS+"test3","a3");List<Object> execResult = multi.exec();if(execResult==null){throw new RuntimeException("事务无法执行,监视的key被修改:"+watchKeys);}System.out.println(execResult);return execResult;} catch (Exception e) {throw new RuntimeException("执行Redis事务失败!",e);} finally {if(watchKeys.length>0){jedis.unwatch();/*前面如果watch了,这里就要unwatch*/}jedis.close();}}

Pipeline和事务的区别

PipeLine看起来和事务很类似,感觉都是一批批处理,但两者还是有很大的区别。简单来说。

1、pipeline是客户端的行为,对于服务器来说是透明的,可以认为服务器无法区分客户端发送来的查询命令是以普通命令的形式还是以pipeline的形式发送到服务器的;

2、而事务则是实现在服务器端的行为,用户执行MULTI命令时,服务器会将对应这个用户的客户端对象设置为一个特殊的状态,在这个状态下后续用户执行的查询命令不会被真的执行,而是被服务器缓存起来,直到用户执行EXEC命令为止,服务器会将这个用户对应的客户端对象中缓存的命令按照提交的顺序依次执行。

3、应用pipeline可以提服务器的吞吐能力,并提高Redis处理查询请求的能力。

但是这里存在一个问题,当通过pipeline提交的查询命令数据较少,可以被内核缓冲区所容纳时,Redis可以保证这些命令执行的原子性。然而一旦数据量过大,超过了内核缓冲区的接收大小,那么命令的执行将会被打断,原子性也就无法得到保证。因此pipeline只是一种提升服务器吞吐能力的机制,如果想要命令以事务的方式原子性的被执行,还是需要事务机制,或者使用更高级的脚本功能以及模块功能。

4、可以将事务和pipeline结合起来使用,减少事务的命令在网络上的传输时间,将多次网络IO缩减为一次网络IO。

Redis提供了简单的事务,之所以说它简单,主要是因为它不支持事务中的回滚特性,同时无法实现命令之间的逻辑关系计算,当然也体现了Redis 的“keep it simple”的特性,下一节将介绍的Lua脚本同样可以实现事务的相关功能,但是功能要强大很多。

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

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

相关文章

如何为你的WordPress网站选择合适的安全插件

在管理WordPress网站时&#xff0c;安全因素至关重要。由于WordPress的广泛使用&#xff0c;它也成为了黑客攻击的首要目标。为了避免潜在的安全风险&#xff0c;选择合适的安全插件至关重要。而Wordfence和iThemes&#xff0c;作为两款颇具人气的WordPress安全插件&#xff0c…

我们使用Rust开发的AI知识库应用

这段时间陆陆续续的开发了2个AI知识库应用&#xff0c;一个面向企业&#xff0c;一个面向C端用户。 飞树智库&#xff1a;一个安全高效的面向 企业的知识库平台&#xff08;https://fskb.coderbox.cn/&#xff09;。 小飞树&#xff1a;一个专注于个人知识管理的AI应用&#…

自动化测试实战篇

目录 1. 自动化实施步骤 1.1 编写web测试用例 1.2 自动化测试脚本开发 1.3 将自动化测试补充至测试报告 1. 自动化实施步骤 1.1 编写web测试用例 1.2 自动化测试脚本开发 TestDevelopment: 测试用例 - Gitee.comhttps://gitee.com/Axurea/test-development/tree/master/2…

idea 服务器Debug端口启动设置

一&#xff1a;在阿里云服务器安全组已经设置了端口授权对象&#xff1a;正确命令&#xff1a;nohup java -Xdebug -Xrunjdwp:transportdt_socket,servery,suspendn,address9998 -jar -Duser.timezoneGMT08 -Xms256m -Xmx256m /opt/projects/*/*/*-starter-1.0-SNAPSHOT.jar -…

大模型量化004

Bert P-tuning BertPET、BertP-Tuning Chain of Thought Few shot Cot Auto-COT 解决手动编写高质量CoT示例麻烦耗时的问题 Auto COT 自动思维链生成器 1.业务场景&#xff1a; 每天收到很多反馈&#xff0c;之前需要人工整理&#xff0c;找到重点&#xff0c;做判断那些需要立…

C#(基本语法)

数据类型C#是一种强类型语言&#xff0c;变量必须声明类型。基本数据类型包括整型&#xff08;int、long&#xff09;、浮点型&#xff08;float、double&#xff09;、布尔型&#xff08;bool&#xff09;、字符型&#xff08;char&#xff09;和字符串型&#xff08;string&a…

ARM-I2C软实现

开发流程引脚初始化引脚功能定义实现读操作实现写操作GD32F4软件I2C初始化void SoftI2C_init() {// 时钟配置rcu_periph_clock_enable(SCL_RCU);// 设置输出模式gpio_mode_set(SCL_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SCL_PIN);gpio_output_options_set(SCL_PORT, GPIO_O…

防水医用无人机市场报告:现状、趋势与洞察

市场规模与增长趋势在全球医疗科技快速发展的当下&#xff0c;防水医用无人机市场正崭露头角&#xff0c;展现出强劲的发展势头。据 QYR统计&#xff0c;2023 年全球医用无人机市场销售额达到 1.9 亿美元&#xff0c;预计到 2030 年将飙升至 8.5 亿美元&#xff0c;年复合增长率…

haproxy代理

一.负载均衡 1.1.什么是负载均衡 负载均衡&#xff1a;Load Balance&#xff0c;简称LB&#xff0c;是一种服务或基于硬件设备等实现的高可用反向代理技术&#xff0c;负载均 衡将特定的业务(web服务、网络流量等)分担给指定的一个或多个后端特定的服务器或设备&#xff0c;…

【面试】软件测试面试题

1. 测试用例如何编写 2. bug的生命周期 项目有多少人&#xff1f;多少条测试用例&#xff1f;多少bug&#xff1f;自己发现的第一条&#xff1f;&#xff08;是不是bug&#xff09; 3. 缺陷管理工具 包括Jira, PingCode, 禅道&#xff0c;BugZilla&#xff0c;Redmine, TAPD&am…

HbuilderX开发小程序

1.打卡HbuilderX&#xff0c;选择文件—新建—项目2.创建项目3.在HbuilderX中运行前要确定微信开发这工具的服务端口号是打开的4.HbuilderX中点击预览可以实时预览5.在微信开发者中进行本地测试点击后自动跳转到微信开发者工具中运行项目

Netty中FastThreadLocal解读

io.netty.util.concurrent.FastThreadLocal 是 Netty 中提供的高性能线程局部存储&#xff08;Thread-Local Storage&#xff09;实现&#xff0c;位于 io.netty.util.concurrent 包。它是 Java 标准库 ThreadLocal 的替代品&#xff0c;旨在优化性能&#xff0c;减少内存分配和…

上海迪士尼游玩攻略 小铁寄存柜让你轻松畅玩

去上海迪士尼玩最烦带一堆行李&#xff0c;其实有小铁寄存柜帮忙就能轻装上阵&#xff0c;各个关键位置都有分布&#xff0c;玩起来特别省心。​刚到迪士尼的时候&#xff0c;要是坐地铁到上海国际旅游度假区站&#xff0c;1/2 号口安检区就有小铁柜&#xff0c;行李箱、大背包…

飞算科技重磅出品:飞算 JavaAI 重构 Java 开发效率新标杆

在 Java 开发领域&#xff0c;一款由国家级高新技术企业自主研发的智能工具正引发行业关注 —— 飞算 JavaAI 不仅承载着中国原创技术的创新基因&#xff0c;更以贴合实际开发场景的功能设计&#xff0c;成为众多企业提升 Java 开发效率的核心助力。​作为飞算数智科技&#xf…

python案例:基于python 神经网络cnn和LDA主题分析的旅游景点满意度分析

1&#xff0e;绪论1.1研究背景与意义1.1.1研究背景随着旅游业的快速发展&#xff0c;满意度分析成为评估旅游景点质量和提升游客体验的重要手段。作为中国的旅游城市之一&#xff0c;其旅游景点吸引了大量游客。然而&#xff0c;如何科学评估和提升旅游景点的满意度&#xff0c…

Git快速入门,完整的git项目管理工具教程,git入门到精通!

Git的下载与安装&#xff1a; 直接去官网下载即可&#xff1b; 或者查看这个博客学会下载:Git 详细安装教程&#xff08;详解 Git 安装过程的每一个步骤&#xff09;_git安装-CSDN博客 注意&#xff1a;一个文件夹下只能有一个本地仓库(就是一个.git) 细节操作

C++day07(三种取整方法)

学习目标 认识流程图 多种方式解决问题 取整方式和取整函数 1.解决编程问题的过程 1.理解题意,找出关键信息。 2.整理思路,用图或者文字写出算法。 3.将算法步骤翻译为C++代码。 4.编译运行,修改语法或逻辑错误。 不符合则需要回到上一步进行修改。 5 .输入测试用例与…

Go语言实战案例-LRU缓存机制模拟

在高性能服务开发中&#xff0c;缓存是提升访问速度和减少后端负载的重要手段。常见的缓存淘汰策略中&#xff0c;**LRU&#xff08;Least Recently Used&#xff0c;最近最少使用&#xff09;**是应用最广的一种。本篇我们用Go语言手写一个LRU缓存机制的模拟实现。一、LRU缓存…

vue2中实现leader-line-vue连线文章对应字符

效果展示 通过点击右边的tag,触发连接操作 第一步:获取右边tag展示 1.右边的tag列表展示,我这边是分为两个list嵌套的数据结构; {"人员": [{

SPEA2(Strength Pareto Evolutionary Algorithm 2)优化算法简介

前言 提醒&#xff1a; 文章内容为方便作者自己后日复习与查阅而进行的书写与发布&#xff0c;其中引用内容都会使用链接表明出处&#xff08;如有侵权问题&#xff0c;请及时联系&#xff09;。 其中内容多为一次书写&#xff0c;缺少检查与订正&#xff0c;如有问题或其他拓展…