《Reids 设计与实现》第十九章 慢查询日志
《Reids 设计与实现》第十九章 慢查询日志
文章目录
- 《Reids 设计与实现》第十九章 慢查询日志
- 一、简介
- 二、慢查询记录的保存
- 三、慢查询日志的阅览和删除
- 四、添加新日志
- 五、重点回顾
一、简介
Redis 的慢查询日志功能用于记录执行时间超过给定时长的命令请求,用户可以同故宫这个功能产生的日志来监视和优化查询速度
服务器配置有两个和慢查询日志相关的选项:
- slowlog-log-slower-than 选项指定执行时间超过多少微秒( 1 秒等于 1000000 微秒)的命令请求会被记录到日志上
- slowlog-max-len 选项指定服务器最多保存多少条慢查询日志
服务器使用先进先出的方式保存多条慢查询日志,当服务器存储的慢查询日志数量等于 slowlog-max-len 选项的值时,服务器在添加一条新的慢查询日志之前,会先将最旧的一条慢查询日志删除
二、慢查询记录的保存
服务器状态中包含了几个和慢查询日志功能有关的属性:
struct redisServer{//...//下一条慢查询日志的 IDlong long slowlog_entry_id;//保存了所有慢查询日志的链表list *slowlog;//服务器配置 slowlog-log-slower-than 选项的值long long slowlog_log_slower_than;//服务器配置 slowlog-max-len 选项的值ussigned long slowlog_max_len;//...
};
slowlog_entry_id 属性的初始值为 0,每当创建一条新的慢查询日志时,这个属性的值就会用作新日志的 id 值,之后程序会对这个属性的值增一
例如,在创建第一条慢查询日志时,slowlog_entry_id 的值 0 会成为第一条慢查询日志的 ID,而之后服务器会对这个属性的值增一;当服务器再创建新的慢查询日志的时候,slowlog_entry_id 的值 1 就会成为第二条慢查询日志的 ID,然后服务器再次对这个属性的值增一,以此类推
slowlog 链表保存了服务器中的所有慢查询日志,链表中的每个节点都保存了一个 slowlogEntry 结构,每个 slowlogEntry 结构代表一条慢查询日志:
typedef struct slowlogEntry{//唯一标识符long long id;//命令执行时的时间,格式为 UNIX 时间戳time_t time;//执行命令消耗的时间,以微秒为单位long long duration;//命令与命令参数robj **argv;//命令与命令参数的数量int argc;
}slowlogEntry;
举个例子,对于以下慢查询日志来说:
1)(integer) 3
2)(integer) 1378781439
3)(integer) 10
4)1)"SET"2)"number"3)"10086"
图 23-1 展示的是该日志所对应的 slowlogEntry 结构
图 23-2 展示了服务器状态中和慢查询功能有关的属性:
- slowllog_entry_id 的值为 6,表示服务器下条慢查询日志的 id 值将为6
- slowlog 链表包含了 id 为 5 至 1 的慢查询日志,最新的 5 号日志排在链表的表头,而最旧的 1 号日志排在链表的表尾,这表明 slowlog 链表是使用插入到表头的方式来添加新日志的
- slowlog_log_slower_than 记录了服务器配置 slowlog-log-slower-than 选项的值 0,表示任何执行时间超过 0 微秒的命令都会被慢查询日志记录
- slowlog-max-len 属性记录了服务器配置 slowlog-max-len 选项的值 5,表示服务器最多储存五条慢查询日志
三、慢查询日志的阅览和删除
弄清楚了服务器状态的 slowlog 链表的作用之后,我们可以用以下伪代码来定义查看日志的 SLOWLOG GET 命令:
def SLOWLOG_GET(number=None):#用户没有给定 number 参数#那么打印服务器包含的全部慢查询日志if number is None:number = SLOWLOG_LEN()#遍历服务器中的慢查询日志for log in redisServer.slowlog:if number <= 0:#打印的日志数量已经足够,跳出循环breakelse:#继续打印,将计数器的值减一number -= 1#打印日志printLog(log)
查看日志数量的 SLOWLOG LEN 命令可以用以下伪代码来定义:
def SLOWLOG_LEN():#slowlog 链表的长度就是慢查询日志的条目数量return len(redisServer.slowlog)
另外,用于清除所有慢查询日志的 SLOWLOG RESET 命令可以用以下伪代码来定义:
def SLOWLOG_RESET():#遍历服务器中的所有慢查询日志for log in redisServer.slowlog:#删除日志deleteLog(log)
四、添加新日志
在每次执行命令的之前和之后,程序都会记录微秒格式的当前 UNIX 时间戳,这两个时间戳之间的差就是服务器执行命令所耗费的时长,服务器会将这个时长作为参数之一传给 slowlogPushEntryIfNeeded 函数,而 slowlogPushEntryIfNeeded 函数负责检查是否需要为这次执行的命令创建慢查询日志,以下伪代码展示了这一过程:
#记录执行命令前的时间
before = unixtime_now_in)us()#执行命令
execute_command(argv, argc, client)#记录执行命令后的时间
after = unixtime_now_in_us()#检查是否需要创建新的慢查询日志
slowlogPushEntryIfNeeded(argv, argc, before-after)
slowlogPushEntryIfNeeded 函数的作用有两个:
- 检查命令的执行时长是否超过 slowlog-log-slower-than 选项所设置的时间,如果是的话,就为命令创建一个新的日志,并将新日志添加到 slowlog 链表的表头
- 检查慢查询日志的长度是否超过 slowlog-max-len 选项所设置的长度,如果是的话,那么将多出来的日志从 slowlog 链表中删除掉
以下是 slowlogPushEntryIfNeeded 函数的实现代码:
void slowlogPushEntryIfNeeded(robj **argv, int argc, long long duration){//慢查询功能未开启,直接返回if(server.slowlog_log_slower_than < 0) return;//如果执行时间超过服务器设置的上限,那么将命令添加到慢查询日志if(duration >= server.slowlog_log_slower_than)//新日志添加到链表表头listAddNodedHead(server.slowlog, slowlogCreateEntry(argv, argc, duration));//如果日志数量过多,那么进行删除while(listLength(server.slowlog) > server.slowlog_max_len)listDelNode(server.slowlog, listLast(server.slowlog));
}
函数中的大部分代码我们已经介绍过了,唯一需要说明的就是 slowlogCreateEntry 函数:该函数根据传入的参数,创建一个新的慢查询日志,并将 redisServer.slowlog_entry_id 的值增 1
五、重点回顾
- Redis 的慢查询日志功能用于记录执行时间超过指定时长的命令
- Redis 服务器将所有的慢查询日志保存在服务器状态的 slowlog 链表中,每个链表节点都包含一个 slowlogEntry 结构,每个 slowlogEntry 结构代表一条慢查询日志
- 打印和删除慢查询日志可以通过遍历 slowlog 链表来完成
- slowlog 链表的长度就是服务器所保存慢查询日志的数量
- 新的慢查询日志会被添加到 slowlog 链表的表头,如果日志的数量超过 slowlog-max-len 选项的值,那么多出来的日志会被删除
《Reids 设计与实现》第十九章 慢查询日志相关推荐
- 《Reids 设计与实现》第十三章 Sentinel
<Reids 设计与实现>第十三章 Sentinel 文章目录 <Reids 设计与实现>第十三章 Sentinel 一.简介 二.启动并初始化 Sentinel 1.初始化服 ...
- 《Reids 设计与实现》第五章 对象
<Reids 设计与实现>第五章 对象 文章目录 <Reids 设计与实现>第五章 对象 一.简介 二.对象的类型与编码 1.类型 2.编码和底层实现 三.字符串对象 1.编码 ...
- bmp文件头_「正点原子FPGA连载」第十九章SD卡读BMP图片LCD显示
1)摘自[正点原子]领航者 ZYNQ 之嵌入式开发指南 2)实验平台:正点原子领航者ZYNQ开发板 3)平台购买地址:https://item.taobao.com/item.htm?&id= ...
- 数字图像处理:第十九章 立体视觉
第十九章 立体视觉 目录 1. 引言 2. 双目立体视觉(BinocularStereo Vision) 2.1 双目立体视觉模型 2.2 匹配基元 2.3 匹配算法 2.4 双目立体视觉 ...
- 鸟哥的Linux私房菜(基础篇)- 第十九章、认识与分析登录文件
第十九章.认识与分析登录文件 最近升级日期:2009/09/14 当你的 Linux 系统出现不明原因的问题时,很多人都告诉你,你要查阅一下登录文件才能够知道系统出了什么问题了,所以说,了解登录文件是 ...
- stm32l0的停止模式怎么唤醒_「正点原子STM32Mini板资料连载」第十九章 待机唤醒实验...
1)实验平台:正点原子STM32mini开发板 2)摘自<正点原子STM32 不完全手册(HAL 库版)>关注官方微信号公众号,获取更多资料:正点原子 第十九章 待机唤醒实验 本章我们将向 ...
- 《Reids 设计与实现》第六章 数据库
<Reids 设计与实现>第六章 数据库 文章目录 <Reids 设计与实现>第六章 数据库 一.服务器中的数据库 二.切换数据库 三.数据库键空间 四.设置键的生存时间或过期 ...
- c语言头文件格式图片_阿波罗 STM32F767 开发板资料连载第四十九章 图片显示实验...
1)实验平台:alientek 阿波罗 STM32F767 开发板2)摘自<STM32F7 开发指南(HAL 库版)>关注官方微信号公众号,获取更多资料:正点原子 第四十九章 图片显示实验 ...
- 【正点原子FPGA连载】第三十九章OV7725摄像头RGB-LCD显示实验 -摘自【正点原子】新起点之FPGA开发指南_V2.1
1)实验平台:正点原子新起点V2开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=609758951113 2)全套实验源码+手册+视频下载地址:ht ...
最新文章
- 日志——Vue.js开发在线简历生成器
- ios 扑克牌效果轮播_iOS一行代码实现立体轮播图
- 暴汗,今天遇到个奇事
- Request中getContextPath、getServletPath、getRequestURI、getRequestURL、getRealPath的区别
- 十二五期间三网融合将有实质性进展
- CSS3实现漂亮ToolTips
- linux bind日志级别,BIND日志相关(一)
- Leetcode--23.合并K个排序链表(Java)
- 关于CSS的碎片学习
- Servlet 与 CGI 的比较
- 理解 webpack 热更新
- Android开发面试经——2.常见Android基础笔试题
- Struts xml中Action的method与路径的三种匹配方法
- 关于Redis的常见面试题解析
- vim个性化设置---给脚本文件加注释头信息
- EAGLE layout 拼板方法
- WIN7共享WIFI
- 微软出品的Python小白神器,真香!
- 为什么自学前端容易失败?数千名新手程序员得出结论
- 我用Python分析了翟天临的论文,学术还是要认真做啊
热门文章
- 定期存款可以提前取出来吗_定期存款、约定转存、自动转存和自己取出来转存有什么不同?...
- mysql 删除了授权_mysql用户授权访问与删除授权
- mysql 从库开启复制慢日志_Mysql数据库优化之开启慢查询日志
- XML指南——XML元素
- LeeCode-------Letter Combinations of a Phone Number 解法
- 织梦标签把","逗号改成空格技巧
- 在Tomcat启动时直接创建servlet(二)
- Struts1 生成Action请求的几种方式分析
- Android入门:封装一个HTTP请求的辅助类
- 企业视觉-大型电商(系统)高性能-用户视觉性能(1)