Redis设计与实现之慢查询日志

news2025/1/11 4:07:39

目录

一、慢查询日志

1、相关数据结构

2、慢查询日志的记录

 3、慢查询日志的操作

4、如何设置慢查询的阈值? 

5、如何查看慢查询日志的内容?

6、如何分析慢查询日志以找出性能瓶颈?

7、如何优化慢查询以提高Redis的性能?

8、慢查询日志对Redis的性能有何影响?

9、是否可以禁用慢查询日志?

10、如何定期清理慢查询日志以减少磁盘空间占用?

11、在集群模式下如何处理慢查询日志?

二、小结


一、慢查询日志

慢查询日志是 Redis 提供的一个用于观察系统性能的功能,这个功能的实现非常简单,这里我们也简单地讲解一下。

本章先介绍和慢查询功能相关的数据结构和变量,然后介绍 Redis 是如何记录命令的执行时间,以及如何为执行超过限制事件的命令记录慢查询日志的。

1、相关数据结构

每条慢查询日志都以一个 slowlog.h/slowlogEntry 结构定义:

typedef struct slowlogEntry { 
    // 命令参数
    robj **argv; 
    // 命令参数数量
    int argc;
    // 唯一标识符
    long long id; /* Unique entry identifier. */
    // 执行命令消耗的时间,以纳秒(1 / 1,000,000,000 秒)为单位
    long long duration; /* Time spent by the query, in nanoseconds. */
    // 命令执行时的时间
    time_t time; /* Unix time at which the query was executed. */
} slowlogEntry;

记录服务器状态的 redis.h/redisServer 结构里保存了几个和慢查询有关的属性:

struct redisServer { 
    // ... other fields
    // 保存慢查询日志的链表 list 
    *slowlog; /* SLOWLOG list of commands */
    // 慢查询日志的当前 id 值 
    long long slowlog_entry_id;/* SLOWLOG current entry ID */
    // 慢查询时间限制
    long long slowlog_log_slower_than; /* SLOWLOG time limit (to get logged) */
    // 慢查询日志的最大条目数量
    unsigned long slowlog_max_len; /* SLOWLOG max number of items logged */ 
    // ... other fields
};

slowlog 属性是一个链表,链表里的每个节点保存了一个慢查询日志结构,所有日志按添加时 间从新到旧排序,新的日志在链表的左端,旧的日志在链表的右端。

slowlog_entry_id 在创建每条新的慢查询日志时增一,用于产生慢查询日志的 ID (这个 ID 在执行 SLOWLOG RESET 之后会被重置)。

slowlog_log_slower_than 是用户指定的命令执行时间上限,执行时间大于等于这个值的命令 会被慢查询日志记录。

slowlog_max_len 慢查询日志的最大数量,当日志数量等于这个值时,添加一条新日志会造成 最旧的一条日志被删除。

下图展示了一个 slowlog 属性的实例:

2、慢查询日志的记录

在每次执行命令之前,Redis 都会用一个参数记录命令执行前的时间,在命令执行完之后,再 计算一次当前时间,然后将两个时间值相减,得出执行命令所耗费的时间值 duration ,并将 duration传给 slowlogPushEntryIfNeed 函数。

如果 duration 超过服务器设置的执行时间上限 server.slowlog_log_slower_than 的话, slowlogPushEntryIfNeed 就会创建一条新的慢查询日志,并将它加入到慢查询日志链表里。可以用一段伪代码来表示这个过程:

def execute_redis_command_with_slowlog(): 
    # 命令执行前的时间
    start = ustime() 
    # 执行命令
    execute_command(argv, argc)
    # 计算命令执行所耗费的时间 
    duration = ustime() - start
    if slowlog_is_enabled: 
    slowlogPushEntryIfNeed(argv, argc, duration)

def slowlogPushEntryIfNeed(argv, argc, duration)
    # 如果执行命令耗费的时间超过服务器设置命令执行时间上限 
    # 那么创建一条新的 slowlog
    if duration > server.slowlog_log_slower_than:
        # 创建新 slowlog
        log = new slowlogEntry()
        # 设置各个域
        log.argv = argv
        log.argc = argc
        log.duration = duration
        log.id = server.slowlog_entry_id log.time = now()
        # 将新 slowlog 追加到日志链表末尾 
        server.slowlog.append(log)
        # 更新服务器 
        slowlog server.slowlog_entry_id += 1

 3、慢查询日志的操作

 针对慢查询日志有三种操作,分别是查看、清空和获取日志数量:

  • 查看日志:在日志链表中遍历指定数量的日志节点,复杂度为 O(N) 。

  • 清空日志:释放日志链表中的所有日志节点,复杂度为 O(N) 。

  • 获取日志数量:获取日志的数量等同于获取 server.slowlog 链表的数量,复杂度为 O(1) 。

4、如何设置慢查询的阈值? 

在Redis中,可以通过设置slowlog-log-slower-than参数来设置慢查询的阈值。

该参数的默认值是10000,单位是微秒。这意味着,如果一个查询的执行时间超过10毫秒,则会被记录在慢查询日志中。

你可以通过以下方式来设置慢查询的阈值:

  1. 修改Redis配置文件redis.conf,在文件中找到slowlog-log-slower-than,修改其值为你希望的慢查询阈值,例如:

    slowlog-log-slower-than 5000
    

    这里将慢查询阈值设置为5毫秒。

  2. 或者,在Redis启动后,使用命令CONFIG SET来修改该参数的值。例如:

    CONFIG SET slowlog-log-slower-than 5000
    

    这里同样将慢查询阈值设置为5毫秒。

请注意,修改Redis参数后,需要重启Redis服务才能生效。

5、如何查看慢查询日志的内容?

要查看Redis的慢查询日志的内容,需要按照以下步骤进行操作:

  1. 打开Redis的配置文件redis.conf,查找以下配置项:

    slowlog-log-slower-than 10000
    slowlog-max-len 128
    

    slowlog-log-slower-than配置项定义了超过多少微秒的查询会被记录到慢查询日志中,默认值是10000微秒(10毫秒)。

    slowlog-max-len配置项定义了慢查询日志的最大长度,默认值是128。

  2. 检查Redis服务器是否启用了慢查询日志功能。在Redis的命令行界面上执行CONFIG GET slowlog-log-slower-than命令,如果返回的值大于0,则表示慢查询日志功能已启用。

  3. 检查慢查询日志的长度。在Redis的命令行界面上执行SLOWLOG LEN命令,返回的值表示当前慢查询日志中记录的慢查询数量。

  4. 查看慢查询日志的内容。在Redis的命令行界面上执行SLOWLOG GET命令,可以返回所有慢查询日志的详细信息,包括查询命令、执行时间等。

注意:慢查询日志是以队列的形式存储在内存中的,当队列长度达到了设置的最大长度时,新的慢查询日志会覆盖最早的日志。如果要持久化保存慢查询日志,可以使用Redis的持久化功能将日志写入磁盘文件。

6、如何分析慢查询日志以找出性能瓶颈?

要分析Redis慢查询日志以找出性能瓶颈,可以按照以下步骤进行:

  1. 打开Redis配置文件(redis.conf)并启用慢查询日志记录。找到slowlog-log-slower-than配置项并设置一个合适的阈值,表示执行时间超过该阈值的命令将被记录为慢查询。例如,将阈值设置为10000,表示执行时间超过10毫秒的命令将被记录。

  2. 重启Redis服务使配置生效。

  3. 使用Redis的SLOWLOG GET命令可以获取慢查询日志信息。可以通过指定参数SLOWLOG GET n来获取最近的n条慢查询日志。

  4. 分析慢查询日志时,可以关注以下几点:

    • 查看命令执行时间(duration)是否超过预期。可以根据具体需求来判断哪些命令执行时间太长,从而找出潜在的性能瓶颈。

    • 查看命令的执行次数(count)以及执行时间总和(total duration)。这可以帮助你确定哪些命令对Redis的性能影响最大。

    • 查看命令的调用者(client name)和客户端地址(client address)。这可能有助于定位哪些客户端对Redis的性能产生较大负担。

    • 查看命令的参数,特别是那些可能会导致性能问题的参数。例如,使用KEYS命令获取所有键可能会导致性能问题,可以考虑改为使用SCAN命令。

  5. 如果发现某些命令执行时间过长,可以通过以下方式来优化性能:

    • 使用Redis的管道(pipeline)机制批量执行多个命令,减少网络开销和服务器响应时间。

    • 使用Redis的事务(transaction)机制将多个命令包装在一个事务中,减少多次网络往返的开销。

    • 使用Redis的持久化功能,将一些频繁访问的数据加载到内存中,减少磁盘IO开销。

    • 合理设计数据结构和命令调用方式,避免不必要的命令调用和数据转换操作。

通过以上步骤,你可以分析Redis慢查询日志并找出性能瓶颈,从而优化Redis的性能。

7、如何优化慢查询以提高Redis的性能?

要优化慢查询以提高Redis的性能,可以采取以下几个步骤:

  1. 使用正确的数据结构:Redis支持多种数据结构,如字符串、哈希表、列表、集合和有序集合等。根据实际需求选择合适的数据结构,以便更高效地使用Redis。

  2. 合理设置索引:对于需要频繁查询的数据,可以考虑使用Redis的有序集合或哈希表来建立索引,以加快查询速度。

  3. 使用批量操作:Redis支持批量操作,如批量获取和批量设置操作等。通过减少网络请求次数,可以提高性能。尽量将多个操作合并到一次请求中。

  4. 避免频繁的数据库查询:如果Redis作为缓存层使用,尽量避免频繁的数据库查询,可以通过设置合适的过期时间和适当的缓存策略来减轻数据库负载。

  5. 使用Pipeline技术:Redis的Pipeline技术可以将多个命令打包成一个批处理命令,减少网络开销。通过使用Pipeline技术,可以大幅度提高性能。

  6. 适当使用持久化功能:Redis支持持久化功能,可以将数据写入磁盘,以防止数据丢失。但是,持久化功能会对性能产生一定影响。因此,需要根据实际需求,选择是否启用持久化功能。

  7. 配置合理的内存策略:根据实际情况,合理配置Redis的最大内存限制和数据淘汰策略,以充分利用有限的内存资源。

  8. 配置合理的网络参数:根据实际网络环境,优化网络参数,如TCP连接数、超时时间等,以提高网络通信的性能。

  9. 使用连接池:为了减少每次请求时的连接建立和断开开销,可以使用连接池技术,提前创建连接并重复利用。

  10. 使用集群模式:当单机Redis无法满足需求时,可以考虑使用Redis集群模式,将数据分片存储在多个Redis节点上,以提高性能和可伸缩性。

通过以上优化措施,可以显著提高Redis的性能,并提升系统的整体运行效率。

8、慢查询日志对Redis的性能有何影响?

慢查询日志可以对Redis的性能产生一定影响,主要体现在以下几个方面:

  1. I/O开销:启用慢查询日志会增加对磁盘的写入操作,增加了I/O开销。尤其是在高并发读写场景下,频繁写入慢查询日志可能会影响Redis的性能。

  2. CPU开销:Redis在记录慢查询日志时需要对查询进行解析和分析,这会增加CPU的使用量。对于高负载的Redis服务器来说,频繁记录慢查询日志可能会竞争CPU资源,导致性能下降。

  3. 空间占用:慢查询日志会占用一定的存储空间,特别是在长期记录慢查询日志的情况下,可能会占用较大的磁盘空间。

为了减轻对Redis性能的影响,可以采取以下措施:

  1. 适量记录:根据实际情况设置阈值,只记录超过一定执行时间的慢查询,避免记录过多的查询。

  2. 异步记录:将慢查询日志记录操作异步化,通过将慢查询信息写入队列或发送到其他存储系统,减少对Redis主线程的阻塞。

  3. 定期清理:定时清理过期的慢查询日志,避免占用过多的存储空间。

总之,慢查询日志可以提供有价值的性能分析信息,但在启用的同时需注意对性能的影响,合理设置慢查询日志的记录策略。

9、是否可以禁用慢查询日志?

是的,Redis可以禁用慢查询日志。你可以通过修改Redis的配置文件(redis.conf)来禁用慢查询日志的记录。找到配置文件中的slowlog-log-slower-than指令,将其值设置为-1即可禁用慢查询日志。然后重新启动Redis服务器使修改生效。

10、如何定期清理慢查询日志以减少磁盘空间占用?

Redis没有内置机制来自动清理慢查询日志。如果你希望定期清理慢查询日志以减少磁盘空间占用,可以考虑使用以下方法:

  1. 使用Redis的SLOWLOG RESET命令手动清空慢查询日志。执行该命令后,慢查询日志将被清空。

  2. 使用外部脚本或工具定期执行Redis的SLOWLOG RESET命令。你可以编写一个脚本来定期执行该命令,例如使用Cron定时任务或其他调度工具。

  3. 在Redis配置文件中设置slowlog-max-len参数来限制慢查询日志的数量。该参数指定了慢查询日志的最大长度,默认为128条。当慢查询日志达到最大长度时,旧的慢查询日志将被自动删除。

请注意,清理慢查询日志可能会导致你失去一些有用的诊断信息。如果你需要保留慢查询日志进行性能分析和问题排查,可以将日志定期备份到其他存储介质,如远程服务器或云存储服务。

11、在集群模式下如何处理慢查询日志?

在Redis集群模式下,慢查询日志的处理与单节点模式下略有不同。以下是在Redis集群模式下处理慢查询日志的一些建议方法:

  1. 通过设置slowlog-log-slower-than参数来定义慢查询的阈值,表示执行时间超过该值的命令将被记录为慢查询。可以根据需求调整该参数的值,通常建议设置为一个合理的时间阈值。

  2. 启用慢查询日志记录,在Redis配置文件中设置slowlog-max-len参数,定义慢查询日志的最大长度。可以根据需要将该值设置为一个适当的数字。

  3. 使用slowlog get命令来获取最近的慢查询日志,可以根据需要获取最新的日志或者历史日志。可以使用slowlog reset命令来重置慢查询日志,可以在某些情况下对维护和监控很有帮助。

  4. 使用Redis的监控命令来监视Redis集群中的各个节点的性能。可以使用info命令获取Redis集群的信息,例如内存使用情况、连接数、命令处理速度等等。这些信息可以帮助找到潜在的性能瓶颈。

  5. 如果发现慢查询是由于某个特定的命令或操作引起的,可以考虑使用Redis的性能分析工具来进一步分析和优化该命令。

总之,在Redis集群模式下处理慢查询日志需要结合Redis的监视和分析工具,以及适当的参数设置来获取和分析性能数据,从而找到潜在的性能问题并采取相应的优化措施。

二、小结

• Redis 用一个链表以 FIFO 的顺序保存着所有慢查询日志。

• 每条慢查询日志以一个慢查询节点表示,节点中记录着执行超时的命令、命令的参数、命 令执行时的时间,以及执行命令所消耗的时间等信息。

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

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

相关文章

人工智能_机器学习069_SVM支持向量机_网格搜索_交叉验证参数优化_GridSearchCV_找到最优的参数---人工智能工作笔记0109

然后我们再来说一下SVC支持向量机的参数优化,可以看到 这次我们需要,test_data这个是测试数据,容纳后 train_data这个是训练数据 这里首先我们,导出 import numpy as np 导入数学计算包 from sklearn.svm import SVC 导入支持向量机包 分类器包 def read_data(path): wit…

纵横字谜的答案 Crossword Answers

纵横字谜的答案 Crossword Answers - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 翻译后大概是&#xff1a; 有一个 r 行 c 列 (1<r,c<10) 的网格&#xff0c;黑格为 * &#xff0c;每个白格都填有一个字母。如果一个白格的左边相邻位置或者上边相邻位置没有白格&…

【Vue2】Component template should contain exactly one root element.

问题描述 [plugin:vite:vue2] Component template should contain exactly one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead.原因分析 这个错误通常是由于 Vue 组件的模板中包含多个根元素导致的。Vue 要求组件模板中只…

【计算机网络】TCP协议——3. 可靠性策略效率策略

前言 TCP是一种可靠的协议&#xff0c;提供了多种策略来确保数据的可靠性传输。 可靠并不是保证每次发送的数据&#xff0c;对方都一定收到&#xff1b;而是尽最大可能让数据送达目的主机&#xff0c;即使丢包也可以知道丢包。 目录 一. 确认应答和捎带应答机制 二. 超时重…

Linear Regression线性回归(一元、多元)

目录 介绍&#xff1a; 一、一元线性回归 1.1数据处理 1.2建模 二、多元线性回归 2.1数据处理 2.2数据分为训练集和测试集 2.3建模 介绍&#xff1a; 线性回归是一种用于预测数值输出的统计分析方法。它通过建立自变量&#xff08;也称为特征变量&#xff09;和因变…

什么店生意好?C++采集美团商家信息做数据分析

最近遇到几个朋友&#xff0c;想要一起合伙投资一个实体店&#xff0c;不问类型&#xff0c;就看哪类产品相对比较受欢迎。抛除地址位置&#xff0c;租金的影响&#xff0c;我们之谈产品。因此&#xff0c;我熬了几个通宵&#xff0c;写了这么一段爬取美团商家商品信息的数据并…

Linux之grep、sed、awk

目录 1.grep 2.sed 3.awk 1.grep grep 擅长过滤查找&#xff0c;按行进行过滤 例&#xff1a; 当有用户对我们的主机进行爆破攻击时&#xff0c;我们可以使用grep将 ip 查找出来&#xff0c;进行封锁等处理 在 /var/log 目录下的 secure 文件中存放在用户登录连接信息&am…

JVM 垃圾回收详解

前言 什么是垃圾? 垃圾是指运行程序中没有任何引用指向的对象&#xff0c;需要被回收。 内存溢出和内存泄漏 内存溢出&#xff1a;经过垃圾回收之后&#xff0c;内存仍旧无法存储新创建的对象&#xff0c;内存不够溢出。 内存泄漏&#xff1a;又叫“存储泄漏”&#xff0…

Docker与微服务:构建和部署微服务架构的完整指南

微服务架构已经成为现代应用开发的主要范式之一&#xff0c;而Docker容器技术则为微服务的构建、部署和管理提供了理想的解决方案。本文将深入探讨如何使用Docker构建和部署微服务架构&#xff0c;提供更多示例代码和细致的指南&#xff0c;以帮助大家更全面地理解和运用这些关…

简单几步完成SVN的安装

介绍以及特点 SVN&#xff1a;Subversion&#xff0c;即版本控制系统。 1.代码版本管理工具 2.查看所有的修改记录 3.恢复到任何历史版本和已经删除的文件 4.使用简单上手快&#xff0c;企业安全必备 下载安装 SVN的安装分为两部分&#xff0c;第一部分是服务端安装&…

从零开始在Linux服务器配置并运行YOLO8+Web项目

✅作者简介&#xff1a;大家好&#xff0c;我是 Meteors., 向往着更加简洁高效的代码写法与编程方式&#xff0c;持续分享Java技术内容。 &#x1f34e;个人主页&#xff1a;Meteors.的博客 &#x1f49e;当前专栏&#xff1a; 神经网络&#xff08;随缘更新&#xff09; ✨特色…

Docker介绍,Docker安装

docker镜像仓库官网 一、Docker的基本概念 1.Docker的三大核心组件 docker 镜像 --------docker images docker 仓库---------docker registeries docker 容器---------docker containers 2.Docker 镜像 Docker镜像是运行docker容器时的只读模板&#xff0c;每一个镜像由一…

20、WEB攻防——PHP特性缺陷对比函数CTF考点CMS审计实例

文章目录 一、PHP常用过滤函数&#xff1a;1.1 与1.2 md51.3 intval1.4 strpos1.5 in_array1.6 preg_match1.7 str_replace CTFshow演示三、参考资料 一、PHP常用过滤函数&#xff1a; 1.1 与 &#xff1a;弱类型对比&#xff08;不考虑数据类型&#xff09;&#xff0c;甚至…

vue使用xlsx和xlsx-style导出xlsx文件并修改样式

1.下载依赖 npm install xlsx --save npm install file-saver --save npm install xlsx-style --save2.先修改xlsx-style的源码&#xff0c;一旦引入xlsx-style则会报错 在\node_modules\xlsx-style\dist\cpexcel.js 807行 的 var cpt require(’./cpt’ ‘able’); 改成 v…

Mongodb复制集架构

目录 复制集架构 复制集优点 复制集模式 复制集搭建 复制集常用命令 复制集增删节点 复制集选举 复制集同步 oplog分析 什么是oplog 查看oplog oplog大小 复制集架构 复制集优点 数据复制: 数据在Primary节点上进行写入&#xff0c;然后异步地复制到Secondary节点&a…

四十七----redux

一、redux redux⽤于状态集中存储,状态的更新必须是⼀种可预测的⽅式更新。严格的单向数据流是Redux架构的设计核⼼。 这意味着应⽤中所有的数据都遵循相同的⽣命周期,这样可以让应⽤变得更加可预测且容易理解。 什么时候用redux? 多交互,多数据源等场景某个组件的状态,需…

C#拼接JSON

一、业务背景 最近项目需要与U8c对接&#xff0c;实现增删改查&#xff0c;借此机会&#xff0c;梳理一下C#解析Json字符串的问题。 这篇文章&#xff0c;先以新增接口为例。 二、新增接口 查看需要传入的json格式。 拼接json&#xff0c;无非就是{}和[]的来回嵌套。 首先&am…

机器人制作开源方案 | 智能水果分拣机器人

作者&#xff1a;史振鹏 岳欣宇 仲祝伟 单位&#xff1a;邢台学院 指导老师&#xff1a;王承林 魏亚清 一、场景调研 智能水果分拣机器人是基于探索者设计的一款可搬运可分拣以及移动的一款轻便机器人&#xff0c;集成了语音控制、分拣、搬运、识别、抓取等功能&#xff0c;…

Java 序列化机制详解

Java 序列化机制是一种将对象转换为字节流的过程&#xff0c;以便在网络上传输或保存到文件中&#xff0c;并能在需要时将字节流还原为对象。这一机制通过实现 java.io.Serializable 接口来实现&#xff0c;同时涉及到一些关键概念和注意事项。 Serializable 接口 Serializabl…

vscode使用remote ssh到server上 - Node进程吃满CPU

起因&#xff1a;Node进程吃满CPU 分析 我发现每次使用vscode的remote插件登陆到server后&#xff0c;就会出现node进程&#xff0c;不太清楚干什么用的&#xff0c;但是绝对和它有关。 查找原因 首先找到了这篇文章&#xff0c;解决了rg进程的问题&#xff1a; https://blo…