PART1:Redis如何做内存优化
- Redis的慢查询日志功能用于记录执行时间超过给定时长的命令请求,用户可以通过这个功能产生的日志来监视和优化查询速度。
- 服务器配置有两个和慢查询日志相关的选项:
- slowlog-log-slower-than选项指定执行时间超过多少微秒(1秒等于1 000 000微秒)的命令请求会被记录到日志上。
- slowlog-max-len选项指定服务器最多保存多少条慢查询日志
- 服务器使用先进先出的方式保存多条慢查询日志,当服务器存储的慢查询日志数量等于slowlog-max-len选项的值时,服务器在添加一条新的慢查询日志之前,会先将最旧的一条慢查询日志删除。
- 慢查询记录的保存:服务器状态中包含了几个和慢查询日志功能有关的属性:
- Redis服务器将所有的慢查询日志保存在服务器状态的slowlog链表中,每个链表节点都包含一个slowlogEntry结构,每个slowlogEntry结构代表一条慢查询日志。
struct redisServer { ... //下一条慢查询日志的ID 。slowlog_entry_id属性的初始值为0,每当创建一条新的慢查询日志 时,这个属性的值就会用作新日志的id值,之后程序会对这个属性的值增一。 long long slowlog_entry_id; //保存了所有慢查询日志的链表 。slowlog链表保存了服务器中的所有慢查询日志,链表中的每个节点 都保存了一个slowlogEntry结构,每个slowlogEntry结构代表一条慢查询 日志: list *slowlog; //服务器配置slowlog-log-slower-than 选项的值 long long slowlog_log_slower_than; // 服务器配置slowlog-max-len选项的值 unsigned long slowlog_max_len; ... }; typedef struct slowlogEntry { //唯一标识符 long long id; //命令执行时的时间,格式为UNIX 时间戳 time_t time; //执行命令消耗的时间,以微秒为单位 long long duration; //命令与命令参数 robj **argv; //命令与命令参数的数量 int argc; } slowlogEntry;
- 慢查询日志的阅览和删除(打印和删除慢查询日志可以通过遍历slowlog链表来完成,slowlog链表的长度就是服务器所保存慢查询日志的数量。):在每次执行命令的之前和之后,程序都会记录微秒格式的当前 UNIX时间戳,这两个时间戳之间的差就是服务器执行命令所耗费的时长,服务器会将这个时长作为参数之一传给slowlogPushEntryIfNeeded函数,而slowlogPushEntryIfNeeded函数则负责检查是否需要为这次执行的命令创建慢查询日志
- slowlogPushEntryIfNeeded函数的作用有两个:
- 1)检查命令的执行时长是否超过slowlog-log-slower-than选项所设置的时间,如果是的话,就为命令创建一个新的日志,并将新日志添加到slowlog链表的表头。
- 2)检查慢查询日志的长度是否超过slowlog-max-len选项所设置的长度,如果是的话,那么将多出来的日志从slowlog链表中删除掉。
- 新的慢查询日志会被添加到slowlog链表的表头,如果日志的数量超过slowlog-max-len选项的值,那么多出来的日志会被删除。
- slowlogPushEntryIfNeeded函数的作用有两个:
- 服务器配置有两个和慢查询日志相关的选项:
PART2:Redis实现乐观锁(监控):watch
- 悲观锁:认为什么时候都有可能出问题,无论做什么都会加锁
- 乐观锁:认为什么时候都不会出问题,所以不用加锁。更新数据的时候去判断一下看看在此期间是否有人修改过数据
- JUC中的自旋锁就可以实现这种功能
- 监视器:通过执行MONITOR命令,客户端可以将自己变为一个监视器(发送MONITOR命令可以让一个普通客户端变为一个监视器,这个客户端的REDIS_MONITOR标志会被打开,并且这个客户端本身会 被添加到monitors链表的表尾。),实时地接收并打印出服务器当前处理的命令请求的相关信息:每当一个客户端向服务器发送一条命令请求时,服务器除了会处理这条命令请求之外,还会将关于这条命令请求的信息发送给所有监视器
- 向监视器发送命令信息: 服务器在每次处理命令请求之前,都会调用replicationFeedMonitors 函数,由这个函数将被处理的命令请求的相关信息发送给各个监视器。
- 当一个客户端从普通客户端变为监视器时,该客户端的REDIS_MONITOR标识会被打开
- 服务器将所有监视器都记录在monitors链表中。
- 每次处理命令请求时,服务器都会遍历monitors链表,将相关信息发送给监视器。
巨人的肩膀:
Redis设计与实现
redis中文官方文档



