`

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;
}
2
0
分享到:
评论

相关推荐

    redis源码分析

    Redis是一款高性能的键值存储系统,常...通过分析以上这些关键点,我们可以深入理解Redis的工作原理,为优化性能、开发插件或解决实际问题提供基础。Redis源码清晰、简洁,是学习分布式存储系统和C语言编程的优秀实例。

    Go 实现的 Redis 内存分析工具

    2. **Redis 协议**:工具需要能够连接到 Redis 服务器,发送命令并接收响应,这就要求对 Redis 的命令集和协议有深入理解。 3. **内存分析**:了解 Redis 数据结构(如 String、Hash、List、Set 和 Sorted Set)的...

    redis之相关理解分析以及面试问题总结

    - 持久化:Redis提供了RDB(快照)和AOF(日志)两种持久化方式,确保在服务器重启后能够恢复数据。 - 主从复制:通过主从复制,可以实现数据备份和读写分离,提高系统的可用性和性能。 - 事务:Redis支持简单...

    Redis流量-流量分析

    本文将深入探讨Redis流量分析的关键知识点。 一、Redis的数据结构与流量 1. 数据结构:Redis支持多种数据结构,如字符串(String)、哈希表(Hash)、列表(List)、集合(Set)和有序集合(Sorted Set)。不同的...

    REDIS_redis的工具包_redisinlabview_labviewredis_labview调用redis_redis

    1. **连接Redis服务器**:首先,需要创建一个连接到Redis服务器的VI,这通常涉及到设置服务器地址、端口号、超时时间等参数。 2. **执行命令**:连接成功后,可以选择相应的VI来执行Redis命令,如`SET`(设置键值)...

    阮若夷:Redis深入浅出

    综上所述,阮若夷在“Redis深入浅出”中全面而细致地讲述了Redis的核心特性和机制,并通过实例和对比分析的方式,帮助读者更加深入地理解Redis。通过这些知识点的学习,开发者可以在实际应用中更加灵活地使用Redis,...

    Redis源代码分析.pdf

    Redis源代码分析文档对Redis的源代码进行了深入分析,涵盖了Redis的基本功能、服务器模型、事件处理、套接字操作、客户端连接、命令处理、虚拟内存、数据读取过程、数据交换策略、备份机制、主从同步等方面。...

    redis架构分析.docx

    本文将深入探讨Redis的架构,尤其是其启动流程以及数据持久化方案。 在启动Redis的过程中,首先会进行服务器变量的初始化,设定默认值,例如端口号、数据库数量等。接着,Redis会读取配置文件,并结合命令行参数来...

    Redis-desktop redis管理工具 支持SSH 各种系统

    在本文中,我们将深入探讨一个名为"Redis-desktop"的可视化管理工具,它支持SSH连接,使得用户能够更方便地管理和操作远程Redis服务器。 **Redis-desktop** 是一款专为Redis设计的图形用户界面(GUI)管理工具,...

    redis windows C++客户端例子

    接下来,深入到代码中,你可能会看到如何初始化Redis连接,设置超时,发送命令(如`SET`, `GET`, `LPUSH`, `LPOP`等)以及处理返回的响应。在VS2010中,你可以设置断点,查看变量状态,理解代码的工作原理。 对于...

    tomcat-redis依赖jar包

    本文将深入探讨"tomcat-redis依赖jar包"的相关知识点。 1. **Redis连接器** Tomcat与Redis通信通常需要一个中间件,即Redis连接器。这个连接器是一个Java库,例如Jedis或Lettuce,它们提供了Java API来操作Redis。...

    redis 可视化工具以及免安装redis 绿色版

    本文将深入探讨Redis的可视化工具及其免安装绿色版的使用,帮助你更好地管理和操作Redis服务器。 首先,了解Redis可视化工具的重要性。在日常开发和运维中,直观地查看和管理Redis的数据结构、键值对以及性能指标是...

    redis远程客户端管理工具

    这对于团队协作和项目管理尤其有帮助,因为团队成员可以直观地看到和修改数据库状态,而不需要深入了解Redis命令行语法。 总的来说,Redis远程客户端管理工具是开发和运维人员不可或缺的辅助工具,它们简化了Redis...

    Redis-x64-5.0.9.zip

    在本文中,我们将深入探讨Redis的主要特性和功能,以及如何安装和使用这个版本。 1. **Redis的数据类型**: - 字符串(Strings):最基础的数据类型,可以存储文本或二进制数据。 - 哈希(Hashes):用于存储键值对...

    redis开发和运维

    接下来,书中对Redis的API进行了深入解析,让读者能够理解不同数据结构(如字符串、哈希、列表、集合、有序集合等)的操作命令和内部编码方式,这些都是Redis开发的基础知识。 书中的第3章聚焦于Redis的一些辅助...

    Go-用于服务器端的一个Redis协议Go库

    2. **响应解码**:接收到Redis服务器的响应后,`go-redisproto`能将其解码回Go语言中的数据结构,如`[]interface{}`或自定义类型,方便进一步的处理和分析。 3. **错误处理**:库内置了对Redis错误响应的处理,当...

    redis的windows版

    Redis提供了INFO命令,用于获取服务器状态和统计信息,帮助监控和分析服务器性能。 总之,Redis在Windows上的使用虽然相比Linux环境有一些差异,但其核心特性和功能保持一致,为开发者提供了强大且灵活的键值存储...

Global site tag (gtag.js) - Google Analytics