Redis是一款基于键值对的数据结构存储系统,它的特点是基于内存操作、单线程处理命令、IO多路复用模型处理网络请求、键值对存储与简单丰富的数据结构等等
本篇文章主要围绕Redis中IO多路复用模型处理网络请求的特点来先从介绍IO模型,IO多路复用模型以及客户端与服务端的通信
等待数据:调用后需要等待数据准备好
复制数据:当准备好数据后,将数据从内核空间复制到用户空间
常见IO模型
一个线程处理一个客户端,同时处理大量网络请求时需要的线程太多,虽然线程IO请求时不阻塞,但是轮循发起IO请求会浪费CPU(CPU空转)
一个线程监听多个客户端,轮循select阻塞,监听到套接字触发读/写事件时再进行处理(循环处理可能有多个客户端同时触发读写事件)
没看懂IO多路复用模型的同学可以继续往下看,下文会详细介绍IO多路复用模型的流程
通信流程主要划分为:服务端要进行初始化,初始化后才开始循环处理事件,服务端在处理事件期间会维护客户端相关信息
初始化
处理事件可以看成处理客户端请求与维护管理服务端自身的资源
事件被分为文件事件和时间时间
文件事件常是处理客户端请求,时间事件常是定时、周期任务来检查/管理服务端资源
Redis 使用IO多路复用模型 监听多个客户端的套接字,当感知到套接字上发生事件时,将事件放入队列中,由文件事件分派器依次取出事件并交给对应事件处理器处理
事件类型可以分为读事件AE_READABLE、写事件AE_WRITEABLE,读写是以服务器为中心(起始)的,比如客户端发起连接请求、发送命令请求都是触发读事件,而客户端需要读响应时是触发写事件
事件处理器有连接应答处理器(处理连接的读事件),命令请求处理器(处理读事件),命令回复处理器(处理写事件),复制处理器(用于主从复制) 等等,本文主要使用连接应答、命令请求、回复三种处理器
时间事件分为定时时间事件和周期时间事件,定时为规定事件做一次,周期为以多少时间为周期做一次
时间事件处理器使用链表管理定时、周期事件,定期遍历链表,判断时间事件是否到期,到期则执行,执行完判断时间事件如果为定时则删除,为周期则更改下个周期到达时间
时间事件较少,基本上都是做一些定期检查,主要处理文件事件
服务器优先处理文件事件再处理时间事件
服务端使用RedisClient对象来存储客户端相关信息,使用链表管理RedisClient(所有连接的客户端)
定时任务通常用来管理服务器资源:更新缓冲时间、每秒执行命令数量、已使用内存峰值,处理sigterm信号关闭前RDB,管理客户端连接、数据库资源,判断是否需要持久化等
本文以Redis使用IO多路复用模型处理网络请求的为起点,介绍了IO模型,服务端初始化,服务端处理文件、时间事件,客户端信息以及完整的通信流程
同步阻塞IO模型,在处理大量网络请求时需要耗费一比一的线程,且发生系统调用读数据时线程会阻塞
同步非阻塞IO模型,虽然不阻塞但存在CPU空转,浪费性能
IO多路复用模型使用select监听套接字上的读写事件,select会阻塞,当监听到客户端套接字触发读写事件时,遍历处理所有套接字的读写事件
服务端初始化时主要是根据配置文件以及启动命令进行资源、数据结构的初始化,同时会根据持久化策略寻找RDB、AOF文件进行数据恢复,初始化完才开始循环处理事件
事件可以分为文件事件和时间事件,文件事件常用来处理客户端请求,分为读、写事件,当客户端套接字触发读、写事件时,将事件放入队列,文件事件分派器将队列中的事件依次交给对应的事件处理器;时间事件常是定时、周期任务,用来检查/管理服务端自身资源等
服务端处理事件期间,会使用链表管理维护客户端相关信息:输入缓冲区(序列化的命令请求)、命令与命令参数个数、命令相关信息(通过这些能够执行命令)、输出缓冲区(保存回复响应)
整体流程:
《Redis深度历险》
《Redis设计与实现》
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。