设为首页 收藏本站
查看: 854|回复: 0

[经验分享] Redis 深入分析 之 服务器篇

[复制链接]
发表于 2016-12-20 08:26:15 | 显示全部楼层 |阅读模式
介绍
目前许多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;
}

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-316663-1-1.html 上篇帖子: redis最大缓存及key回收策略 下篇帖子: redis安装使用-进阶篇(持久化)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表