2.4 网络设计与redis、memcached、nginx组件

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 2.4 网络设计与redis、memcached、nginx组件

9589b9293a684fdb86ce344ce7c081b7.png

一、网络模块需要处理哪些事情

网络编程主要关注客户端与服务端交互的四个问题:

1、连接建立

2、消息到达

3、消息发送

4、连接断开

以上四个问题归结到底是网络IO,IO函数主要有两个作用:

1、检测IO是否就绪

2、进行IO操作—accept、connect、read、write

accept、connect是关于网络的连接建立。accept检测全连接队列中是否有数据,如果有则从中取出一个节点,返回一个对象clientfd,以及客户端的IP地址。connect是对于客户端而言,如果客户端收到ACK,即连接建立成功。(对应三次握手)

read是把数据从内核态read buffe拷贝到用户态中,当期为0代表read buffer中读到EOF

write是把数据从用户态拷贝到内核态write buffe中

读和写的区分:以“读书”和“写字”为例子。所谓读书:就是书籍上的文字通过人的视觉系统,经神经系统在大脑里产生主观映像;写字就是大脑里产生的主观映像通过神经系统控制运动器官——手在纸上写出字。“读”与“写”是把大脑作为中心,由外界向中心输入,就是“读”;由中心向外界输出就是“写”。现在“读”与“写”的问题就变成了输入和输出的关系了。

以电脑CPU为中心。从外界的设备(键盘,磁盘等等)向CPU传递信息就是“读操作”,由CPU向外界设备(屏幕,磁盘等等)传递信息就是“写操作”。

例如对于全双工通信的TCP协议

二、reactor网络设计模型

IO多路复用的主要功能是检测多条连接的IO是否就绪,但不具备具体IO操作的功能(比如读写数据)。常见的IO多路复用器有select、poll,epoll,他们是对IO的管理,检测接入的IO,触发IO事件;注意这三个都是同步IO。

reactor网络设计模型是把IO就绪检测的功能交由IO多路复用器实现,针对事件进行进行IO操作,不同的事件调用不同的回调函数。

int nready = epoll_wait(reactor.epfd, events, EVENTS_LEN, timeouts);
int i = 0;
for (i=0; i< nready; i++){
  if (events[i].events & EPOLLIN){//触发读事件
    listenfd --> 新连接到达--> accept
    clientfd --> 这条连接发送了数据 --> read
  }else{ //触发写事件
    connectfd --> 连接建立成功,可向第三方(如数据库)发送数据
    clientfd -->  这条连接写缓冲区可写 -->write
  }
}

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

三、网络模块与业务的关系

  1. 创建socket,生成listenfd,通过bind绑定,通过listen监听。
  2. 把listenfd注册到reactor,注册读事件(客户端与服务端建立连接)。
  3. 如果listenfd读事件触发,调用accept接收连接生成clientfd,然后把clientfd注册到reactor中,注册读事件(客户端向服务端发送数据)。
  4. 当客户端发送数据时,会触发clientfd写事件相应的回调函数。 读数据—解析(协议)数据—处理业务相关的计算—加密打包—回复数据


四、redis、memcached、nginx

1、redis

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


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


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

1、如果IO耗时,把IO操作放到IO线程池处理,主线程处理computer。

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


2、memcached

memcached是一个基于事件驱动的内存缓存服务器,它使用多个reactor来处理并发连接。

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


在默认情况下,memcached的工作线程数等于CPU核心数。


3、ngnix

Nginx是一个基于事件驱动的服务器,它通过多个reactor处理并发连接。


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

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

  1. 创建 Listenfd bind 监听
  2. worker 进程都有 Listenfd
  3. worker 进程争夺 accept 锁
  4. 谁争夺到了锁,谁就有接收新连接的权利
  5. 接收的连接放入该 worker


4、总结

redis是单线程单reactor,可以把IO放入线程池,也可以把业务计算部分放入线程池。

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

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

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
2月前
|
NoSQL 网络协议 Linux
Redis的实现一:c、c++的网络通信编程技术,先实现server和client的通信
本文介绍了使用C/C++进行网络通信编程的基础知识,包括创建socket、设置套接字选项、绑定地址、监听连接以及循环接受和处理客户端请求的基本步骤。
60 6
|
3月前
|
NoSQL 关系型数据库 Redis
mall在linux环境下的部署(基于Docker容器),Docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongo
mall在linux环境下的部署(基于Docker容器),docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongodb、minio详细教程,拉取镜像、运行容器
mall在linux环境下的部署(基于Docker容器),Docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongo
|
2月前
|
NoSQL 网络协议 应用服务中间件
redis,memcached,nginx网络组件
redis,memcached,nginx网络组件
22 0
|
2月前
|
存储 应用服务中间件 nginx
nginx数据结构组件二
nginx数据结构组件二
30 0
|
2月前
|
存储 监控 NoSQL
Redis的实现二: c、c++的网络通信编程技术,让服务器处理多个client
本文讨论了在C/C++中实现服务器处理多个客户端的技术,重点介绍了事件循环和非阻塞IO的概念,以及如何在Linux上使用epoll来高效地监控和管理多个文件描述符。
38 0
|
7月前
|
存储 NoSQL Redis
11- Redis 和 Memcached 的区别有哪些?
Redis与Memcached的主要区别在于:Redis提供复杂数据结构和丰富的操作,而Memcached只支持简单字符串;Redis原生支持集群,Memcached不支持;Memcached数据无法持久化,重启会丢失,但Redis支持持久化并能在重启后恢复数据。
137 12
|
5月前
|
存储 缓存 NoSQL
Redis问题之Redis与Memcached的主要区别是什么
Redis问题之Redis与Memcached的主要区别是什么
|
缓存 NoSQL Redis
Redis 和 Memcached 的区别
Redis和Memcached是两种常用的内存缓存系统,尽管它们都被用于提高应用程序的性能和扩展性,但它们在一些方面有所不同。
105 0
|
存储 缓存 NoSQL
redis 和 memcached 的区别
redis 和 memcached 的区别
100 0
|
存储 NoSQL Redis
Redis 与 Memcached的区别
Redis 与 Memcached的区别