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