千家信息网

怎样分析Redis超时

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这期内容当中小编将会给大家带来有关怎样分析Redis超时,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Redis在分布式应用中占据着越来越重要的地位,短短的几万行代
千家信息网最后更新 2026年11月02日怎样分析Redis超时

这期内容当中小编将会给大家带来有关怎样分析Redis超时,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

Redis在分布式应用中占据着越来越重要的地位,短短的几万行代码,实现了一个高性能的数据存储服务。最近dump中心的cm8集群出现过几次redis超时的情况,但是查看redis机器的相关内存都没有发现内存不够,或者内存发生交换的情况,查看redis源码之后,发现在某些情况下redis会出现超时的状况,相关细节如下。

1. 网络。Redis的处理与网络息息相关,如果网络出现闪断则容易发生redis超时的状况。如果出现这种状况首先应查看redis机器网络带宽信息,判断是否有闪断情况发生。

2. 内存。redis所有的数据都放在内存里,当物理内存不够时,linux os会使用swap内存,导致内存交换发生,这时如果有redis调用命令就会产生redis超时。这里可以通过调整/proc/sys/vm/swappiness参数,来设置物理内存使用超过多少就会进行swap。

int rdbSaveBackground(char *filename) {     pid_t childpid;     long long start;       if (server.rdb_child_pid != -1) return REDIS_ERR;     serverserver.dirty_before_bgsave = server.dirty;     server.lastbgsave_try = time(NULL);     start = ustime();     if ((childpid = fork()) == 0) {         int retval;         /* Child */         if (server.ipfd > 0) close(server.ipfd);         if (server.sofd > 0) close(server.sofd);         retval = rdbSave(filename);         if (retval == REDIS_OK) {             size_t private_dirty = zmalloc_get_private_dirty();             if (private_dirty) {                 redisLog(REDIS_NOTICE,                     "RDB: %zu MB of memory used by copy-on-write",                     private_dirty/(1024*1024));             }         }         exitFromChild((retval == REDIS_OK) ? 0 : 1);     } else {         /* Parent */         server.stat_fork_time = ustime()-start;         if (childpid == -1) {             server.lastbgsave_status = REDIS_ERR;             redisLog(REDIS_WARNING,"Can't save in background: fork: %s",                 strerror(errno));             return REDIS_ERR;         }         redisLog(REDIS_NOTICE,"Background saving started by pid %d",childpid);         server.rdb_save_time_start = time(NULL);         server.rdb_child_pid = childpid;         updateDictResizePolicy();         return REDIS_OK;     }     return REDIS_OK; /* unreached */ }

程序1

另外还有一些特殊情况也会导致swap发生。当我们使用rdb做为redis集群持久化时可能会发生物理内存不够的情况(aof持久化只是保持支持不断的追加redis集群变化操作,不太容易引起swap)。当使用rdb持久化时,如程序1所示主进程会fork一个子进程去dump redis中所有的数据,主进程依然为客户端服务。此时主进程和子进程共享同一块内存区域, linux内核采用写时复制来保证数据的安全性。在这种模式下如果客户端发来写请求,内核将该页赋值到一个新的页面上并标记为写,在将写请求写入该页面。因此,在rdb持久化时,如果有其他请求,那么redis会使用更多的内存,更容易发生swap,因此在可以快速恢复的场景下尽量少使用rdb持久化可以将rdb dump的条件设的苛刻一点,当然也可以选择aof,但是aof也有他自身的缺点。另外也可以使用2.6以后的主从结构,将读写分离,这样不会出现server进程上又读又写的情景发生 3. Redis单进程处理命令。Redis支持udp和tcp两种连接,redis客户端向redis服务器发送包含redis命令的信息,redis服务器收到信息后解析命令后执行相应的操作,redis处理命令是串行的具体流程如下。首先服务端建立连接如程序2所示,在创建socket,bind,listen后返回文件描述符:

server.ipfd = anetTcpServer(server.neterr,server.port,server.bindaddr);

程序2

对于redis这种服务来说,它需要处理成千上万个连接(***达到655350),需要使用多路复用来处理多个连接。这里redis提供了epoll,select, kqueue来实现,这里在默认使用epoll(ae.c)。拿到listen函数返回的文件描述符fd后,redis将fd和其处理acceptTcpHandler函数加入到事件驱动的链表中.实际上在加入事件队列中,程序4事件驱动程序将套接字相关的fd文件描述符加入到epoll的监听事件中。

 if (server.ipfd > 0 && aeCreateFileEvent(server.el,server.ipfd,AE_READABLE,         acceptTcpHandler,NULL) == AE_ERR) redisPanic("Unrecoverable error creating server.ipfd file event.");   int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask,         aeFileProc *proc, void *clientData) {     if (fd >= eventLoop->setsize) {         errno = ERANGE;         return AE_ERR;     }     aeFileEvent *fe = &eventLoop->events[fd];       if (aeApiAddEvent(eventLoop, fd, mask) == -1)         return AE_ERR;     fe->mask |= mask;     if (mask & AE_READABLE) fe->rfileProc = proc;     if (mask & AE_WRITABLE) fe->wfileProc = proc;     fe->clientDataclientData = clientData;     if (fd > eventLoop->maxfd)         eventLoop->maxfd = fd;     return AE_OK; }

程序3

static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) {      aeApiState *state = eventLoop->apidata;      struct epoll_event ee;      /* If the fd was already monitored for some event, we need a MOD       * operation. Otherwise we need an ADD operation. */      int op = eventLoop->events[fd].mask == AE_NONE ?              EPOLL_CTL_ADD : EPOLL_CTL_MOD;      ee.events = 0;      mask |= eventLoop->events[fd].mask; /* Merge old events */      if (mask & AE_READABLE) ee.events |= EPOLLIN;      if (mask & AE_WRITABLE) ee.events |= EPOLLOUT;      ee.data.u64 = 0; /* avoid valgrind warning */      ee.data.fd = fd;      if (epoll_ctl(state->epfd,op,fd,&ee) == -1) return -1;      return 0;  }

程序4

在初始话完所有事件驱动后,如程序5所示主进程根据numevents = aeApiPoll(eventLoop, tvp)获得io就绪的文件描述符和其对应的处理程序,并对fd进行处理。大致流程是accept()->createclient()->readQueryFromClient()。其中readQueryFromClient()读取信息中的redis命令-> processInputBuffer()->call()***完成命令。

void aeMain(aeEventLoop *eventLoop) {     eventLoop->stop = 0;     while (!eventLoop->stop) {         if (eventLoop->beforesleep != NULL)             eventLoop->beforesleep(eventLoop);         aeProcessEvents(eventLoop, AE_ALL_EVENTS);     } } int aeProcessEvents(aeEventLoop *eventLoop, int flags) {-------------------------------  numevents = aeApiPoll(eventLoop, tvp);         for (j = 0; j < numevents; j++) {             aeFileEvent *fe = &eventLoop->events[eventLoop->fired[j].fd];             int mask = eventLoop->fired[j].mask;             int fd = eventLoop->fired[j].fd;             int rfired = 0;               /* note the fe->mask & mask & ... code: maybe an already processed              * event removed an element that fired and we still didn't              * processed, so we check if the event is still valid. */             if (fe->mask & mask & AE_READABLE) {                 rfired = 1;                 fe->rfileProc(eventLoop,fd,fe->clientData,mask);             }             if (fe->mask & mask & AE_WRITABLE) {                 if (!rfired || fe->wfileProc != fe->rfileProc)                     fe->wfileProc(eventLoop,fd,fe->clientData,mask);             }             processed++;         } }

程序5

从上述代码可以看出redis利用ae事件驱动结合epoll多路复用实现了串行式的命令处理。所以一些慢命令例如sort,hgetall,union,mget都会使得单命令处理时间较长,容易引起后续命令time out.所以我们需要从业务上尽量避免使用慢命令,如将hash格式改为kv自行解析,第二增加redis实例个数,每个redis服务器调用尽量少的慢命令。

上述就是小编为大家分享的怎样分析Redis超时了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注行业资讯频道。

命令 内存 程序 处理 进程 服务 事件 情况 分析 信息 数据 文件 网络 驱动 不够 客户 客户端 服务器 物理 状况 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技公司的优势 中国互联网科技股 致聘互联网科技 米客互联网科技 猫创互联网科技 互联网前沿科技 甘肃拓世互联网科技有限公司 互联网科技中介 互联网科技项目计划书材料类 武汉健翔互联网络科技有限公司 岳阳华臻互联网科技有限公司 移动互联网年度科技创新 四川慕妮娅互联网科技有限公司 互联网科技公司营业执照怎么办理 杭州披云加互联网科技有限公司 郑州欣桑互联网科技有限公司 吉林省码上互联网科技电话 中国新注册互联网科技 互联网科技平台产品运营 宁波允成互联网科技有限公司 互联网科技的发展 银优互联网科技有限公司 互联网科技博客 互联网企业和科技型企业 广州恒生互联网科技有限 辽宁互联网新科技 广州燕处互联网科技有限公司 上海旺乐尼互联网科技有限公司 互联网企业和网络科技有限公司 银川新华互联网科技学校招聘
0