redis 慢查询、位数组和事务

慢查询日志

配置慢查询日志

选项slowlog-log-slower-than用于配置执行时间大于多少毫秒的命令会记录慢查询日志
选项slowlog-max-len用于配置服务器最多保存多少条慢查询日志

慢查询日志查看

  • 通过命令SLOWLOG GET可以产看当前服务器的慢查询日志
  • 通过命令SLOwLOG RESET 可以删除慢查询日志
  • 通过命令SLOWLOG LEN可以查看慢查询日志的数目

慢查询日志实现

  • redisServer结构体内保存了一个slowlog的列表,元素是slowlogEntry。slowlogEntry结构体内包含命令的执行时间,命令本身以及命令的参数。
  • 每次执行命令,都会计算命令开始执行时间和结束时间,通过它判断出命令时间是否大于慢查询日志事件下限,如果符合要求,一个slowlogEntry就会被构造出来,使用头插法,插入日志链表中。此外,如果日志链表长度超过配置的最大慢查询日志长度,插入新的日志之后还会删除链表尾的旧日志

monitor

monitor用于客户端监视指定服务器上执行的命令,当执行MONITOR命令后,客户端转换为监视器,服务器上对应客户端的REDIS_MONITOR标识会被打开,并且服务器结构体的链表monitors会将客户端加入进去,待有命令执行的时候遍历monitors链表,把执行的命令发送给每一个监视服务器的客户端。

需要注意的是,监视器很拖累redis的性能,所以不能常开,只可当作短期调试使用。

位数组

命令

  • SETBIT <key> postion 0|1:将位数组key对应位postion设置为0或1
  • GETBIT <key> postion:得到位数组key对应位postion的值
  • BITCOUNT <key> :得到位数组key有多少位1
  • BITOP AND|OR|XOR <target_key> <key1> <key2> [...keyn]:对指定若干个key对应位数组进行与、或、异或操作,并存储在目标key中
  • BITOP NOT <target_key> <key>:对指定key取反,并存储

实现

位数组是存在sds内来实现的,sds内有若干个字符数组,使用它们来实现位数组的各个操作。
扩容起始是对sds扩容。

BITCOUNT的实现

  • 计算一个数二进制位有多少位为1的问题(计算汉明重量),有遍历,查表和variable-precision SWAR算法。
  • BITCOUNT使用了查表和variable-precision SWAR算法两种方法:查表法存储了8位长度键的表,使用数组记录00000000~11111111各数据值(下标表示)和对应1的个数(下标元素的值表示);对于位数组长度大于等于128的使用variable-precision SWAR算法

事务

事务的执行流程

  • MULTI命令开始,表明接下来的是需要打包执行的事务命令
  • 若干个事务的命令
  • EXEC命令结束,表明事务的命令输入结束,提交事务

实现

  • MULTI命令:这会打开客户端的REDIS_MULTI标识
  • MULTI后其他命令:如果不是EXEC、DISCARD、WATCH、MULTI这四个命令,则命令不会立刻执行,而是放入客户端的事务队列中,返回客户端QUEUED
  • EXEC:提交事务,服务器会遍历客户端的事务队列,顺序执行其中的命令,最后将所有结果返回给客户端,最后把客户端的事务标识去掉

watch命令

  • watch命令是一个乐观锁,它可以在exec命令执行之前,监视任意数量的数据库键,并在exec执行的时候,检查键是否有修改,如果有的话,则不执行事务
  • 实现:redisDb内会保存一个字典watched_keys,键是被监视的数据库键,值是客户端的链表,当调用修改数据的函数的时候,如果数据库键被watch监视,则watched_keys内对应的客户端链表的客户端的REDIS_DIRTY_CAS表示会被打开。当执行事务的时候,如果检测发现该标识被打开,则不执行事务

猜你喜欢

转载自blog.csdn.net/lqadam/article/details/79429659