4.网络设计与redis、memcached、nginx组件(二)

系列文章目录

第四章 网络设计与redis、memcached、nginx组件(一)

第五章 网络设计与redis、memcached、nginx组件(二)


### 文章目录

  • [系列文章目录](#文章目录 系列文章目录 @TOC 前言 一、reactor模型? 二、Reactor 开发 1.建立连接 三、典型reactor 模型 单reactor 模型 典型 readis radis 中优化 多reactor 模型 多线程(one eventloop per thread) 典型 memcached 为什么支持多线程 多reactor 多reactor 模型 多进程 (one eventloop per process) 典型引用 nginx nginx流程 总结)
  • [@[TOC](文章目录)](#文章目录 系列文章目录 @TOC 前言 一、reactor模型? 二、Reactor 开发 1.建立连接 三、典型reactor 模型 单reactor 模型 典型 readis radis 中优化 多reactor 模型 多线程(one eventloop per thread) 典型 memcached 为什么支持多线程 多reactor 多reactor 模型 多进程 (one eventloop per process) 典型引用 nginx nginx流程 总结)
  • [前言](#文章目录 系列文章目录 @TOC 前言 一、reactor模型? 二、Reactor 开发 1.建立连接 三、典型reactor 模型 单reactor 模型 典型 readis radis 中优化 多reactor 模型 多线程(one eventloop per thread) 典型 memcached 为什么支持多线程 多reactor 多reactor 模型 多进程 (one eventloop per process) 典型引用 nginx nginx流程 总结)
  • [一、reactor模型?](#文章目录 系列文章目录 @TOC 前言 一、reactor模型? 二、Reactor 开发 1.建立连接 三、典型reactor 模型 单reactor 模型 典型 readis radis 中优化 多reactor 模型 多线程(one eventloop per thread) 典型 memcached 为什么支持多线程 多reactor 多reactor 模型 多进程 (one eventloop per process) 典型引用 nginx nginx流程 总结)
  • [二、Reactor 开发](#文章目录 系列文章目录 @TOC 前言 一、reactor模型? 二、Reactor 开发 1.建立连接 三、典型reactor 模型 单reactor 模型 典型 readis radis 中优化 多reactor 模型 多线程(one eventloop per thread) 典型 memcached 为什么支持多线程 多reactor 多reactor 模型 多进程 (one eventloop per process) 典型引用 nginx nginx流程 总结)
  • [1.建立连接](#文章目录 系列文章目录 @TOC 前言 一、reactor模型? 二、Reactor 开发 1.建立连接 三、典型reactor 模型 单reactor 模型 典型 readis radis 中优化 多reactor 模型 多线程(one eventloop per thread) 典型 memcached 为什么支持多线程 多reactor 多reactor 模型 多进程 (one eventloop per process) 典型引用 nginx nginx流程 总结)
  • [三、典型reactor 模型](#文章目录 系列文章目录 @TOC 前言 一、reactor模型? 二、Reactor 开发 1.建立连接 三、典型reactor 模型 单reactor 模型 典型 readis radis 中优化 多reactor 模型 多线程(one eventloop per thread) 典型 memcached 为什么支持多线程 多reactor 多reactor 模型 多进程 (one eventloop per process) 典型引用 nginx nginx流程 总结)
  • [单reactor 模型](#文章目录 系列文章目录 @TOC 前言 一、reactor模型? 二、Reactor 开发 1.建立连接 三、典型reactor 模型 单reactor 模型 典型 readis radis 中优化 多reactor 模型 多线程(one eventloop per thread) 典型 memcached 为什么支持多线程 多reactor 多reactor 模型 多进程 (one eventloop per process) 典型引用 nginx nginx流程 总结)
  • [典型 readis](#文章目录 系列文章目录 @TOC 前言 一、reactor模型? 二、Reactor 开发 1.建立连接 三、典型reactor 模型 单reactor 模型 典型 readis radis 中优化 多reactor 模型 多线程(one eventloop per thread) 典型 memcached 为什么支持多线程 多reactor 多reactor 模型 多进程 (one eventloop per process) 典型引用 nginx nginx流程 总结)
  • [radis 中优化](#文章目录 系列文章目录 @TOC 前言 一、reactor模型? 二、Reactor 开发 1.建立连接 三、典型reactor 模型 单reactor 模型 典型 readis radis 中优化 多reactor 模型 多线程(one eventloop per thread) 典型 memcached 为什么支持多线程 多reactor 多reactor 模型 多进程 (one eventloop per process) 典型引用 nginx nginx流程 总结)
  • [多reactor 模型 多线程(one eventloop per thread)](#文章目录 系列文章目录 @TOC 前言 一、reactor模型? 二、Reactor 开发 1.建立连接 三、典型reactor 模型 单reactor 模型 典型 readis radis 中优化 多reactor 模型 多线程(one eventloop per thread) 典型 memcached 为什么支持多线程 多reactor 多reactor 模型 多进程 (one eventloop per process) 典型引用 nginx nginx流程 总结)
  • [典型 memcached](#文章目录 系列文章目录 @TOC 前言 一、reactor模型? 二、Reactor 开发 1.建立连接 三、典型reactor 模型 单reactor 模型 典型 readis radis 中优化 多reactor 模型 多线程(one eventloop per thread) 典型 memcached 为什么支持多线程 多reactor 多reactor 模型 多进程 (one eventloop per process) 典型引用 nginx nginx流程 总结)
  • [为什么支持多线程 多reactor](#文章目录 系列文章目录 @TOC 前言 一、reactor模型? 二、Reactor 开发 1.建立连接 三、典型reactor 模型 单reactor 模型 典型 readis radis 中优化 多reactor 模型 多线程(one eventloop per thread) 典型 memcached 为什么支持多线程 多reactor 多reactor 模型 多进程 (one eventloop per process) 典型引用 nginx nginx流程 总结)
  • [多reactor 模型 多进程 (one eventloop per process)](#文章目录 系列文章目录 @TOC 前言 一、reactor模型? 二、Reactor 开发 1.建立连接 三、典型reactor 模型 单reactor 模型 典型 readis radis 中优化 多reactor 模型 多线程(one eventloop per thread) 典型 memcached 为什么支持多线程 多reactor 多reactor 模型 多进程 (one eventloop per process) 典型引用 nginx nginx流程 总结)
  • [典型引用 nginx](#文章目录 系列文章目录 @TOC 前言 一、reactor模型? 二、Reactor 开发 1.建立连接 三、典型reactor 模型 单reactor 模型 典型 readis radis 中优化 多reactor 模型 多线程(one eventloop per thread) 典型 memcached 为什么支持多线程 多reactor 多reactor 模型 多进程 (one eventloop per process) 典型引用 nginx nginx流程 总结)
  • [nginx流程](#文章目录 系列文章目录 @TOC 前言 一、reactor模型? 二、Reactor 开发 1.建立连接 三、典型reactor 模型 单reactor 模型 典型 readis radis 中优化 多reactor 模型 多线程(one eventloop per thread) 典型 memcached 为什么支持多线程 多reactor 多reactor 模型 多进程 (one eventloop per process) 典型引用 nginx nginx流程 总结)
  • [总结](#文章目录 系列文章目录 @TOC 前言 一、reactor模型? 二、Reactor 开发 1.建立连接 三、典型reactor 模型 单reactor 模型 典型 readis radis 中优化 多reactor 模型 多线程(one eventloop per thread) 典型 memcached 为什么支持多线程 多reactor 多reactor 模型 多进程 (one eventloop per process) 典型引用 nginx nginx流程 总结)

前言

此文章主要是是介绍一下reactor 模型和典型的reactor模型开源软件介绍分析。


一、reactor模型?

复制代码
Reactor 模型的核心就是把对网络IO的处理转变成对事件的处理。 把网络IO检测功能交由IO多路复用(epoll  select poll)实现检测fd 状态,针对时间的处理进行IO操作,不同职能事件通过不同的事件函数处理。

IO多路复用的主要功能是检测多条链路的状态(可读 可写 错误 断开等),但不具备具体IO操作的功能(比如读写数据)。IO多路复用都是同步网络IO ,常见的IO多路复用器有select、poll,epoll,他们是对IO的管理,检测接入的IO,触发IO事件;注意这三个都是同步IO。

之所以把IO就绪检测的功能交由IO多路复用器,是因为对于服务端而言,某一时刻只有少量的连接有数据交互,如果让IO函数自己检测,在阻塞IO时,每个连接都需要一个线程;非阻塞IO时,每个连接都需要通过while在应用层进行检测。

二、Reactor 开发

1.建立连接

代码如下(示例):

c 复制代码
//1.服务端作为被动建立连接
// listenfd 注册监听listenfd 的事件
struct epoll_event  ev;
ev.events = EPOLLIN;
ev.date.fd = listenfd;

epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev);

// 触发listenfd 的读事件,调用accept 接受新的连接

clientfd = accept(listen_fd,(struct sockaddr *)&addr, sizeof(addr))

ev.events = EPOLLIN;

ev.date.fd = clientfd;

epoll_ctl(epfd, EPOLL_CTL_ADD,clientfd, &ev);

.//服务端主动

// 1. 创建 socket 建立连接

int connectfd = socket(AF_INET, SOCK_STREAM, 0);

connect(connectfd, (struct sockaddr *)&addr,

sizeof(addr));

// 2. 注册监听 connectfd 的写事件

struct epoll_event ev;

ev.events = EPOLLOUT;

ev.data.fd = connetfd

epoll_ctl(efd, EPOLL_CTL_ADD, connectfd, &ev);

// 3. 当 connectfd 写事件被触发,连接建立成功

if (status == e_connecting && e->events &

EPOLLOUT) {

status == e_connected;

// 这里需要把写事件关闭

epoll_ctl(epfd, EPOLL_CTL_DEL, connectfd,

NULL);

}

三、典型reactor 模型

单reactor 模型

典型 readis

redis命令行采用了单reactor 网络事件模型,在启动时会创建一个I/O多路复用的事件处理器(即reactor)用于监听链路的状态,然后将所有客户端请求都注册到该事件处理器中。当有新连接到达或者已有连接有数据可读写时,事件处理器就会触发相应的回调函数进行处理。

由于redis是单线程运行的,因此只需要一个reactor即可满足其并发处理需求。通过合理地利用CPU资源和异步非阻塞IO技术,redis可以实现高效地处理大量并发请求。

radis 中优化

需要注意的是,当Redis遇到某些长时间执行的命令时,可能会导致其他请求被阻塞而影响整个系统性能。比如三个客户端同时向服务端发送数据,服务端是按先后顺序接收处理。这种就会出现如果先到的数据处理比较耗时,会导致后续客户端出现饥饿现象。优化方式是:

1、如果IO耗时,把IO操作放到IO线程池处理,主线程处理computer。read 、write、encode 、decode等丢入线程池处理

2、如果computer耗时,采用分治思想或者不同时间复杂度的算法

多reactor 模型 多线程(one eventloop per thread)

模型图

典型 memcached

memcached是一个基于事件驱动的内存缓存服务器,它使用多个reactor来处理并发连接。开启多个线程,每个线程中都有一个独立的reactor 对象。

为什么支持多线程 多reactor

memcached 也是kv类型的数据库,但是value 支持数据结构比较单一不支持多种数据结构, 对于锁的处理比较简单。

具体来说,memcached使用一个主线程和多个工作线程。每个工作线程都有自己的reactor,用于处理客户端连接和请求。当有新连接到达时,主线程(master epoll )会将新的fd分配给某个工作线程,并且该工作线程的reactor会负责处理这个连接的所有事件。

多reactor 模型 多进程 (one eventloop per process)

模型

典型引用 nginx

nginx是一个基于事件驱动的服务器,它通过多个reactor处理并发连接,它采用多进程的方式(master、slave worker)模型

具体来说,Nginx使用一个主进程(master)和多个worker进程。每个worker进程都有自己的reactor队形,用于处理客户端连接和请求。当有新连接到达时,主进程会将其分配给某个worker进程,并且该worker进程的reactor会负责处理这个连接的所有事件。

在默认情况下,Nginx的worker进程数等于CPU核心数。

nginx流程

Master process 创建的时候会监听listenfd, 然后在fork 出work 进程, work 进程当中都会有一个listenfd 的备份。每个work 进程会创建自己的epoll 对象。并且把listenfd交割epoll 对象管理. 多个进程都监听了listenfd 的读事件,如果listenfd 的全链接队列当中,加入节点的时候,他就会给每一个epoll 对象发送信号,每个epoll 对象都会去触发读事件。这样就产生了惊群现象。在用户层解决这个问题,通过在work 进程当中添加共享锁的方式解决。


总结

单线程单reactor模型,典型是radis 可以把IO放入线程池,也可以把业务计算部分放入线程池。通过回调的方式处理

多线程多reactor模型 如果业务之间交互比较多,但加锁简单,可以用多线程memcached

多进程多reactor模型 如果业务之间交互比较少,可以用多进程ngnix

相关推荐
Orlando cron2 小时前
Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?
网络·tcp/ip·kubernetes
1.01^10004 小时前
[3-02-01].第13节:三方整合 - Jedis客户端操作Redis
redis
KKKlucifer5 小时前
加密通信 + 行为分析:运营商行业安全防御体系重构
网络·安全·重构
achene_ql7 小时前
select、poll、epoll 与 Reactor 模式
linux·服务器·网络·c++
黎相思8 小时前
应用层自定义协议与序列化
运维·服务器·网络
开航母的李大8 小时前
【中间件】Web服务、消息队列、缓存与微服务治理:Nginx、Kafka、Redis、Nacos 详解
前端·redis·nginx·缓存·微服务·kafka
Lightning-py9 小时前
Linux命令cat /proc/net/snmp查看网络协议层面统计信息
网络·网络协议·tcp/ip
langmeng1109 小时前
使用docker在3台服务器上搭建基于版本redis 6.x的一主两从模式
运维·redis·docker·容器·集群
wo32586614510 小时前
浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
开发语言·网络·php
光路科技11 小时前
TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?
服务器·网络·重构