有一天开发突然照过来问,维萨我这个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 命令会做以下操作:

  1. 先对比 rename 中的两个KEY是不是一样,如果不相同则继续
  2. 对第一个KEY在db 中查找,如果存在则继续,并记录 value 对象地址
  3. 获取这个KEY 的过期时间,继续下一步
  4. 尝试着查找第二个KEY,如果第二个KEY存在则删除第二个KEY
  5. 把第二个KEY名字和第一个KEY的value 作为K-V 添加到DB中
  6. 如果第一个KEY有过期时间,则为该KEY设置过期时间
  7. 最后删除掉第一个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的更多相关文章

  1. linux mknod命令解析

    linux mknod命令解析 http://www.cnblogs.com/cobbliu/archive/2011/07/05/2389014.html mknod:make node  生成设备 ...

  2. C#基础:命令解析

    1.普通格式命令的解析 例如: RENA<SP>E:\\A.txt<SP>C:\\B.txt<CRLF> (SP -> 空格,CRLF -> 回车加换行 ...

  3. Appium Android Bootstrap源码分析之命令解析执行

    通过上一篇文章<Appium Android Bootstrap源码分析之控件AndroidElement>我们知道了Appium从pc端发送过来的命令如果是控件相关的话,最终目标控件在b ...

  4. virsh的详细命令解析(一)

    virsh的详细命令解析 virsh 有命令模式和交互模式如果直接在vrish后面添加参数是命令模式,如果直接写virsh,就会进入交互模式 virsh list 列出所有的虚拟机,虚拟机的状态有(8 ...

  5. 重命名文件或文件夹(mv命令与rename命令)

    在Linux下重命名文件或目录,可以使用mv命令或rename命令,这里分享下二者的使用方法. mv命令既可以重命名,又可以移动文件或文件夹. 例子:将目录A重命名为B mv A B 例子:将/a目录 ...

  6. (转)Linux命令:使用dig,nslookup命令解析域名

    Linux命令:使用dig命令解析域名 Linux下解析域名除了使用nslookup之外,开可以使用dig命令来解析域名,dig命令可以得到更多的域名信息. dig的全称是 (domain infor ...

  7. Linux下重命名文件或文件夹(mv命令与rename命令)

    在Linux下重命名文件或目录,可以使用mv命令或rename命令 mv ———————————— mv命令既可以重命名,又可以移动文件或文件夹. 例子:将目录A重命名为B mv A B 例子:将/a ...

  8. angular-cli.json配置参数解析,常用命令解析

    1.angular-cli.json配置参数解析 { "project": { "name": "ng-admin", //项目名称 &qu ...

  9. [Linux] Linux中重命名文件和文件夹的方法(mv命令和rename命令)

    原文链接 在Linux下重命名文件或目录,可以使用mv命令或rename命令,这里分享下二者的使用方法. mv命令既可以重命名,又可以移动文件或文件夹. 例子:将目录A重命名为B mv A B 例子: ...

随机推荐

  1. spring security 配置多个AuthenticationProvider

    前言 发现很少关于spring security的文章,基本都是入门级的,配个UserServiceDetails或者配个路由控制就完事了,而且很多还是xml配置,国内通病...so,本文里的配置都是 ...

  2. 在linux下管理iphone

    场景: linux发行版:ubuntu 14.04 64bit 3.13.0-67-generic(内核版本) iphone型号:iphone 5c (ios 8.1.3 已越狱) 准备工作(一定要先 ...

  3. DelayQueue的原理和使用浅谈

    在谈到DelayQueue的使用和原理的时候,我们首先介绍一下DelayQueue,DelayQueue是一个无界阻塞队列,只有在延迟期满时才能从中提取元素.该队列的头部是延迟期满后保存时间最长的De ...

  4. Android 模块化探索与实践

    首发于<程序员>杂志五月刊 一.前言 万维网发明人 Tim Berners-Lee 谈到设计原理时说过:"简单性和模块化是软件工程的基石:分布式和容错性是互联网的生命." ...

  5. 文本主题模型之LDA(二) LDA求解之Gibbs采样算法

    文本主题模型之LDA(一) LDA基础 文本主题模型之LDA(二) LDA求解之Gibbs采样算法 文本主题模型之LDA(三) LDA求解之变分推断EM算法(TODO) 本文是LDA主题模型的第二篇, ...

  6. Natas Wargame Level 13 Writeup(文件上传漏洞,篡改file signature,Exif)

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAqMAAADDCAYAAAC29BgbAAAABHNCSVQICAgIfAhkiAAAIABJREFUeF

  7. ionic2 使用 cordova 打包成安卓apk

    准备工作: 1.下载java sdk 配置好java 环境 2.下载android sdk 跟 android studio 并配置好环境 1.查看平台支持,添加android平台 首先命令提示符进入 ...

  8. windows搭建代理服务器

    系统环境:windows server 2008R2 利用CCProxy软件达成 安装后确保设置正确,如下图: 注意:需要编辑防火墙开启相关端口,或直接关闭内网防火墙. 设置后可用telnet测试端口 ...

  9. Java解析word文档

    背景 在互联网教育行业,做内容相关的项目经常碰到的一个问题就是如何解析word文档. 因为系统如果无法智能的解析word,那么就只能通过其他方式手动录入word内容,效率低下,而且人工成本和录入出错率 ...

  10. 解决R语言临时文件目录的问题(tempdir、tempfile)

    最近在调用SparkR的时候,当用copy_to函数将R中的数据框导入到Spark时,会在默认的tempdir()目录下(这里默认目录即为/tmp)产生巨大的临时文件, 严重影响R脚本的运行,最终一番 ...