redis源碼筆記
摘要: hiredis是redis官方提供的c客戶端庫。在讀代碼的過程中,發現了一個bug,記錄一下。hiredis里定義了一個上下文結構(struct redisContext),代碼如下(deps/hiredis/hiredis.h):https://github.com/antirez/hiredis/blob/master/hiredis.h157 /* Context for a connection to Redis */158 typedef struct redisContext {159 int err; /* Error flags, 0 when there is no ... 閱讀全文摘要: serverCron是redis每隔100ms執行的一個循環事件,由ae事件框架驅動。其主要執行如下任務:1.記錄循環時間:server.unixtime = time(NULL)redis使用全局狀態cache了當前的時間值。在vm實現以及lru實現中,均需要對每一個對象的訪問記錄其時間,在這種情況下,對精度的要求并不高(100ms內的訪問值一樣是沒有問題的)。使用cache的時間值,其代價要遠遠低于每次均調用time()系統調用2.更新LRUClock值:updateLRUClock()后續在執行lru淘汰策略時,作為比較的基準值。redis默認的時間精度是10s(#defineREDIS 閱讀全文摘要: initServer是redis對server進行初始化的入口,其由main調用,位于initServerConfig、命令行參數解析、守護進程判定之后,是server最重要的入口點。盡管代碼看似簡單(102行代碼,且大量的賦值語句),但順藤摸瓜,有很多點值得仔細看看。接下來逐行分析:函數第一件事是對信號進行處理: 899 signal(SIGHUP, SIG_IGN); 900 signal(SIGPIPE, SIG_IGN); 901 setupSignalHandlers();redis多作為守護進程運行,這時其不會有控制終端,首先忽略掉SIGHUP信號。(見AP... 閱讀全文摘要: 純文本協議,請求-響應模式。看下邊鏈接:http://redis.io/topics/protocol《Unix編程藝術》中明確倡導使用純文本協議。作者在specification的開頭就指出,Redis的協議設計是如下三點的折中:Simple to implementFast to parse by a computerEasy enough to parse by a human一個如此重視性能的代碼實現選用了如此簡單易懂的協議設計,相信對仍舊執拗于使用二進制協議設計的開發者是個啟發。 閱讀全文摘要: redis可以被作為類似memcached的應用級緩存使用,在內存超過限制時,按照配置的策略,淘汰掉相應的kv,使得內存可以繼續留有足夠的空間保存新的數據。redis的conf文件中有對該機制的一份很好的解釋:194 # Don't use more memory than the specified amount of bytes.195 # When the memory limit is reached Redis will try to remove keys196 # accordingly to the eviction policy selected (see maxme 閱讀全文摘要: redis允許對key設置超時時間,實現過期key的自動淘汰。這篇blog分析下,其自適應(adaptive)的淘汰機制。redis每隔100ms定時執行的循環(serverCron function)里有如下語句: 655 /* Expire a few keys per cycle, only if this is a master. 656 * On slaves we wait for DEL operations synthesized by the master 657 * in order to guarantee a strict consisten... 閱讀全文摘要: aof是redis提供的一種數據持久化機制,通過將每一條命令dump下來,保持數據和內存中的數據一致。 1 #include "redis.h" 2 #include "bio.h" 3 4 #include <signal.h> 5 #include <fcntl.h> 6 #include <sys/stat.h> 7 #include <sys/types.h> 8 #include <sys/time.h> 9 #include <sys/resource.h> 10 #in 閱讀全文摘要: slowlog是redis提供的進行query分析的工具。它將執行時間長的命令統一以list形式保存在內存之中,使用者可以通過slowlog命令查看這些慢query,從而分析系統瓶頸。最好的分析筆記是作者的注釋,除此之外,會做簡要記錄。slowlog.h 1 /* This structure defines an entry inside the slow log list */ 2 typedef struct slowlogEntry { 3 robj **argv; //記錄query參數 4 int argc; 5 l... 閱讀全文摘要: 這份代碼是redis的client接口,其和server端的交互使用了deps目錄下的hiredis c庫,同時,在這部分代碼中,應用了linenoise庫完成類似history命令查詢、自動補全等終端控制功能。 1 #include "fmacros.h" //用于mac下的兼容性處理 2 #include "version.h" //版本信息頭文件,當前版本是2.4.10 3 4 #include <stdio.h> 5 #include <string.h> 6 #include <stdlib.h> 7 #in 閱讀全文摘要: 作者在bio.c的頭注釋中對設計進行了詳細的介紹/* Background I/O service for Redis. 這個文件是redis后臺IO服務的實現 * * This file implements operations that we need to perform in the background. * Currently there is only a single operation, that is a background close(2) * system call. This is needed as when the process is the last .. 閱讀全文摘要: 這部分代碼是具體事件觸發網絡庫的底層實現。Linux下有epoll設施,而且其效率是現在最高的。注意即使高效如redis,其也只是選擇了自動檔-水平觸發(自動檔和手動檔的典故請自行google)。據說libevent也是使用的水平觸發。廢話不多說,看代碼吧。 1 #include <sys/epoll.h> 2 3 typedef struct aeApiState { 4 int epfd; 5 struct epoll_event events[AE_SETSIZE]; //存的是epoll_wait返回后得到的事件列表 6 } aeApiState; //作為event... 閱讀全文摘要: ae.c是redis事件框架的具體實現,這篇blog對這份源碼進行簡單說明。其中談到了作者已經標記的一些未來可能做的改進。ae.c 1 #include <stdio.h> 2 #include <sys/time.h> 3 #include <sys/types.h> 4 #include <unistd.h> 5 #include <stdlib.h> 6 7 #include "ae.h" 8 #include "zmalloc.h" 9 #include "config.h&q 閱讀全文摘要: ae框架是redis作者開發的事件處理框架,其目的和libevent項目類似。redis本著最小依賴原則,自己實現了一套,而且速度更快。ae只有不到500行代碼,但據說libevent有3萬加的代碼,實現這一個功能所付出的代碼量已經超過了redis所有的代碼量。ae.h 1 #ifndef __AE_H__ 2 #define __AE_H__ 3 //同時支持的連接數,其實這個還是可以設的更大一些 4 #define AE_SETSIZE (1024*10) /* Max number of fd supported */ 5 6 #define AE_OK 0 7 #defi... 閱讀全文摘要: redis配置文件的頭文件,有一些和平臺有關的配置,在這里邊進行設置。config.h 1 #ifndef __CONFIG_H 2 #define __CONFIG_H 3 4 #ifdef __APPLE__ 5 #include <AvailabilityMacros.h> 6 #endif 7 8 /* Define redis_fstat to fstat or fstat64() */ 9 #if defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_6)10 #define redis_fstat fst 閱讀全文摘要: 對于目標機是大端字節序的機器,進行字節碼的轉換,提供了16byte、32byte、64byte字節的轉換。在intset\ziplist\zipmap三種數據結構中使用,使得不同字節序機器生成的rdb文件格式都是統一的(小端字節序),便于兼容。代碼實在是太簡單了,貼上來,不多說了。endian.h 1 #ifndef __ENDIAN_H 2 #define __ENDIAN_H 3 4 void memrev16(void *p); 5 void memrev32(void *p); 6 void memrev64(void *p); 7 8 /* variants of the fun.. 閱讀全文摘要: anet庫是redis對tcp網絡層以及unix域實現的一個封裝。redis的客戶端和server端通信使用的均為TCP協議。Basic TCP socket stuff made a bit less boringanet.h 1 #ifndef ANET_H 2 #define ANET_H 3 4 #define ANET_OK 0 5 #define ANET_ERR -1 6 #define ANET_ERR_LEN 256 7 8 #if defined(__sun) 9 #define AF_LOCAL AF_UNIX10 #endif11 12 i... 閱讀全文摘要: 這篇blog介紹dict的實現。dict.c 1 #include "fmacros.h" 2 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <string.h> 6 #include <stdarg.h> 7 #include <assert.h> 8 #include <limits.h> 9 #include <sys/time.h> 10 #include <ctype.h> 11 12 #include &q 閱讀全文摘要: 這篇介紹redis最后一個基礎數據結構——hash表。可以毫不夸張的說,hash表是redis一切存儲的基礎,也是redis得以快如飛的基礎。注:其實還有個intset,不過intset是在持久化dump到硬盤時為節省空間設計的,和我們這里談的不一樣。dict的設計呢,簡單的說是一個雙表,“一主一從”,不定時rehash,建議大家在讀代碼前能夠對這個設計有所了解。Anyway,隨便搜一搜,很多文章的。dict.h 1 #ifndef __DICT_H 2 #define __DICT_H 3 4 #define DICT_OK 0 5 #define DICT_ERR 1 6 ... 閱讀全文摘要: testhelp.h是作者為redis量身定做的單元測試框架,對于redis這種規模的項目,就沒有必要上GTEST這種大殺器了,作者18行代碼搞定。不過很遺憾,在2.4.10這個版本的版本的redis中,只有sds用了這個測試框架,不知其他代碼作者是如何做測試的。我慢慢摸索,摸索到了告訴大家。 1 #ifndef __TESTHELP_H 2 #define __TESTHELP_H 3 4 int __failed_tests = 0; //失敗的測試用例數 5 int __test_num = 0; //總的測試用例數 6 #defin... 閱讀全文摘要: sds和adlist一樣,是redis的基礎數據結構之一,是其為自身實現的字符串類型。A C dynamic strings librarysds.h 1 #ifndef __SDS_H 2 #define __SDS_H 3 4 #define SDS_MAX_PREALLOC (1024*1024) //字符串最大的預分配長度是1M 5 6 #include <sys/types.h> 7 #include <stdarg.h> 8 9 typedef char *sds; //sds本身被typedef為char*,是后續絕大部分函數的參數(之一)10... 閱讀全文摘要: adlist是redis自己是實現的一個通用的雙向鏈表。------------------------------------------------adlist.h---------------------------------------------------#ifndef __ADLIST_H__#define __ADLIST_H__/* Node, List, and Iterator are the only data structures used currently. */typedef struct listNode {struct listNode *prev;str 閱讀全文摘要: redis.conf是redis-server的配置文件# Redis configuration file example# Note on units: when memory size is needed, it is possible to specifiy# it in the usual form of 1k 5GB 4M and so forth:## 1k => 1000 bytes# 1kb => 1024 bytes# 1m => 1000000 bytes# 1mb => 1024*1024 bytes# 1g => 1000000000 b 閱讀全文摘要: 每天抽出時間來讀一讀代碼,只是作為學習的目的,盡量寫的系統些。redis的版本選的2.4.10。形式以源碼剖析的方式寫,類似于結合代碼寫注釋。 閱讀全文
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
