Redis源碼剖析--源碼結構解析


Redis:

架構:單機,主從,集群

應用:

          1—緩存、持久化

         2—訂閱、發布(消息隊列、消息通知)

         3—分布式鎖

         4—分布式Session共享     

 

@ https://zcheng.ren/posts/page/2/

 

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.gz tar 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]# ls Makefile crc64.h mkreleasehdr.sh redis-cli.o sort.o Makefile.dep crc64.o multi.c redis-sentinel sparkline.c adlist.c db.c multi.o redis-server sparkline.h adlist.h db.o networking.c redis-trib.rb sparkline.o adlist.o debug.c networking.o redisassert.h syncio.c ae.c debug.o notify.c release.c syncio.o ae.h debugmacro.h notify.o release.h t_hash.c ae.o dict.c object.c release.o t_hash.o ae_epoll.c dict.h object.o replication.c t_list.c ae_evport.c dict.o pqsort.c replication.o t_list.o ae_kqueue.c endianconv.c pqsort.h rio.c t_set.c ae_select.c endianconv.h pqsort.o rio.h t_set.o anet.c endianconv.o pubsub.c rio.o t_string.c anet.h fmacros.h pubsub.o scripting.c t_string.o anet.o geo.c quicklist.c scripting.o t_zset.c aof.c geo.h quicklist.h sds.c t_zset.o aof.o geo.o quicklist.o sds.h testhelp.h asciilogo.h help.h rand.c sds.o util.c bio.c hyperloglog.c rand.h sdsalloc.h util.h bio.h hyperloglog.o rand.o sentinel.c util.o bio.o intset.c rdb.c sentinel.o valgrind.sup bitops.c intset.h rdb.h server.c version.h bitops.o intset.o rdb.o server.h ziplist.c blocked.c latency.c redis-benchmark server.o ziplist.h blocked.o latency.h redis-benchmark.c setproctitle.c ziplist.o cluster.c latency.o redis-benchmark.o setproctitle.o zipmap.c cluster.h lzf.h redis-check-aof sha1.c zipmap.h cluster.o lzfP.h redis-check-aof.c sha1.h zipmap.o config.c lzf_c.c redis-check-aof.o sha1.o zmalloc.c config.h lzf_c.o redis-check-rdb slowlog.c zmalloc.h config.o lzf_d.c redis-check-rdb.c slowlog.h zmalloc.o crc16.c lzf_d.o redis-check-rdb.o slowlog.o crc16.o memtest.c redis-cli solarisfixes.h crc64.c memtest.o redis-cli.c sort.c

源代碼結構解析

看了上面src目錄下的文件,簡直讓人眼花繚亂。這里不得不批評以下redis的作者啊,都沒有整理一下源代碼,統統都放在一個文件夾下。

正所謂不打無准備的仗,拿到源碼之后,我們首先要對這些文件進行一個分類,來規划一下我們的閱讀順序。這里介紹一下在網上看到的源碼閱讀方法(摘自redis源碼解析)。

  • 自底向上:從耦合關系最小的模塊開始讀,然后逐漸過度到關系緊密的模塊。就好像寫程序的測試一樣,先從單元測試開始,然后才到功能測試。
  • 從功能入手:通過文件名(模塊名)和函數名,快速定位到一個功能的具體實現,然后追蹤整個實現的運作流程,從而了解該功能的實現方式。
  • 自頂向下:從程序的 main() 函數,或者某個特別大的調用者函數為入口,以深度優先或者廣度優先的方式閱讀它的源碼。

另外,按照黃健宏老師《如何閱讀 Redis 源碼?》一文中介紹的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操作


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM