Redis源碼分析(一)redis.c //redis-server.c

Redis源碼分析(一)redis.c //redis-server.c

入口函數 int main()

  4450 int main(int argc, char **argv) {4451     initServerConfig();4452     if (argc == 2) {4453         ResetServerSaveParams();4454         loadServerConfig(argv[1]);4455     } else if (argc > 2) {4456         fprintf(stderr,"Usage: ./redis-server [/path/to/redis.conf]\n");4457         exit(1);4458     } else {4459         redisLog(REDIS_WARNING,"Warning: no config file specified, using the default config. In order to specify a config file use 'redis-server /path/to/redis.conf'");4460     }4461     initServer();4462     if (server.daemonize) daemonize();4463     redisLog(REDIS_NOTICE,"Server started, Redis version " REDIS_VERSION);4464 #ifdef __linux__4465     linuxOvercommitMemoryWarning();4466 #endif4467     if (rdbLoad(server.dbfilename) == REDIS_OK)4468         redisLog(REDIS_NOTICE,"DB loaded from disk");4469     if (aeCreateFileEvent(server.el, server.fd, AE_READABLE,4470         acceptHandler, NULL, NULL) == AE_ERR) oom("creating file event");4471     redisLog(REDIS_NOTICE,"The server is now ready to accept connections on port %d", server.port);4472     aeMain(server.el);4473     aeDeleteEventLoop(server.el);4474     return 0;4475 }     

初始化參數 initServerConfig()

   static void initServerConfig() {server.dbnum = REDIS_DEFAULT_DBNUM;//初始化redis的數據庫個數16server.port = REDIS_SERVERPORT;//端口6379server.verbosity = REDIS_DEBUG;//默認這個為0// 這個是日志級別,有三種//#define REDIS_DEBUG 0                                                                                                                                                                          //#define REDIS_NOTICE 1 //#define REDIS_WARNING 2server.maxidletime = REDIS_MAXIDLETIME;//最大空閑時間60*5,也是客戶端的超時時間server.saveparams = NULL;//持久化策略server.logfile = NULL; /* NULL = log on standard output, 也可以在后期腳本文件中將參數傳入 */server.bindaddr = NULL;server.glueoutputbuf = 1;//在向客戶端應答時,是否把較小的包合并為一個包發送,默認為開啟。server.daemonize = 0;設置redis是否以守護進程方式運行,默認為no。server.pidfile = "/var/run/redis.pid";server.dbfilename = "dump.rdb";server.requirepass = NULL;//設置redis連接的密碼,設置之后客戶端連接redis時需要先通過auth命令提供密碼進行驗證才能進行后續操作,默認沒有密碼。設置操作:requirepass mypassserver.shareobjects = 0;server.sharingpoolsize = 1024;server.maxclients = 0;server.maxmemory = 0;ResetServerSaveParams();appendServerSaveParams(60*60,1);  /* save after 1 hour and 1 change */appendServerSaveParams(300,100);  /* save after 5 minutes and 100 changes */appendServerSaveParams(60,10000); /* save after 1 minute and 10000 changes *//* Replication related */server.isslave = 0;server.masterhost = NULL;server.masterport = 6379;server.master = NULL;server.replstate = REDIS_REPL_NONE;}

初始化函數中的server變量包含

   223 /* Global server state structure */224 struct redisServer {225     int port; //端口號226     int fd; //文件描述符227     redisDb *db; // 一個數組,保存著服務器中的所有數據庫228     dict *sharingpool; //存放數據的哈希表229     unsigned int sharingpoolsize;230     long long dirty; /* changes to DB from the last save */231     list *clients; //客戶端鏈表232     list *slaves, *monitors;233     char neterr[ANET_ERR_LEN]; //網絡錯誤信息存儲,最多256個char234     aeEventLoop *el; //事件循環結構體 235     int cronloops;              /* number of times the cron function run */236     list *objfreelist;          /* A list of freed objects to avoid malloc() */237     time_t lastsave;            /* Unix time of last save succeeede */238     size_t usedmemory;             /* Used memory in megabytes */239     /* Fields used only for stats */240     time_t stat_starttime;         /* server start time */241     long long stat_numcommands;    /* number of processed commands */242     long long stat_numconnections; /* number of connections received */243     /* Configuration */244     int verbosity;245     int glueoutputbuf;246     int maxidletime; //最大空閑時間247     int dbnum; //數據庫的數量248     int daemonize;249     char *pidfile;250     int bgsaveinprogress;251     pid_t bgsavechildpid;252     struct saveparam *saveparams; //持久化參數253     int saveparamslen;254     char *logfile; //日志文件路徑255     char *bindaddr;256     char *dbfilename;257     char *requirepass;258     int shareobjects;259     /* Replication related */260     int isslave;261     char *masterhost;262     int masterport;263     redisClient *master;    /* client that is master for this slave */264     int replstate;265     unsigned int maxclients; 266     unsigned int maxmemory;267     /* Sort parameters - qsort_r() is only available under BSD so we268      * have to take this state global, in order to pass it to sortCompare() */269     int sort_desc;270     int sort_alpha;271     int sort_bypattern;272 };273 

server函數中的redisDb *db;結構體

   190 typedef struct redisDb {                                                                                                                                                                                                         191     dict *dict; //當前數據庫的鍵空間192     dict *expires; //鍵的過期時間193     int id; //數據庫ID標識194 } redisDb;195     

server函數中的dict結構體

結構體位于:dict.h

 67 //哈希表的定義                                                                                                  68 typedef struct dict {                                                                                           69     //指向實際的哈希表記錄(用數組+開鏈的形式進行保存)                                                           70     dictEntry **table;                                                                                          71     //type中包含一系列哈希表需要用到的函數                                                                      72     dictType *type;                                                                                             73     //size表示哈希表的大小,為2的指數                                                                           74     unsigned long size;                                                                                         75     //sizemask=size-1,方便哈希值根據size取模                                                                    76     unsigned long sizemask;                                                                                     77     //used記錄了哈希表中有多少記錄                                                                              78     unsigned long used;                                                                                         79     void *privdata;                                                                                             80 } dict;                                                                                                         81 82 //對Hash表進行迭代遍歷時使用的迭代器83 typedef struct dictIterator {                                                                                   84     dict *ht;                                                                                                   85     int index;                                                                                                  86     dictEntry *entry, *nextEntry;                                                                               87 } dictIterator;                                                                                                 88 

dict結構體中的dictEntry

 46 //實際存放數據的地方47 typedef struct dictEntry {48     void *key;49     void *val;50     struct dictEntry *next;51 } dictEntry;52 

dict結構體中的dictType

 53 //要作用于哈希表上的相關函數54 /*55  * dictType在哈希系統中包含了一系列可由應用程序定義的56  * 函數指針57  */58 typedef struct dictType {59     unsigned int (*hashFunction)(const void *key);//哈希函數60     void *(*keyDup)(void *privdata, const void *key);//key復制61     void *(*valDup)(void *privdata, const void *obj);//value復制62     int (*keyCompare)(void *privdata, const void *key1, const void *key2);//key比較63     void (*keyDestructor)(void *privdata, void *key);//key銷毀64     void (*valDestructor)(void *privdata, void *obj);//value銷毀65 } dictType;66 

server函數中的list結構體

adlist.h

 67 /*                                                                                                              68  * redis中的雙向鏈表                                                                                            69  * head標識鏈表的頭指針                                                                                         70  * tail標識鏈表的尾結點                                                                                         71  * dup/free/match是三個函數指針                                                                                 72  * dup用于復制鏈表,返回值也是一個函數指針                                                                      73  * free用于釋放鏈表                                                                                             74  * match用于判斷鏈表中是否存在*key的值                                                                          75  * len標識鏈表的長度                                                                                            76  * listIter鏈表的迭代器,通過此迭代器可以對鏈表進行遍歷                                                         77  * 至于為什么要提供這種迭代器,可以查看設計模式相關的書箱                                                       78  */                                                                                                             79                                                                                                                 80 typedef struct list {                                                                                           81     listNode *head;//鏈表的頭結點                                                                         82     listNode *tail;//鏈表的尾節點                                                                      83     void *(*dup)(void *ptr);//復制鏈表                                                                     84     void (*free)(void *ptr);//釋放內存                                                                     85     int (*match)(void *ptr, void *key);//匹配                                                                         86     unsigned int len; //標識鏈表的長度,                                                                                         87     listIter iter;                                                                                              88 } list;                                                                                                         89                       

listNode結構體

 40 /*                                                                                                              41  * redis中最基本的結構用以標識鏈表中的結點                                                                      42  * *prev標識上一個節點                                                                                          43  * *next標識下一個節點                                                                                          44  * *value標識節點的值                                                                                           45  */                                                                                                             46                                                                                                          47 typedef struct listNode {                                                                                       48     struct listNode *prev;                                                                                      49     struct listNode *next;                                                                                      50     void *value;                                                                                                51 } listNode;                                                                                                     52   

迭代器

 53 /*                                                                                                              54  * 迭代器用于鏈表的遍歷                                                                                         55  * next將要遍歷的下一個元素                                                                                     56  * direction遍歷鏈表的方向                                                                                      57  * 方向由下面的兩個宏進行標識                                                                                   58  * AL_START_HEAD表示向前                                                                                        59  * AL_START_TAIL表示向后                                                                                        60  */                                                                                                             61                                                                                                                 62 typedef struct listIter {                                                                                       63     listNode *next;                                                                                             64     int direction;                                                                                              65 } listIter;                                                                                                     66  

server函數中的aeEventLoop *el結構體

ae.h

112 
113 /* State of an event based program */
114 /**
115  * 事件循環結構體
116  */
117 typedef struct aeEventLoop {
118     //用于標識下一個定時器
119     long long timeEventNextId;
120     //文件事件
121     aeFileEvent *fileEventHead;
122     //定時器事件
123     aeTimeEvent *timeEventHead;
124     //stop用于停止事件輪詢
125     int stop;
126 } aeEventLoop;
127 

aeEventLoopd的aeFileEvent和aeTimeEvent

 78 typedef struct aeFileEvent {79     int fd;80     /**81      * AE_READABLE|AE_WRITEABLE_AE_EXCEPTION中的一個82      * 表示要監聽的事件類型83      */84     int mask; /* one of AE_(READABLE|WRITABLE|EXCEPTION) */85     //文件事件相應的處理函數86     aeFileProc *fileProc;87     aeEventFinalizerProc *finalizerProc;88     void *clientData;89     //下一個文件事件90     struct aeFileEvent *next;91 } aeFileEvent;92 93 /* Time event structure */94 /**95  * redis自已定義的定時器事件96  * 其實現是一個鏈表,其中的每一個結點是一個Timer97  * when_sec與when_ms指定了定時器發生的時間98  * timeProc為響應函數99  * finalizerProc為刪除定時器的析構函數
100  */
101 typedef struct aeTimeEvent {
102     //定時器的id
103     long long id; /* time event identifier. */
104     long when_sec; /* seconds */
105     long when_ms; /* milliseconds */
106     aeTimeProc *timeProc;
107     aeEventFinalizerProc *finalizerProc;
108     //定義了該定時器有的數據情況
109     void *clientData;
110     struct aeTimeEvent *next;
111 } aeTimeEvent;

常數定義部分

  /* Error codes */#define REDIS_OK                0#define REDIS_ERR               -1/* Static server configuration */#define REDIS_SERVERPORT        6379    /* TCP port */#define REDIS_MAXIDLETIME       (60*5)  /* default client timeout */#define REDIS_IOBUF_LEN         1024#define REDIS_LOADBUF_LEN       1024#define REDIS_STATIC_ARGS       4#define REDIS_DEFAULT_DBNUM     16#define REDIS_CONFIGLINE_MAX    1024#define REDIS_OBJFREELIST_MAX   1000000 /* Max number of objects to cache */#define REDIS_MAX_SYNC_TIME     60      /* Slave can't take more to sync */#define REDIS_EXPIRELOOKUPS_PER_CRON    100 /* try to expire 100 keys/second */#define REDIS_MAX_WRITE_PER_EVENT (1024*64)#define REDIS_REQUEST_MAX_SIZE  (1024*1024*256) /* max bytes in inline command *//* Hash table parameters */#define REDIS_HT_MINFILL        10      /* Minimal hash table fill 10% *//* Command flags */#define REDIS_CMD_BULK          1       /* Bulk write command */#define REDIS_CMD_INLINE        2       /* Inline command *//* REDIS_CMD_DENYOOM reserves a longer comment: all the commands marked withthis flags will return an error when the 'maxmemory' option is set in theconfig file and the server is using more than maxmemory bytes of memory.In short this commands are denied on low memory conditions. */#define REDIS_CMD_DENYOOM       4/* Object types */#define REDIS_STRING 0#define REDIS_LIST 1#define REDIS_SET 2#define REDIS_HASH 3/* Object types only used for dumping to disk */#define REDIS_EXPIRETIME 253#define REDIS_SELECTDB 254#define REDIS_EOF 255/* Defines related to the dump file format. To store 32 bits lengths for short* keys requires a lot of space, so we check the most significant 2 bits of* the first byte to interpreter the length:** 00|000000 => if the two MSB are 00 the len is the 6 bits of this byte* 01|000000 00000000 =>  01, the len is 14 byes, 6 bits + 8 bits of next byte* 10|000000 [32 bit integer] => if it's 01, a full 32 bit len will follow* 11|000000 this means: specially encoded object will follow. The six bits*           number specify the kind of object that follows.*           See the REDIS_RDB_ENC_* defines.** Lenghts up to 63 are stored using a single byte, most DB keys, and may* values, will fit inside. */#define REDIS_RDB_6BITLEN 0#define REDIS_RDB_14BITLEN 1#define REDIS_RDB_32BITLEN 2#define REDIS_RDB_ENCVAL 3#define REDIS_RDB_LENERR UINT_MAX/* When a length of a string object stored on disk has the first two bits* set, the remaining two bits specify a special encoding for the object* accordingly to the following defines: */#define REDIS_RDB_ENC_INT8 0        /* 8 bit signed integer */#define REDIS_RDB_ENC_INT16 1       /* 16 bit signed integer */#define REDIS_RDB_ENC_INT32 2       /* 32 bit signed integer */#define REDIS_RDB_ENC_LZF 3         /* string compressed with FASTLZ *//* Client flags */#define REDIS_CLOSE 1       /* This client connection should be closed ASAP */#define REDIS_SLAVE 2       /* This client is a slave server */#define REDIS_MASTER 4      /* This client is a master server */#define REDIS_MONITOR 8      /* This client is a slave monitor, see MONITOR *//* Slave replication state - slave side */#define REDIS_REPL_NONE 0   /* No active replication */#define REDIS_REPL_CONNECT 1    /* Must connect to master */#define REDIS_REPL_CONNECTED 2  /* Connected to master *//* Slave replication state - from the point of view of master* Note that in SEND_BULK and ONLINE state the slave receives new updates* in its output queue. In the WAIT_BGSAVE state instead the server is waiting* to start the next background saving in order to send updates to it. */#define REDIS_REPL_WAIT_BGSAVE_START 3 /* master waits bgsave to start feeding it */#define REDIS_REPL_WAIT_BGSAVE_END 4 /* master waits bgsave to start bulk DB transmission */#define REDIS_REPL_SEND_BULK 5 /* master is sending the bulk DB */#define REDIS_REPL_ONLINE 6 /* bulk DB already transmitted, receive updates *//* List related stuff */#define REDIS_HEAD 0#define REDIS_TAIL 1/* Sort operations */#define REDIS_SORT_GET 0#define REDIS_SORT_DEL 1#define REDIS_SORT_INCR 2#define REDIS_SORT_DECR 3#define REDIS_SORT_ASC 4#define REDIS_SORT_DESC 5#define REDIS_SORTKEY_MAX 1024/* Log levels */#define REDIS_DEBUG 0#define REDIS_NOTICE 1#define REDIS_WARNING 2/* Anti-warning macro... */#define REDIS_NOTUSED(V) ((void) V)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/382378.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/382378.shtml
英文地址,請注明出處:http://en.pswp.cn/news/382378.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux 學習

1.linux文本命令行語言環境設置命令 查看當前語言環境: echo ¥LANG 修改: LANG選擇的語言環境’ 引申:https://blog.csdn.net/huoyunshen88/article/details/41113633 2.linux中的硬鏈接和軟連接 linux中文件的儲存方式&#xf…

vivo C/C++工程師視頻面試總結 20180802

1.自我介紹:有點兒緊張了,直接把自己簡歷上的一些信息信息說了一遍,說完之后在介紹了一下自己的平時的愛好和興趣,感覺面試官沒有理我,直接進入下一環節了。 2.項目詳情:主要是自己最近的一個項目和自己負…

Redis源碼分析(二)redis-cli.c

文章目錄1. int main()2. parseOptions(int argc, char **argv) 進行ip和port的改變3. lookupCommand(char *name) 查找命令,判斷命令合法3.2 strcasecmp(name,cmdTable[j].name)3.1 redisCommand cmdTable[]4. cliSendCommand(int argc, char **argv)4.1 cliConnec…

C語言中有bool變量嗎?

1.C/C中定義的數據類型: C語言中定義了6種基本數據類型:short,int,long,float,double,char 4種構造類型:數組,結構體(struct),共用類型(union),枚舉類型(enum) 指針類型和空類型 C語…

redis源碼剖析(三)——基礎數據結構

文章目錄SDS鏈表字典這篇文章關于 Redis 的基礎數據:SDS SDS (Simple Dynamic String)是 Redis 最基礎的數據結構。直譯過來就是”簡單的動態字符串“。Redis 自己實現了一個動態的字符串,而不是直接使用了 C 語言中的字符串。 sds 的數據結…

C++迭代器使用錯誤總結

指針和迭代器的區別: 迭代器: (1)迭代器不是指針,是類模板,表現的像指針。他只是模擬了指針的一些功能,通過重載了指針的一些操作符,->,*, --等封裝了指針,是一…

redis源碼剖析(四)跳表

文章目錄整數集合跳躍表壓縮列表總結整數集合 當一個集合只包含整數,且這個集合的元素不多的時候,Redis 就會使用整數集合 intset 。首先看 intset 的數據結構: typedef struct intset {// 編碼方式uint32_t encoding;// 集合包含的元素數量…

vivo C/C++工程師 HR視頻面試問題總結20180807

一開始沒想到這次視頻面是HR面試,還以為是技術面試,畢竟上次面試的時候技術問題問的相對比較少,所以面試準備方向有點兒錯了,不過還是總結一下具體問題。 1)自我介紹:吸取了上次自我介紹的經驗,…

在Redis客戶端設置連接密碼 并演示密碼登錄

我們先連接到Redis服務 然后 我們要輸入 CONFIG SET requirepass “新密碼” 例如 CONFIG SET requirepass "A15167"這樣 密碼就被設置成立 A15167 我們 輸入 AUTH 密碼 例如 AUTH A15167這里 返回OK說明成功了 然后 我們退出在登錄就真的需要 redis-cli -h IP地…

redis源碼剖析(五)—— 字符串,列表,哈希,集合,有序集合

文章目錄對象REDIS_STRING (字符串)REDIS_LIST 列表REDIS_SET (集合)REDIS_ZSET (有序集合)REDIS_HASH (hash表)int refcount(引用計數器)unsigned lru:REDIS_LRU_BITS對象 對于 Re…

函數sscanf小結

1.sscanf用于處理固定格式的字符串&#xff0c;包含在頭文件<cstdio>中&#xff0c;函數原型為&#xff1a; int sscanf(const char *buffer,const char*format,[]argument ]...); 其中:buffer代表著要存儲的數據&#xff0c;format 代表格式控制字符串&#xff0c;arg…

redis源碼剖析(六)—— Redis 數據庫、鍵過期的實現

文章目錄數據庫的實現數據庫讀寫操作鍵的過期實現數據庫的實現 我們先看代碼 server.h/redisServer struct redisServer{...//保存 db 的數組redisDb *db;//db 的數量int dbnum;... }再看redisDb的代碼&#xff1a; typedef struct redisDb {dict *dict; /*…

多益網絡 視頻面試面試總結20180816

1.首先是自我介紹&#xff1a;因為等了半個小時&#xff0c;所以有點兒緊張&#xff0c;只說了一下自己的學校&#xff0c;愛好和興趣&#xff1b; 2.介紹了一個自己的最成功的項目&#xff1a;我介紹了一個關于GPS導航的項目&#xff0c;介紹了項目的內容和項目的一些工作&am…

redis源碼剖析(七)—— Redis 數據結構dict.c

文章目錄dict.hdict.cdict.h //定義錯誤相關的碼 #define DICT_OK 0 #define DICT_ERR 1//實際存放數據的地方 typedef struct dictEntry {void *key;void *val;struct dictEntry *next; } dictEntry;//哈希表的定義 typedef struct dict {//指向實際的哈希表記錄(用數組開鏈的…

簡述linux中動態庫和靜態庫的制作調用流程

假設現在有這些文件&#xff1a;sub.c add.c div.c mul.c mainc head.h&#xff08;前4個.C文件的頭文件&#xff09; 1.靜態庫制作流程 gcc -c sub.c add.c div.c mul.c -->生成 .o目標文件文件 ar rcs libmycal.a *.o …

redis源碼剖析(八)—— 當你啟動Redis的時候,Redis做了什么

文章目錄啟動過程初始化server結構體main函數會調用initServer函數初始化服務器狀態載入持久化文件&#xff0c;還原數據庫開始監聽事件流程圖啟動過程 初始化server結構體從配置文件夾在加載參數初始化服務器載入持久化文件開始監聽事件 初始化server結構體 服務器的運行ID…

linux中錯誤總結歸納

1.使用gcc編譯C文件&#xff0c;C文件在for循環語句中出現變量定義 編譯器提示錯誤&#xff1a;“for”loop initial declarations are only allowed in C99 mode. note:use option -stdc99or-stdgnu99 to compile; 原因&#xff1a;gcc的標準是基于c89的&#xff0c;c89不能在…

redis源碼剖析(十一)—— Redis字符串相關函數實現

文章目錄初始化字符串字符串基本操作字符串拼接操作other獲取指定范圍里的字符串將字符串中的所有字符均轉為小寫的形式將字符串中所有字符均轉為大寫的形式字符串比較other#define SDS_ABORT_ON_OOM#include "sds.h" #include <stdio.h> #include <stdlib.…

makefile內容小結

makefile中每個功能主要分為三部分&#xff1a;目標&#xff0c;依賴條件和命令語句 1.支持對比更新的Makefile寫法&#xff08;只會編譯文件時.o文件和.c文件時間不一致的文件&#xff09; 2.使用makefile自動變量和自定義變量的makefile寫法 其中&#xff1a;這三個符號為ma…

事務隔離級別動圖演示

事務的基本要素&#xff08;ACID&#xff09; 原子性&#xff08;Atomicity&#xff09; 事務開始后所有操作&#xff0c;要么全部做完&#xff0c;要么全部不做&#xff0c;不可能停滯在中間環節。事務執行過程中出錯&#xff0c;會回滾到事務開始前的狀態&#xff0c;所有的…