慢查询日志
配置慢查询日志
选项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或1GETBIT <key> postion
:得到位数组key对应位postion的值BITCOUNT <key>
:得到位数组key有多少位1BITOP 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
表示会被打开。当执行事务的时候,如果检测发现该标识被打开,则不执行事务