Reids命令解析-RENAME
有一天开发突然照过来问,维萨我这个Redis实例这么慢呢?为什么这么慢,于是连上实例SLOWLOG 一看,这些慢日志都是大部分是RENMAE操作导致的,可是为什么RENAME操作会慢呢?不就是改个名字么? 难道它还做了别的事? 又或者学习Linux 的mv 操作? 先copy 再DEL ?
于是带着这个问题,问问来拜访一下REDIS源码,看看为什么RENAME操作会慢的?在Redis中RENAME相关命令有两个 rename、renamenx。
我们找到入库函数 server.c [struct redisCommand redisCommandTable[] = {}],定位到renameCommand,可以发现这两个命令后端都是调用同一个函数[ renameGenericCommand(c,N)],只是这个N这个值不同而已
所以问题就很简单了, 我们只需要知道 [renameGenericCommand] 这个函数到底做了什么操作即可,定位到这个函数不难发现,对于Rename 命令会做以下操作:
- 先对比 rename 中的两个KEY是不是一样,如果不相同则继续
- 对第一个KEY在db 中查找,如果存在则继续,并记录 value 对象地址
- 获取这个KEY 的过期时间,继续下一步
- 尝试着查找第二个KEY,如果第二个KEY存在则删除第二个KEY
- 把第二个KEY名字和第一个KEY的value 作为K-V 添加到DB中
- 如果第一个KEY有过期时间,则为该KEY设置过期时间
- 最后删除掉第一个KEY
精简过得源代码如下:
void renameGenericCommand(client *c, int nx) {
robj *o;
long long expire;
int samekey = 0;
if (sdscmp(c->argv[1]->ptr,c->argv[2]->ptr) == 0) samekey = 1;
if ((o = lookupKeyWriteOrReply(c,c->argv[1],shared.nokeyerr)) == NULL) return;
if (samekey) return;
incrRefCount(o);
expire = getExpire(c->db,c->argv[1]);
if (lookupKeyWrite(c->db,c->argv[2]) != NULL) {
dbDelete(c->db,c->argv[2]);
}
dbAdd(c->db,c->argv[2],o);
if (expire != -1) setExpire(c,c->db,c->argv[2],expire);
dbDelete(c->db,c->argv[1]);
}
所以通过以上我们可以得到如下结论:
实际上RENAME = Query * 2 + ADD + [ DEL ] + [ EXPIRE ]
而对于RENAMENX = Query * 2 + ADD + [ EXPIRE ] ,这里一定没有DEL操作
对于内存数据库REDIS 来说, QUERY 、ADD 、EXPIRE 都是很快的,但是对于某些KEY DEL则不一定块,如果这个KEY的内存占用比较多,那么DEL 是个比较慢的过程。
OK,结论似乎有了, 那么需要进一步的来验证一下这个结论,怎么验证呢?很简单,我们可以GET 出来看看这个KEY 有多大, 或者使用 DEBUG OBJECT XXXKEY 看一下序列化后的内存大小。
OK,结论也有了,也验证了,看起来是 大KEY 惹的货啊, 那么对于我们怎么找到这些大KEY,如果进行删除,请查看我的前两篇文章 :)
Reids命令解析-RENAME的更多相关文章
- linux mknod命令解析
linux mknod命令解析 http://www.cnblogs.com/cobbliu/archive/2011/07/05/2389014.html mknod:make node 生成设备 ...
- C#基础:命令解析
1.普通格式命令的解析 例如: RENA<SP>E:\\A.txt<SP>C:\\B.txt<CRLF> (SP -> 空格,CRLF -> 回车加换行 ...
- Appium Android Bootstrap源码分析之命令解析执行
通过上一篇文章<Appium Android Bootstrap源码分析之控件AndroidElement>我们知道了Appium从pc端发送过来的命令如果是控件相关的话,最终目标控件在b ...
- virsh的详细命令解析(一)
virsh的详细命令解析 virsh 有命令模式和交互模式如果直接在vrish后面添加参数是命令模式,如果直接写virsh,就会进入交互模式 virsh list 列出所有的虚拟机,虚拟机的状态有(8 ...
- 重命名文件或文件夹(mv命令与rename命令)
在Linux下重命名文件或目录,可以使用mv命令或rename命令,这里分享下二者的使用方法. mv命令既可以重命名,又可以移动文件或文件夹. 例子:将目录A重命名为B mv A B 例子:将/a目录 ...
- (转)Linux命令:使用dig,nslookup命令解析域名
Linux命令:使用dig命令解析域名 Linux下解析域名除了使用nslookup之外,开可以使用dig命令来解析域名,dig命令可以得到更多的域名信息. dig的全称是 (domain infor ...
- Linux下重命名文件或文件夹(mv命令与rename命令)
在Linux下重命名文件或目录,可以使用mv命令或rename命令 mv ———————————— mv命令既可以重命名,又可以移动文件或文件夹. 例子:将目录A重命名为B mv A B 例子:将/a ...
- angular-cli.json配置参数解析,常用命令解析
1.angular-cli.json配置参数解析 { "project": { "name": "ng-admin", //项目名称 &qu ...
- [Linux] Linux中重命名文件和文件夹的方法(mv命令和rename命令)
原文链接 在Linux下重命名文件或目录,可以使用mv命令或rename命令,这里分享下二者的使用方法. mv命令既可以重命名,又可以移动文件或文件夹. 例子:将目录A重命名为B mv A B 例子: ...
随机推荐
- 进击 spring !!
1.spring简介 Spring 是一个开源框架,是为了解决企业应用程序开发复杂性而创建的.框架的主要优势之一就是其分层架构,分层架构允许您选择使用某一个组件,同时为 J2EE 应用程序开发提供集成 ...
- 2016年BAT公司常见的Web前端面试题整理
1.JavaScript是一门什么样的语言,它有哪些特点? 没有标准答案. 2.JavaScript的数据类型都有什么? 基本数据类型:String,boolean,Number,Undefined ...
- Java学习笔记——设计模式之一.简单工厂
蜀道之难.难于上青天,侧身西望长咨嗟 --蜀道难 设计模式第一篇,简单工厂. 定义Operation类 package cn.no1.simplefactory; public abstract cl ...
- JEESZ分布式框架简介
声明:该框架面向企业,是大型互联网分布式企业架构,后期会介绍Linux上部署高可用集群项目. 项目基础功能截图(自提供了最小部分) 介绍 1. 项目核心代码结构截图 <modules& ...
- MyBatis源码解读(4)——SqlSession(上)
在上一篇博客中提到MyBatis是如何实现代理类MapperProxy,并抛出了一个问题--是怎么执行一个具体的sql语句的,在文末中提到了MapperMethod的execute采用命令模式来判断是 ...
- 【JAVAWEB学习笔记】12_Http&Tomcat
一.Http协议 1.什么是Http协议 HTTP,超文本传输协议(HyperText Transfer Protocol)是互联网上应用最为广泛的 一种网络协议.所有的WWW文件都必须遵守这 ...
- WINFORM实现进程信息的查看,listview,点击,右键,右键菜单
1. 程序设计要求 设计程序来获取计算机中的进程信息 2.程序设计流程图 3.程序设计亮点 (0)程序启动时加载guide引导使用视频 (1)使用Listview控件显示出所有控件的名称. (2) ...
- Linux环境下配置JDK,java环境
1.查看Linux自带的JDK是否已安装 # java -version 2. 查看JDK信息 # rpm -qa | grep java 显示: java-x.x.x-gcj-compat-x.x. ...
- Customer segmentation – LifeCycle Grids, CLV and CAC with R(转)
We studied a very powerful approach for customer segmentation in the previous post, which is based o ...
- tornado之文件上传的几种形式form,伪ajax(iframe)
1直接form提交给后台处理 <!DOCTYPE html> <html lang="en"> <head> <meta charset= ...