redis是水平触发还是边沿触发
对的,epoll默认是水平触发,从主从同步也可以看出来,主从同步时,从节点在REPL_STATE_RECEIVE_AUTH_REPLY前一个状态REPL_STATE_SEND_HANDSHAKE时,发送了多个命令给master,但是这里针对该状态,只处理了一个就返回了,怎么保证服务器发送的多个回复得到处理,元素是因为下次还是会触发,因为是水平触发,触发后还是会到达syncWithMaster函数根据状态进行相应的处理
redis中限制最大客户连接数怎么实现的?
连接建立时,会调用到acceptCommonHandler函数,该函数会判断,如果超过了则会拒绝
同时添加事件监听时也会判断fd是否超过
epoll_wait中也会用到最大连接数
serverCron多久执行一次
f (aeCreateTimeEvent(server.el, 1, serverCron, NULL, NULL) == AE_ERR) {
serverPanic("Can't create event loop timers.");
exit(1);
}
上面代码表示1毫秒后开始执行serverCron,在Ae.c中的processTimeEvents函数中调用的serverCron函数,调用完会更新下次执行时间,如下:
if (te->when <= now) {
int retval;
id = te->id;
te->refcount++;
retval = te->timeProc(eventLoop, id, te->clientData);
te->refcount--;
processed++;
now = getMonotonicUs();
if (retval != AE_NOMORE) {
te->when = now + retval * 1000; //这个地方
} else {
te->id = AE_DELETED_EVENT_ID;
}
}
即下次执行的时间是serverCron函数返回值*1000,serverCron函数返回的是1000/server.hz,server.hz默认是10,所以默认serverCron是每100毫秒调用一次,但是是在主线程中执行的,主线程阻塞(如在执行命令)的话,就可能导致延期执行了,可以知道serverCron函数是每1000/server.hz毫秒调用一次
run_with_period宏定义解释
#define run_with_period(_ms_) if ((_ms_ <= 1000/server.hz) || !(server.cronloops%((_ms_)/(1000/server.hz))))
这个宏是在serverCron函数中被调用,如下:
/* Run the Redis Cluster cron. */
run_with_period(100) {
if (server.cluster_enabled) clusterCron();
}
上面表示每100毫秒就执行if中的代码,server.cronloops表示serverCron每执行一次就会加1
server.hz的意义是serverCron在一秒内执行的次数(从redis的实现来看,这个值是以ms为最小单位来计算的),那么1000/server.hz就是serverCron的执行间隔(ms),再结合run_with_period的定义可以看出,run_with_period表示每_ms_毫秒执行一段任务