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 命令会做以下操作:

  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,如果进行删除,请查看我的前两篇文章 :)

时间: 2024-10-05 07:22:57

Reids命令解析-RENAME的相关文章

Ubuntu16.04安装mysql和命令解析

一.Mysql的安装 1.安装mysql的服务端和客户端 apt install mysql-server sudo apt install mysql-client  sudo apt install libmysqlclient-dev 2.测试是否安装成功: sudo netstat -tap | grep mysql 3.设置mysql允许远程访问: vim /etc/mysql/mysql.conf.d/mysqld.cnf 注释掉bind-address = 127.0.0.1: 4

闲云控制台(一)控制台命令解析框架

发布闲云控制台连载系列,会不定期加入新功能~ 先发一个命令解析的框架 /************************************************** *******************闲云万能控制台********************* ********* ********* 作者: 闲云野鹤 ********* QQ: 836663997 ********* QQ群: 116920287 欢迎加入 ********* 邮箱: [email protected]

linux 命令解析2

基本命令  uname -a -s hostname显示主机名若是要永久生效,则编辑以下文件  #vim /etc/sysconfig/network    ssh远程登录#ssh 10.1.1.54 (是以root用户登录的)  #ssh [email protected](是以tom身份登录)  #ssh -Y 10.1.1.54(可以启动图形界面的远程登陆) scp远程拷贝  #scp 10.1.1.54:/etc/passwd /tmp/test(将目的地址10.1.1.54上的/etc

liunx 命令解析1

RHEL5.3安装光盘主要文件内容:ClusterClusterStorageimagesisolinuxServerVT showmount -e 10.1.1.20显示指定的主机可供挂载的目录 将U盘作为引导盘dd if=diskboot.img of=/dev/sdb CTRL + SHIFT + T增加终端标签 常用的shell  cat /etc/shells    /bin/sh   /bin/bash   /sbin/nologin   /bin/tcsh   /bin/csh 

ASA 8.0命令解析

有些朋友对配防火墙还是有问题,其实配置ASA防火墙很简单,常用的命令有hostname.interface(ip address.no shutdown.nameif.security-level).nat.global.route.static.access-list.access-group. 下面来解析一台ASA 8.0的配置 ASA Version 8.0(2)  //注意版本,8.3以后NAT命令有所变化!hostname ciscoasa   //主机名domain-name san

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

在Linux下重命名文件或目录,可以使用mv命令或rename命令 mv ------------ mv命令既可以重命名,又可以移动文件或文件夹. 例子:将目录A重命名为B mv A B 例子:将/a目录移动到/b下,并重命名为c mv /a /b/c 其实在文本模式中要重命名文件或目录,只需要使用mv命令就可以了,比如说要将一个名为abc的文件重命名为1234: mv abc 1234 注意,如果当前目录下也有个1234的文件的话,这个文件是会将它覆盖的. rename -----------

Linux中的命令解析

命令解析: [[email protected]~]# []                  没有特殊意义 root:             当前登录用户(管理员用户) @                 没有特殊含义 localhost      主机名 ~                  代表当前所在(~家目录) #                  代表当前登录用户是管理员 $                  如果是$则表示普通用户 ----------- 关于文件 格式: 命令

Linux c 开发 - Memcached源码分析之命令解析(2)

前言 从我们上一章<Linux c 开发 - Memcached源码分析之基于Libevent的网络模型>我们基本了解了Memcached的网络模型.这一章节,我们需要详细解读Memcached的命令解析. 我们回顾上一章发现Memcached会分成主线程和N个工作线程.主线程主要用于监听accpet客户端的Socket连接,而工作线程主要用于接管具体的客户端连接. 主线程和工作线程之间主要通过基于Libevent的pipe的读写事件来监听,当有连接练上来的时候,主线程会将连接交个某一个工作线

ASA 8.4命令解析

前面发表了一篇文章是ASA 8.0版本的,后面用到8.4发现命令有很多不一样,特发一篇8.4版本的命令可以和前面命令做对比和参考 需要注意的是 1.这边没有nat 0,也就是说到DMZ区域不需旁路. 2.如果是ASA 5505的设备,则需定义vlan端口地址然后把防火墙相应端口加入对应vlan. : ASA Version 8.4(2)                                      //版本8.4 ! hostname fw enable password 8Ry2Y