Redis 심층 분석 서버 편

소개 하 다.
현재 많은 NoSql 데이터베이스 가 활발 하 게 등장 하기 시 작 했 습 니 다. 성능 이 좋 은 Nosql DB 로 서 Redis 는 좋 은 선택 입 니 다. 또한 Redis 는 다양한 데이터 구 조 를 지원 합 니 다. Sort Set, SET, LIST, 그리고 1.3.4 버 전에 서 Sort Set 의 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;
}

좋은 웹페이지 즐겨찾기