Redis源码分析之启动流程

@startuml
group main
  server.c -> setproctitle.c : spt_init():为函数setproctitle调用做初始化工作
  server.c -> server.c : setlocale(LC_COLLATE,""); 设置本地化
  server.c -> server.c : tzset(); 
  server.c -> server.c : zmalloc_set_oom_handler(redisOutOfMemoryHandler);
  server.c -> server.c : srand(time(NULL)^getpid());
  server.c -> server.c : gettimeofday(&tv,NULL);
  server.c -> dict.c : dictSetHashFunctionSeed((uint8_t*)hashseed); 设置hash函数随机种子
  server.c -> server.c : checkForSentinelMode() 检查哨兵模式
  server.c -> server.c : initServerConfig() 初始化server配置
  server.c -> module.c : moduleInitModulesSystem() 初始化module系统
  server.c -> server.c : 保存argc和argv
  group #LightYellow 如果是哨兵模式
    server.c -> sentinel.c : initSentinelConfig() 初始化哨兵配置
    server.c -> sentinel.c : initSentinel() 初始化哨兵
  end
  server.c -> redis_check_rdb.c : redis_check_rdb_main() 如果是通过redis-check-rdb启动,执行rdb检查
  redis_check_rdb.c -> END : 结束
  server.c -> redis_check_aof.c : redis_check_aof_main() 如果是通过redis-check-aof启动,执行aof检查,然后返回
  redis_check_aof.c -> END : 结束
  server.c -> config.c : loadServerConfig() 根据配置文件和命令行参数设置server
  server.c -> server.c : 打印启动信息
  server.c -> server.c : 根据配置决定是否后台进程启动
  server.c -> server.c : initServer() 初始化服务器
  group #Yellow initServer
    server.c -> server.c : setupSignalHandlers() 设置信号处理函数
    server.c -> server.c : 根据配置决定是否开启系统日志
    server.c -> server.c : 初始化server对象用到的的结构体:list、rax等
    server.c -> server.c : createSharedObjects() 创建共享对象
    server.c -> server.c : adjustOpenFilesLimit() 适配打开文件数限制
    server.c -> ae.c : aeCreateEventLoop() 创建事件循环对象el
    server.c -> server.c : listenToPort() 开启本地端口监听
    group #LightBlue listenToPort
      server.c -> anet.c : anetTcpServer() 
        group #LightPink anetTcpServer
          anet.c -> system : socket() 创建服务端socket
          anet.c -> anet.c : anetSetReuseAddr() 设置地址重用
          anet.c -> system : bind() 绑定本地地址
          anet.c -> system : listen() 开始监听端口
        end
      server.c -> anet.c : anetNonBlock() 设置非阻塞监听
    end
    server.c -> server.c : 初始化默认的16个数据库对象
    server.c -> evict.c : evictionPoolAlloc() 初始化内存淘汰池
    server.c -> server.c : 初始化server的其他字段
    server.c -> ae.c : aeCreateTimeEvent() 创建时间处理事件,处理函数为serverCron
    server.c -> networking.c : aeCreateFileEvent() 绑定socket到el,监听读事件,处理函数为acceptTcpHandler
    server.c -> networking.c : aeCreateFileEvent() 绑定module的管道到el,监听读事件,处理函数为moduleBlockedClientPipeReadable
    server.c -> server.c : 如果开启了AOF,则打开AOF文件
    server.c -> server.c : 32位系统没有设置内存限制,默认设置为3G,缓存不淘汰
    server.c -> cluster.c : clusterInit() 开启了集群能力,则进行集群初始化工作
    server.c -> replication.c : replicationScriptCacheInit() 备份脚本缓存初始化
    server.c -> script.c : scriptingInit() 脚本初始化
    server.c -> slowlog.c : slowlogInit() 慢日志初始化
    server.c -> latency.c : latencyMonitorInit() 延迟监控初始化
  end
  server.c -> server.c : 有必要则创建pid文件
  server.c -> setproctitle.c : redisSetProcTitle() 设置进程名称
  server.c -> server.c : redisAsciiArt() 打印logo
  server.c -> server.c : checkTcpBacklogSettings() 检查系统tcp backlog,小于当前设置则打印警告
  alt#Gold #LightYellow 非哨兵模式
    server.c -> server.c : 执行系统相关检查
    server.c -> module.c : moduleLoadFromQueue() 模块加载
    server.c -> server.c : InitServerLast() 初始化后置操作
    group #LightBlue InitServerLast
      server.c -> bio.c : bioInit() 初始化后台线程
      server.c -> server.c : server.initial_memory_usage参数
    end
    server.c -> server.c : loadDataFromDisk() 从磁盘加载数据
    group #LightGreen loadDataFromDisk 优先加载aof,没有则加载rdb
      server.c -> aof.c : loadAppendOnlyFile() 加载aof文件
      server.c -> rdb.c : rdbLoad() 加载rdb文件
    end
    server.c -> cluster.c : verifyClusterConfigWithData() 如果开启了集群模式,进行集群配置验证 
  else #Yellow 哨兵模式
    group #LightBlue InitServerLast
      server.c -> bio.c : bioInit() 初始化后台线程
      server.c -> server.c : server.initial_memory_usage参数
    end
    server.c -> sentinel.c : sentinelIsRunning() 
  end
  server.c -> ae.c : aeSetBeforeSleepProc() 设置休眠前处理函数beforeSleep
  server.c -> ae.c : aeSetAfterSleepProc() 设置休眠后处理函数afterSleep
  server.c -> ae.c : aeMain() 开始事件循环,正常启动后会一直循环
  server.c -> ae.c : aeDeleteEventLoop() 删除事件循环,释放事件循环资源
end
@enduml
  • servercron 函数
@startuml
  server.c -> server.c : servercron() 
  group #LightYellow servercron
    server.c -> debug.c : watchdogScheduleSignal() 设置了watchdog_period参数,调度SIGALRM信号
    server.c -> server.c : updateCachedTime() 更新缓存的时间
    server.c -> server.c : 设置自动更新或者手动设置的频率hz
    group #yellow 每100ms执行一次
      server.c -> server.c : trackInstantaneousMetric() 更新服务器采样STATS_METRIC_COMMAND
      server.c -> server.c : trackInstantaneousMetric() 更新服务器采样STATS_METRIC_NET_INPUT
      server.c -> server.c : trackInstantaneousMetric() 更新服务器采样STATS_METRIC_NET_OUTPUT
    end
    server.c -> server.c : 更新LRU时钟
    server.c -> server.c : 更新服务器内存使用峰值
    group #yellow 每100ms执行一次
      server.c -> server.c : 更新内存使用统计cron_malloc_stats
    end   
    server.c -> server.c : 响应停机信号 
    group #yellow 每5s执行一次
      server.c -> server.c : 打印VERBOSE级别的DB统计信息
    end
    group #yellow 非哨兵模式下,每5s执行一次
      server.c -> server.c : 打印VERBOSE级别的客户端信息
    end
    server.c -> server.c : clientsCron()
    group #yellow clientsCron
      loop 遍历总数/hz个客户端
        server.c -> server.c : 把链表尾部的客户端移动到链表开头
        server.c -> server.c : clientsCronHandleTimeout() 处理客户端超时
        server.c -> server.c : clientsCronResizeQueryBuffer() 整理客户端的queryBuffer
        server.c -> server.c : clientsCronTrackExpansiveClients() 统计大流量客户端Top8
      end
    end
    server.c -> server.c : databasesCron()
    group #yellow databasesCron
      alt #Pink master
        server.c -> expire.c : activeExpireCycle()
      else #LightBlue slave
        server.c -> expire.c : expireSlaveKeys()
      end
      server.c -> defrag.c : activeDefragCycle() 开启了内存碎片整理,则执行
      server.c -> server.c : 没有RDB和AOF子进程,对DB进行扩容,执行1ms的增量rehash
    end
    server.c -> aof.c : rewriteAppendOnlyFileBackground() 没有RDB和AOF子进程,设置了AOF重写,则执行
    alt #Pink 有RDB或AOF子进程或ldbPendingChildren()
      server.c -> server.c : 等待子进程执行,执行对应收尾
    else #LightBlue
      server.c -> rdb.c : rdbSaveBackground() 根据save配置决定执行RDB保存
      server.c -> aof.c : rewriteAppendOnlyFileBackground() 根据条件决定执行AOF重写
    end
      server.c -> aof.c : flushAppendOnlyFile() 根据aof_flush_postponed_start决定是否刷新AOF文件
    group #yellow 每1s执行一次
      server.c -> aof.c : flushAppendOnlyFile() 如果aof_last_write_status为err
    end
    server.c -> networking.c : freeClientsInAsyncFreeQueue() 异步释放客户端
    server.c -> networking.c : clientsArePaused()
    group #yellow 每1s执行一次
      server.c -> replication.c : replicationCron() 执行备份调度函数
    end 
    group #yellow 每1s执行一次
      server.c -> cluster.c : clusterCron() 执行集群调度函数
    end
    server.c -> sentinel.c : sentinelTimer 如果是哨兵模式,执行哨兵调度函数
    group #yellow 每1s执行一次
      server.c -> cluster.c : migrateCloseTimedoutSockets() 
    end
    server.c -> server.c : 执行被延迟的bgsave,如有
  end
@enduml
  • acceptTcpHandler 函数
@startuml
networking.c -> networking.c : acceptTcpHandler 服务端socket处理函数
loop #LightYellow 1000
  networking.c -> anet.c : anetTcpAccept() 获取Tcp连接 
  anet.c -> system : accept() 
  networking.c <- anet.c : anetTcpAccept() 返回客户端fd
  networking.c -> networking.c : acceptCommonHandler() 处理客户端fd
  group #Yellow acceptCommonHandler
    networking.c -> networking.c : createClient() 创建客户端对象
    group #Red createClient
      networking.c -> anet.c : anetNonBlock() 设置非阻塞
      networking.c -> anet.c : anetEnableTcpNoDelay() 设置无延迟
      networking.c -> anet.c : anetKeepAlive() 根据配置设置keepalive
      networking.c -> ae.c : aeCreateFileEvent() 注册到事件循环el上,处理函数为readQueryFromClient
      networking.c -> db.c : selectDb() 选中0号DB
      networking.c -> networking.c : 初始化客户端数据
      networking.c -> networking.c : linkClient()把客户端放进客户端链表
      networking.c -> multi.c : initClientMultiState() 初始化客户端事务数据
    end
    networking.c -> networking.c : 如果客户端连接数超限制,返回错误并关闭
    networking.c -> networking.c : 如果客户端不满足安全要求,返回错误并关闭
  end
end
@enduml
posted @ 2023-09-24 17:46  java拌饭  阅读(51)  评论(0编辑  收藏  举报