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.mzph.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;所有的…