求指教學習redis源碼的方法?
現在想學習redis的源碼,大家有沒有什麼好的方法呢?
我以前學開源項目的話,就是找出幾個可以獨立運行的文件來,單獨編譯,這樣分開學習,請問大家學redis有沒有類似的,或者其它的經驗呢?
找工作那會兒,看了黃建宏老師的《Redis設計與實現》,對redis的部分實現有了一個簡明的認識。在面試過程中,redis確實成為了面試官考核我的一個亮點,恰好以後的工作又與redis有著千絲萬縷的聯繫,於是就想趁著畢業前的這段時間把redis的源代碼研究一下,為以後的工作打個良好的基礎。
Redis簡介redis全稱REmote DIctionary Server,是一個由Salvatore Sanfilippo寫的高性能key-value存儲系統,其完全開源免費,遵守BSD協議。Redis與其他key-value緩存產品(如memcache)有以下幾個特點。
- Redis支持數據的持久化,可以將內存中的數據保存在磁碟中,重啟的時候可以再次載入進行使用。
- Redis不僅僅支持簡單的key-value類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。
- Redis支持數據的備份,即master-slave模式的數據備份。
Redis的性能極高且擁有豐富的數據類型,同時,Redis所有操作都是原子性的,也支持對幾個操作合併後原子性的執行。另外,Redis有豐富的擴展特性,它支持publish/subscribe, 通知,key 過期等等特性。
Redis更為優秀的地方在於,它的代碼風格極其精簡,整個源碼只有23000行,很有利於閱讀和賞析!還在等什麼呢?Start!
如何獲取Redis源碼?redis是完全開源的,其源代碼可以在直接在官網上獲取(目前最新版本是3.2.5)。執行以下指令:
cd ... // 這裡打開你存放redis的文件夾wget http://download.redis.io/releases/redis-3.2.5.tar.gztar zxvf redis-3.2.5.tar.gz
此時,進入解壓後的redis目錄下的src文件夾,redis的所有源代碼都存放在此。
[root@VM_123_20_centos redis-3.2.5]# cd src/[root@VM_123_20_centos src]# lsMakefile crc64.h mkreleasehdr.sh redis-cli.o sort.oMakefile.dep crc64.o multi.c redis-sentinel sparkline.cadlist.c db.c multi.o redis-server sparkline.hadlist.h db.o networking.c redis-trib.rb sparkline.oadlist.o debug.c networking.o redisassert.h syncio.cae.c debug.o notify.c release.c syncio.oae.h debugmacro.h notify.o release.h t_hash.cae.o dict.c object.c release.o t_hash.oae_epoll.c dict.h object.o replication.c t_list.cae_evport.c dict.o pqsort.c replication.o t_list.oae_kqueue.c endianconv.c pqsort.h rio.c t_set.cae_select.c endianconv.h pqsort.o rio.h t_set.oanet.c endianconv.o pubsub.c rio.o t_string.canet.h fmacros.h pubsub.o scripting.c t_string.oanet.o geo.c quicklist.c scripting.o t_zset.caof.c geo.h quicklist.h sds.c t_zset.oaof.o geo.o quicklist.o sds.h testhelp.hasciilogo.h help.h rand.c sds.o util.cbio.c hyperloglog.c rand.h sdsalloc.h util.hbio.h hyperloglog.o rand.o sentinel.c util.obio.o intset.c rdb.c sentinel.o valgrind.supbitops.c intset.h rdb.h server.c version.hbitops.o intset.o rdb.o server.h ziplist.cblocked.c latency.c redis-benchmark server.o ziplist.hblocked.o latency.h redis-benchmark.c setproctitle.c ziplist.ocluster.c latency.o redis-benchmark.o setproctitle.o zipmap.ccluster.h lzf.h redis-check-aof sha1.c zipmap.hcluster.o lzfP.h redis-check-aof.c sha1.h zipmap.oconfig.c lzf_c.c redis-check-aof.o sha1.o zmalloc.cconfig.h lzf_c.o redis-check-rdb slowlog.c zmalloc.hconfig.o lzf_d.c redis-check-rdb.c slowlog.h zmalloc.ocrc16.c lzf_d.o redis-check-rdb.o slowlog.ocrc16.o memtest.c redis-cli solarisfixes.hcrc64.c memtest.o redis-cli.c sort.c
源代碼結構解析
看了上面src目錄下的文件,簡直讓人眼花繚亂。這裡不得不批評以下redis的作者啊,都沒有整理一下源代碼,統統都放在一個文件夾下。
正所謂不打無準備的仗,拿到源碼之後,我們首先要對這些文件進行一個分類,來規劃一下我們的閱讀順序。這裡介紹一下在網上看到的源碼閱讀方法(摘自redis源碼解析)。
- 自底向上:從耦合關係最小的模塊開始讀,然後逐漸過度到關係緊密的模塊。就好像寫程序的測試一樣,先從單元測試開始,然後才到功能測試。
- 從功能入手:通過文件名(模塊名)和函數名,快速定位到一個功能的具體實現,然後追蹤整個實現的運作流程,從而了解該功能的實現方式。
- 自頂向下:從程序的 main() 函數,或者某個特別大的調用者函數為入口,以深度優先或者廣度優先的方式閱讀它的源碼。
另外,按照黃健宏老師《如何閱讀 Redis 源碼?》一文中介紹的redis閱讀方法,基本上可以將上述文件進行合理的拆分,以便於對其進行一一攻破。
按照上圖對Redis源碼的模塊劃分,初步確定一下源碼的學習路線如下:
第一階段- 閱讀Redis的數據結構部分,基本位於如下文件中:內存分配 zmalloc.c和zmalloc.h
- 動態字元串 sds.h和sds.c
- 雙端鏈表 adlist.c和adlist.h
- 字典 dict.h和dict.c
- 跳躍表 server.h文件裡面關於zskiplist結構和zskiplistNode結構,以及t_zset.c中所有zsl開頭的函數,比如 zslCreate、zslInsert、zslDeleteNode等等。
- 基數統計 hyperloglog.c 中的 hllhdr 結構, 以及所有以 hll 開頭的函數
第二階段 熟悉Redis的內存編碼結構
- 整數集合數據結構 intset.h和intset.c
- 壓縮列表數據結構 ziplist.h和ziplist.c
第三階段 熟悉Redis數據類型的實現
- 對象系統 object.c
- 字元串鍵 t_string.c
- 列表建 t_list.c
- 散列鍵 t_hash.c
- 集合鍵 t_set.c
- 有序集合鍵 t_zset.c中除 zsl 開頭的函數之外的所有函數
- HyperLogLog鍵 hyperloglog.c中所有以pf開頭的函數
第四階段 熟悉Redis資料庫的實現
- 資料庫實現 redis.h文件中的redisDb結構,以及db.c文件
- 通知功能 notify.c
- RDB持久化 rdb.c
- AOF持久化 aof.c
以及一些獨立功能模塊的實現
- 發布和訂閱 redis.h文件的pubsubPattern結構,以及pubsub.c文件
- 事務 redis.h文件的multiState結構以及multiCmd結構,multi.c文件
第五階段 熟悉客戶端和伺服器端的代碼實現
- 事件處理模塊 ae.c/ae_epoll.c/ae_evport.c/ae_kqueue.c/ae_select.c
- 網路鏈接庫 anet.c和networking.c
- 伺服器端 redis.c
- 客戶端 redis-cli.c
- 這個時候可以閱讀下面的獨立功能模塊的代碼實現
- lua腳本 scripting.c
- 慢查詢 slowlog.c
- 監視 monitor.c
第六階段 這一階段主要是熟悉Redis多機部分的代碼實現
- 複製功能 replication.c
- Redis Sentinel sentinel.c
- 集群 cluster.c
其他代碼文件介紹
關於測試方面的文件有:
- memtest.c 內存檢測
- redis_benchmark.c 用於redis性能測試的實現。
- redis_check_aof.c 用於更新日誌檢查的實現。
- redis_check_dump.c 用於本地資料庫檢查的實現。
- testhelp.c 一個C風格的小型測試框架。
一些工具類的文件如下:
- bitops.c GETBIT、SETBIT 等二進位位操作命令的實現
- debug.c 用於調試時使用
- endianconv.c 高低位轉換,不同系統,高低位順序不同
- help.h 輔助於命令的提示信息
- lzf_c.c 壓縮演算法系列
- lzf_d.c 壓縮演算法系列
- rand.c 用於產生隨機數
- release.c 用於發布時使用
- sha1.c sha加密演算法的實現
- util.c 通用工具方法
- crc64.c 循環冗餘校驗
- sort.c SORT命令的實現
- 一些封裝類的代碼實現:
- bio.c background I/O的意思,開啟後台線程用的
- latency.c 延遲類
- migrate.c 命令遷移類,包括命令的還原遷移等
- pqsort.c 排序演算法類
- rio.c redis定義的一個I/O類
- syncio.c 用於同步Socket和文件I/O操作
整個Redis的源碼分類大體上如上所述了,接下來就按照既定的幾個階段一一去分析Redis這款如此優秀的源代碼吧!
Ps: 又給自己制定了一個艱巨的計劃,希望自己能像之前一樣堅持下去,一點一點去剖析,相信最後會收穫很多!
最後,希望關注我的個人博客,和我一起來剖析Redis的源碼。
https://zcheng.ren可以看一下《Redis設計與實現》 《Redis設計與實現》(黃健宏)【摘要 書評 試讀】
給redis增加幾條命令,修改查找結構,比對查找效率。邊看邊擼助你快速高潮迭起!
redis的代碼確實不多,這篇快速查看一下Redis源代碼應該適合你
找個基礎版本看。先跟蹤一個簡單命令的流程。比如跟蹤ping的執行,然後set get等等。
讀第一個版本,代碼很少,半個小時就能看明白,結構馬上清楚了,後面版本改動雖大,基本結構卻是沒變,弄清楚了基本結構,再看後面的版本沒準更好。
1. 了解概要設計思路,從官網上看看資料即可,不用太細節,觀其大要。2. 找一個突破口,比如找個功能修改下,如incr這個操作,相關數據介面,設計本意,然後動手改改功能。3. 上手後在慢慢最終一個個功能,慢慢熟悉整體設計、模型等。
建議從以下幾個階段入手:1、了解核心數據結構。2、了解I/O模型。3、從一個簡單的命令跟蹤下去,看看整體的流程,此時不必在意細節。4、選自己感興趣的部分開始仔細品讀。
我也在讀。源碼不算很多(三萬多),而且redis是單線程方式運行,比較清晰,可以直接讀,一兩個禮拜就可以看個大概了。
同問啊。。。
推薦閱讀:
※集群環境中資料庫與緩存的三板斧
※aredis —— 一款高效的非同步 redis 客戶端
※No-SQL資料庫中的事務性設計
※200G的數據,主要是查詢操作,酷睿I5個人PC,應該選擇什麼資料庫來存儲?
TAG:Redis |