redis源码阅读5----beforesleep
本篇文章,想主要研究下beforesleep和aftersleep两个阶段redis究竟干了什么。
aftersleep只是处理module,可以忽略。
主要研究beforesleep。
1.刷新zmalloc_used变量和server.stat_peak_memory变量。很简单,就是当前的used_memory。
2.
if (ProcessingEventsWhileBlocked) { uint64_t processed = 0; processed += handleClientsWithPendingReadsUsingThreads(); processed += tlsProcessPendingData(); processed += handleClientsWithPendingWrites(); processed += freeClientsInAsyncFreeQueue(); server.events_processed_while_blocked += processed; return; } 这一大段就是判断需要处理的processed有多少。进行累加。 3. handleBlockedClientsTimeout(); 处理tomeout和blocked的客户端。 4. handleClientsWithPendingReadsUsingThreads(); 处理读任务的队列。 主线程会遍历读任务的队列,即:server.clients_pending_read。如果开启了多线程,那么这一步就会给不同的线程进行处理。最后会落到readQueryFromClient上。 5. tlsProcessPendingData(); 处理tls的数据。 6. aeSetDontWait(server.el, tlsHasPendingData()); 这也是处理tls的。我们省略。 7. if (server.cluster_enabled) clusterBeforeSleep(); 如果开启了集群模式。调用clusterBeforeSleep()。我们没有开启,跳过。 8. if (server.active_expire_enabled && server.masterhost == NULL) activeExpireCycle(ACTIVE_EXPIRE_CYCLE_FAST); 处理过期key。 这个判断应该是基本上都会进入的。只要你是master,并且active_expire_enabled为1.条件很好满足。 然后根据你配置的过期参数进行淘汰。默认1,最大10. 核心函数是activeExpireCycleTryExpire(). 如果没有需要淘汰的key。整个函数稍微计算几个变量就很快return了。 9. if (listLength(server.clients_waiting_acks)) processClientsWaitingReplicas(); 解除阻塞。如果这个客户端在等待synchronous replication。 10. if (moduleCount()) moduleHandleBlockedClients(); 检查有没有因为module而阻塞的client。 11. if (listLength(server.unblocked_clients)) processUnblockedClients(); 让刚刚解除阻塞的client挂起。 12. if (server.get_ack_from_slaves && !checkClientPauseTimeoutAndReturnIfPaused()) { robj *argv[3];argv[0] = shared.replconf; argv[1] = shared.getack; argv[2] = shared.special_asterick; /* Not used argument. */ replicationFeedSlaves(server.slaves, server.slaveseldb, argv, 3); server.get_ack_from_slaves = 0; } 如果上个事件循环有一个client被阻塞,那么向所有slave发送ack。 13. updateFailoverStatus(); 这是进行failover切换。 14. trackingBroadcastInvalidationMessages(); 用广播方式向参与客户端缓存协议的客户端发送失效消息。 15. if (server.aof_state == AOF_ON) flushAppendOnlyFile(0); 开启了aof则进行aof。 16. handleClientsWithPendingWritesUsingThreads(); 处理写事件。 17. freeClientsInAsyncFreeQueue(); 处理需要关闭的客户端。 18. handleClientsBlockedOnKeys(); 尝试每隔一段时间处理被阻止的客户端。