redis学习笔记->时间事件管理
2017-04-11 20:04
288 查看
一、redis时间缓存
在server结构体内,有两个成员,缓存下系统的当前时间
二、执行定时事件
server结构体内,有个 server.hz成员,时间事件serverCron()函数每次调用完会返回1000/server.hz,时间事件处理器将当前时间会加上这个值,作为下次触发serverCron()函数的时间点。这以为着,每秒钟,会调用server.hz次serverCron()函数。
serverCron()函数内会调用一些定时事件,比如检查客户端,统计命令次数等等。有的事件不需要每秒执行1000/server.hz次,因此需要使用run_with_period(milliseconds)宏,代表着每隔milliseconds秒执行一次该事件。
三、定时事件
检查客户端
数据库操作
// 对数据库执行删除过期键,调整大小,以及主动和渐进式 rehash
void databasesCron(void) {
// 函数先从数据库中删除过期键,然后再对数据库的大小进行修改
/* Expire keys by random sampling. Not required for slaves
* as master will synthesize DELs for us. */
// 如果服务器不是从服务器,那么执行主动过期键清除
if (server.active_expire_enabled && server.masterhost == NULL)
// 清除模式为 CYCLE_SLOW ,这个模式会尽量多清除过期键
activeExpireCycle(ACTIVE_EXPIRE_CYCLE_SLOW);
/* Perform hash tables rehashing if needed, but only if there are no
* other processes saving the DB on disk. Otherwise rehashing is bad
* as will cause a lot of copy-on-write of memory pages. */
// 在没有 BGSAVE 或者 BGREWRITEAOF 执行时,对哈希表进行 rehash
if (server.rdb_child_pid == -1 && server.aof_child_pid == -1) {
/* We use global counters so if we stop the computation at a given
* DB we'll be able to start from the successive in the next
* cron loop iteration. */
static unsigned int resize_db = 0;
static unsigned int rehash_db = 0;
unsigned int dbs_per_call = REDIS_DBCRON_DBS_PER_CALL;
unsigned int j;
/* Don't test more DBs than we have. */
// 设定要测试的数据库数量
if (dbs_per_call > server.dbnum) dbs_per_call = server.dbnum;
/* Resize */
// 调整字典的大小
for (j = 0; j < dbs_per_call; j++) {
tryResizeHashTables(resize_db % server.dbnum);
resize_db++;
}
/* Rehash */
// 对字典进行渐进式 rehash
if (server.activerehashing) {
for (j = 0; j < dbs_per
4000
_call; j++) {
int work_done = incrementallyRehash(rehash_db % server.dbnum);
rehash_db++;
if (work_done) {
/* If the function did some work, stop here, we'll do
* more at the next cron loop. */
break;
}
}
}
}
}
还有定时记录日志,统计服务器命令,内存信息等等
在server结构体内,有两个成员,缓存下系统的当前时间
redisServer { time_t unixtime; /* Unix time sampled every cron cycle. */ long long mstime; /* Like 'unixtime' but with milliseconds resolution. */ }在初始化iniServer()函数内,以及系统定时调用serverCron()函数内,会调用updateCachedTime()更新缓存的时间。
void updateCachedTime(void) { server.unixtime = time(NULL); server.mstime = mstime(); }
二、执行定时事件
server结构体内,有个 server.hz成员,时间事件serverCron()函数每次调用完会返回1000/server.hz,时间事件处理器将当前时间会加上这个值,作为下次触发serverCron()函数的时间点。这以为着,每秒钟,会调用server.hz次serverCron()函数。
serverCron()函数内会调用一些定时事件,比如检查客户端,统计命令次数等等。有的事件不需要每秒执行1000/server.hz次,因此需要使用run_with_period(milliseconds)宏,代表着每隔milliseconds秒执行一次该事件。
#define run_with_period(_ms_) if ((_ms_ <= 1000/server.hz) || !(server.cronloops%((_ms_)/(1000/server.hz))))
// 每隔100毫秒记录服务器执行命令的次数 run_with_period(100) trackOperationsPerSecond();其中server.cronloops再每次serverCron()函数返回之前会自增一次。
三、定时事件
检查客户端
// 检查客户端,关闭超时客户端,并释放客户端多余的缓冲区 clientsCron(); void clientsCron(void) { // 客户端数量 int numclients = listLength(server.clients); // 要处理的客户端数量 int iterations = numclients/(server.hz*10); // 至少要处理 50 个客户端 if (iterations < 50) iterations = (numclients < 50) ? numclients : 50; while(listLength(server.clients) && iterations--) { redisClient *c; listNode *head; /* Rotate the list, take the current head, process. * This way if the client must be removed from the list it's the * first element and we don't incur into O(N) computation. */ // 翻转列表,然后取出表头元素,这样一来上一个被处理的客户端会被放到表头 // 另外,如果程序要删除当前客户端,那么只要删除表头元素就可以了 listRotate(server.clients); head = listFirst(server.clients); c = listNodeValue(head); /* The following functions do different service checks on the client. * The protocol is that they return non-zero if the client was * terminated. */ // 检查客户端,并在客户端超时时关闭它 if (clientsCronHandleTimeout(c)) continue; // 根据情况,缩小客户端查询缓冲区的大小 if (clientsCronResizeQueryBuffer(c)) continue; } }
数据库操作
// 对数据库执行删除过期键,调整大小,以及主动和渐进式 rehash
void databasesCron(void) {
// 函数先从数据库中删除过期键,然后再对数据库的大小进行修改
/* Expire keys by random sampling. Not required for slaves
* as master will synthesize DELs for us. */
// 如果服务器不是从服务器,那么执行主动过期键清除
if (server.active_expire_enabled && server.masterhost == NULL)
// 清除模式为 CYCLE_SLOW ,这个模式会尽量多清除过期键
activeExpireCycle(ACTIVE_EXPIRE_CYCLE_SLOW);
/* Perform hash tables rehashing if needed, but only if there are no
* other processes saving the DB on disk. Otherwise rehashing is bad
* as will cause a lot of copy-on-write of memory pages. */
// 在没有 BGSAVE 或者 BGREWRITEAOF 执行时,对哈希表进行 rehash
if (server.rdb_child_pid == -1 && server.aof_child_pid == -1) {
/* We use global counters so if we stop the computation at a given
* DB we'll be able to start from the successive in the next
* cron loop iteration. */
static unsigned int resize_db = 0;
static unsigned int rehash_db = 0;
unsigned int dbs_per_call = REDIS_DBCRON_DBS_PER_CALL;
unsigned int j;
/* Don't test more DBs than we have. */
// 设定要测试的数据库数量
if (dbs_per_call > server.dbnum) dbs_per_call = server.dbnum;
/* Resize */
// 调整字典的大小
for (j = 0; j < dbs_per_call; j++) {
tryResizeHashTables(resize_db % server.dbnum);
resize_db++;
}
/* Rehash */
// 对字典进行渐进式 rehash
if (server.activerehashing) {
for (j = 0; j < dbs_per
4000
_call; j++) {
int work_done = incrementallyRehash(rehash_db % server.dbnum);
rehash_db++;
if (work_done) {
/* If the function did some work, stop here, we'll do
* more at the next cron loop. */
break;
}
}
}
}
}
还有定时记录日志,统计服务器命令,内存信息等等
相关文章推荐
- 你的C:\>能干啥?(1) -- 用PowerShell打造时间管理小秘书
- 时间事件管理工具类
- 专题: 时间/进度管理中的---&gt; 图
- 时间事件管理工具类
- 队列->离散事件模拟-银行管理
- outlook中“约会”、“事件”和“任务”的概念及论“时间管理
- redis学习笔记->事件处理流程
- <<时间管理与问题解决技巧>> 培训心得
- 时间管理不等于事件提醒
- <Linux+Qt>时间控制事件触发
- 结果导向的时间管理
- 第四代时间管理:要事第一
- 结果导向的时间管理
- 脚本中心-->>计算机管理示例脚本(收集整理)
- 一事无成?你会管理好自己的时间吗?
- 时间管理 - 简化生活:复杂性定律
- 时间管理的十个漏洞
- 时间管理的40项准则
- [转载]时间管理
- 时间管理读后记(三)