redis源码分析
主流程
server.c
全局變量server,只有一個,記錄本服務的信息。
1.spt_init初始化全局環境變量,關聯變量environ
2.設置時區
3.初始化oom_handler
4.其他初始化:隨機數種子,crc64,acl,服務配置,tls,哨兵模式,幫助,加載配置文件,moduleInitModulesSystem模塊系統初始化
5.關鍵函數initServer,初始化核心。
6.創建pid文件
7.設置cpu親和性
8.執行事件循環核心
9.異常情況退出釋放結束。
initServer
1.初始化處理信號的handlers
2.設置線程可以被kill
3.全局變量server初始化默認屬性
4.創初始化共享對象shared
5.adjustOpenFilesLimit,根據配置判斷文件描述符的數量限制
6.aeCreateEventLoop創建epoll循環對象
7.監聽端口,設置非阻塞
8.aeCreateTimeEvent定時器初始化
9.設置accpet回調
10.aeCreateFileEvent使用管道初始化喚醒event loop的線程通信
11.設置sleep前后的回調函數
12.初始化集群clusterInit,副本集replicationScriptCacheInit,lua腳本scriptingInit,慢查詢
slowlogInit,延遲監控latencyMonitorInit,acl默認密碼ACLUpdateDefaultUserPassword。
redisSetCpuAffinity設置cpu親和性
linux調用setcpuaffinity->sched_setaffinity,glibc的接口,最終調用系統調用INTERNAL_SYSCALL。
aeMain
aeApiPoll執行事件循環,linux一般使用epoll,epoll_wait阻塞。定時器事件processTimeEvents在最后處理。
reactor模型
ae_epoll
linux使用ae_epoll封裝epoll。
ae.h聲明了通用的事件函數,基本都是epoll的封裝。
anet.h聲明了tcp連接的操作函數。
connection
connection.h封裝了連接的通用接口,最終會調用anet的tcp函數。
ConnectionType以函數指針的形式封裝了接口,可以切換綁定的函數。
networking
networking.c主要是和客戶端相關的連接操作。
rio
rio是文件相關操作的抽象封裝。
syncio
同步讀寫操作接口。
集群
cluster
集群相關操作
replication
副本集相關操作
基礎工具
crc64
crc64_init初始化,crc64計算校驗值
pgsort,sort
排序算法,_pqsort高速排序算法。
sha1,sha256
哈希算法
壓縮算法
lz算法
調試優化
debug
debug.c:重點關注logStackTrace和dumpCodeAroundEIP
logStackTrace:可通過信號,觸發logStackTrace,核心原理是調用glibc的backtrace獲取當前棧信息,backtrace_symbols_fd解析棧信息(查找符號表)到文件。
glibc通過elf庫的_dl_addr獲取詳細信息解析。
dumpCodeAroundEIP:直接根據eip指針獲得下一條指令的地址,然后通過dladdr能夠得到dump信息。
memtest
內存測試
tracking
核心存儲結構:使用基數樹存儲的TrackingTable和PrefixTable
客戶端指令解析后,調用call的地方執行trackingRememberKeys,記錄到TrackingTable
每個epoll循環的beforeSleep都會執行trackingBroadcastInvalidationMessages,發送tracking跟蹤信息到客戶端。
核心數據結構
redisServer
服務的全局信息,struct redisServer server;
包括pid,主線程id,配置文件路徑,執行路徑,參數,和其他客戶端,連接,線程,備份,慢查詢日志,oom_score,集群,scripts等等的配置和信息。
redisOp
定義了redis的操作,是解析客戶端消息后的比較原始的結構數據
redisCommand
redisCommandTable數組:表驅動執行函數和命令信息。
redisDb
redis的db是字典查詢的基本單位,需要指定db然后根據key查詢字典找到對應的數據。
redisObject/robj
通用的redis數據結構封裝,包含引用計數,獲取和釋放需要使用指定的函數。
incrRefCount/decrRefCount,引用計數為零,執行free
字典
所有redis數據類型的的存儲都靠字典
rax基數樹
* This is the vanilla representation:** (f) ""* \* (o) "f"* \* (o) "fo"* \* [t b] "foo"* / \* "foot" (e) (a) "foob"* / \* "foote" (r) (r) "fooba"* / \* "footer" [] [] "foobar"*基數樹層級固定了之后,最大時間復雜度就確定了,查詢粒度小,速度快。
數據結構編碼
編碼屬于redisObject的一個字段,占4位。
編碼類型:
持久化的時候需要用到。類型比較判斷也需要用到。
其他功能
notify
rdb,aof,sentinel
redismodule
scripting
slowlog
布隆過濾器模塊插件
總結
- 上一篇: 云速建站:10分钟出特效系列(二)
- 下一篇: 程序员生活_程序员租房需要注意什么