前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >nginx,memcached,redis网络模型总结

nginx,memcached,redis网络模型总结

作者头像
后端技术探索
发布2018-08-10 11:15:02
1.7K0
发布2018-08-10 11:15:02
举报
文章被收录于专栏:后端技术探索后端技术探索

nginx服务器模型

nginx进程模型

nginx采用多进程模型,含一个master进程和多个worker进程,worker进程数目可配置,一般与机器CPU核心数目一致,master进程主要职责是:接收外界信号,如star,stop,restart,监控worker进程状态。worker进程主要职责:负责处理客户端请求。

这种进程模型的好处:

  1. 每个worker进程相互独立,无需加锁,省掉锁的开销
  2. 多个worker进程互相不影响,提高稳定性
  3. 多进程提供性能

nginx利用多进程+非阻塞的模型,能轻松处理上万连接。其处理请求的大致过程为:

  • 一个连接请求过来,worker进程的监听套接字可读(这里涉及到惊群现象
  • 处理监听套接字可读事件,accept该连接
  • worker进程开始读取请求,解析请求,处理请求,回复数据,断开连接的流程
nginx事件处理模型

处理三种常见事件:信号、定时器、网络IO,其中信号有专门的handler来处理,定时器事件和网络IO在主循环中处理。

用一段伪代码来总结Nginx的事件处理机制:

代码语言:javascript
复制
while (true) {
    for t in run_tasks:
        t.handler();
    update_time(&now);
    timeout = ETERNITY;
    for t in wait_tasks: /* sorted already 处理定时器事件*/
        if (t.time <= now) {
            t.timeout_handler();
        } else {
            timeout = t.time - now;
            break;
        }
    nevents = poll_function(events, timeout);/*处理网络IO事件*/
    for i in nevents:
        task t;
        if (events[i].type == READ) {
            t.handler = read_handler;
        } else { /* events[i].type == WRITE */
            t.handler = write_handler;
        }
        run_tasks_add(t);
}
惊群现象

master进程会事先创建好监听套接字,然后fork worker子进程时,会继承监听套接字,当listen socket可读时,所有进程都将被唤醒,都会去accept这个请求,最终只有一个进程会成功,其他则失败,这就是惊群现象

nginx解决方法:提供一个ngx_accept_mutex,worker进程尝试accept之前会去获取该mutex,获取成功的采取accept连接。

nginx进程间通信

nginx的进程通信分为三种类别:linux 系统与nginx 通信, master 进程与worker进程通信, worker进程间通信。

  • linux 系统与nginx之间通信,通过信号进行,通过信号控制nginx重启、关闭以及加载配置文件等。
  • master进程与worker进程通信,socket方式,该种方式的优势是,统一封装网络IO事件,循环处理
  • worker进程之间通信,共享内存

Memcached总结

网络模型

memcached是一款服务器缓存软件,基于libvent开发,使用的多线程模型,主线程listen\accept,工作线程处理消息。

主要流程是:

  1. 创建主线程和若干个工作线程;
  2. 主线程监听、接受连接;
  3. 然后将连接信息分发(求余)到工作线程,每个工作线程有一个conn_queue处理队列;
  4. 工作线程从conn_queue中取连接,处理用户的命令请求并返回数据;

Redis事件模型

Redis采用单线程模型,通过IO多路复用来监听多个连接,非阻塞IO,同时单线程避免了不必要的锁的开销。

Redis同时处理文件事件和时间事件

文件事件,Redis将产生事件套接字放入一个队列中,然后依次分派给文件事件处理器;Redis编写了多个文件事件处理器,如

  • 连接应答处理器networking.c/acceptTcpHandler
  • 命令请求处理器networking.c/readQueryFromClinet
  • 命令回复处理器networking.c/sendReplyToClient

时间事件包含定时事件周期性事件,Redis将其放入一个无序链表中,每当时间事件执行器运行时,就遍历链表,查找已经到达的时间事件,调用相应的处理器。

Redis中一个重要的时间事件是serverCron,Redis利用该函数来定期对自身的资源和状态进行检查和调整,时间周期可以参考redis.conf关于hz选项说明,其主要工作包含:

  1. 更新服务器的各类统计信息
  2. 清理数据库中的过期键值对
  3. 关闭和清理失效的客户端连接
  4. 进行AOF和RDB持久化操作
  5. 如果服务器是主服务器,则进行定期同步
  6. 如果处于集群模式,对集群定期同步和连接测试

Redis主函数关于事件处理的代码表示如下:

代码语言:javascript
复制
def main():
    #一直循环处理事件
    while(not_stop){
        aeProcessEvents()
    }

下面展示aeProcessEvents调度文件事件和时间事件的过程:

代码语言:javascript
复制
def aeProcessEvents():
    time_event = aeSearchNearestTimer() #获取当前时间最近的时间事件
    remaind_ms = time_event.when - unix_ts_now() #获取最近的时间事件达到的毫秒时间
    if remaind_ms < 0 : #时间为负数,赋值0
        remaind_ms = 0
    timeval = create_timeval_with_ms(remainds_ms) #创建等待的时间结构
    aeApiPoll(timeval) #等待文件事件产生,时间取决于remainds_ms
    processFileEvent() #处理文件事件
    processTimeEvent() #处理时间事件

原文:

http://panzhengguang.github.io/2016/06/15/nginx_memcached_server_model/

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-05-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 nginx 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • nginx服务器模型
    • nginx进程模型
      • nginx事件处理模型
        • 惊群现象
          • nginx进程间通信
          • Memcached总结
            • 网络模型
            • Redis事件模型
            相关产品与服务
            云数据库 Redis
            腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档