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();
尝试每隔一段时间处理被阻止的客户端。
posted @   拿什么救赎  阅读(340)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
点击右上角即可分享
微信分享提示