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(); 尝试每隔一段时间处理被阻止的客户端。