Redis 深入分析 之 服务器篇 RedisNoSQL数据结构J#算法
程序员文章站
2024-03-17 12:42:46
...
介绍
目前许多NoSql的数据库开始踊跃出现,作为性能比较出色的Nosql DB,Redis还是不错的选择,并且Redis 支持多种数据结构 SortSet,SET ,LIST, 并且在1.3.4版本支持SortSet的RANK功能,如果您想要计算排名服务不妨试试它、
Redis 官方网站:
http://code.google.com/p/redis/
以下是Redis 服务器端代码的分析
目前许多NoSql的数据库开始踊跃出现,作为性能比较出色的Nosql DB,Redis还是不错的选择,并且Redis 支持多种数据结构 SortSet,SET ,LIST, 并且在1.3.4版本支持SortSet的RANK功能,如果您想要计算排名服务不妨试试它、
Redis 官方网站:
http://code.google.com/p/redis/
以下是Redis 服务器端代码的分析
//Title: Redis 深入分析之服务器篇 //author: liuzheng //注意: 本篇文章仅供参考 main(int argc, char **argv) { //一 加载配置 loadServerConfig(); ///二 配置项 maxidletime,port,bindaddr,verbosity,logfile,dbnum,maxclients,maxmemory,masterhost,masterport,replstate,masterauth,glueoutputbuf,shareobjects,rdbcompression sharingpoolsize,daemonize,appendonly,appendfsyncm,requirepass,pidfile,dbfilename //三 初始化服务器 initServer(); //1.赋值server 属性 //2.创建定时器,1ms执行一次 aeCreateTimeEvent(server.el, 1, serverCron, NULL, NULL); //这个是个定时器链表 //long long aeCreateTimeEvent(aeEventLoop *eventLoop, long long milliseconds, //aeTimeProc *proc, void *clientData, //aeEventFinalizerProc *finalizerProc) //3.server Crontab serverCron(); //1.log数据库信息 //2.log client connections //3.Show info about connections of clients //4.Close connections of timedout clients //5.1 Check if a background saving or AOF rewrite in progress terminated, //5.2 If there is not a background saving in progress check if we have to save now if (server.dirty >= sp->changes && now-server.lastsave > sp->seconds) rdbSaveBackground(server.dbfilename)-> rdbSave(server.dbfilename); //1.创建 "temp-%d.rdb" //2. for (j = 0; j < server.dbnum; j++) { redisDb *db = server.db+j; //1.保存类型 //2.保存大小 //遍历 DB 写入每个 entry //写入方式 // 1.写入原始值-一般为string类型 // 2.将内存值转换为string写入 } //写入文件数据结构为 //DB_TYPE,DB_LEN,Entry_type,Entry_len,Entry_object_string...... //DB_TYPE,DB_LEN,Entry_type,Entry_len,Entry_object_string...... //...16个DB //这里只有发生变化就会触发 server.dirty++; //但是mset 使用的是如下算法 server.dirty += (c->argc-1)/2; //6. Try to expire a few timed out keys //7. Check if we should connect to a MASTER ,SYNC syncWithMaster(void); //1.valid and auth //2.按块(1024)读取数据库文件 while(可以读到数据) { nread = read(fd,buf,(dumpsize < 1024)?dumpsize:1024); # nwritten = write(dfd,buf,nread); nwritten.to(temp_file); } rename(temp_file,server.dbfilename); emptyDb(); rdbLoad(server.dbfilename); //四 Load File to memory if (server.appendonly) { if (loadAppendOnlyFile(server.appendfilename) == REDIS_OK) redisLog(REDIS_NOTICE,"DB loaded from append only file"); } else { if (rdbLoad(server.dbfilename) == REDIS_OK) redisLog(REDIS_NOTICE,"DB loaded from disk"); } //五 侦听client事件 aeCreateFileEvent(server.el, server.fd, AE_READABLE,acceptHandler, NULL) == AE_ERR) //aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask,aeFileProc *proc, void *clientData) //六 开启所有侦听事件 aeMain(); //七 清楚完成事件 aeDeleteEventLoop(server.el); } //Redis 数据结构介绍 //DB struct //创建数据库 server.db = zmalloc(sizeof(redisDb)*server.dbnum); for (j = 0; j < server.dbnum; j++) { server.db[j].dict = dictCreate(&hashDictType,NULL); server.db[j].expires = dictCreate(&setDictType,NULL); server.db[j].id = j; } /* Create a new hash table */ dict *dictCreate(dictType *type, void *privDataPtr) { dict *ht = _dictAlloc(sizeof(*ht)); _dictInit(ht,type,privDataPtr); return ht; } /* Initialize the hash table */ int _dictInit(dict *ht, dictType *type,void *privDataPtr) { _dictReset(ht); ht->type = type; ht->privdata = privDataPtr; return DICT_OK; } /* Resize the table to the minimal size that contains all the elements, * but with the invariant of a USER/BUCKETS ration near to <= 1 */ static void _dictReset(dict *ht) { ht->table = NULL; ht->size = 0; ht->sizemask = 0; ht->used = 0; } typedef struct dictEntry { void *key; void *val; struct dictEntry *next; } dictEntry; typedef struct dictType { unsigned int (*hashFunction)(const void *key); void *(*keyDup)(void *privdata, const void *key); void *(*valDup)(void *privdata, const void *obj); int (*keyCompare)(void *privdata, const void *key1, const void *key2); void (*keyDestructor)(void *privdata, void *key); void (*valDestructor)(void *privdata, void *obj); } dictType; typedef struct dict { dictEntry **table; dictType *type; unsigned long size; unsigned long sizemask; unsigned long used; void *privdata; } dict; typedef struct redisDb { dict *dict; dict *expires; int id; } redisDb; /// //Save Struct 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 */ static void appendServerSaveParams(time_t seconds, int changes) { server.saveparams = zrealloc(server.saveparams,sizeof(struct saveparam)*(server.saveparamslen+1)); server.saveparams[server.saveparamslen].seconds = seconds; server.saveparams[server.saveparamslen].changes = changes; server.saveparamslen++; } static void resetServerSaveParams() { zfree(server.saveparams); server.saveparams = NULL; server.saveparamslen = 0; }