【后端面经】【缓存】36|Redis 单线程:为什么 Redis 用单线程而 Memcached 用多线程?--epoll调用和中断

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 【5月更文挑战第18天】`epoll`包含红黑树和就绪列表,用于高效管理文件描述符。关键系统调用有3个:`epoll_create()`创建epoll结构,`epoll_ctl()`添加/删除/修改文件描述符,`epoll_wait()`获取就绪文件描述符。`epoll_wait()`可设置超时时间(-1阻塞,0立即返回,正数等待指定时间)。当文件描述符满足条件(如数据到达)时,通过中断机制(如网卡或时钟中断)更新就绪列表,唤醒等待的进程。

再介绍一下epoll的基本结构和系统调用

epoll里有两个关键结构。一个是红黑树,每一个节点都代表了一个文件描述符;另外一个是双向链表,也叫做就绪列表。

为了维护epoll的结构,有三个关键的系统调用。

  1. epoll_create:也就是创建一个epoll结构

  2. epoll_ctl:管理epoll里面那些文件描述符,简单来说就是增删改查那些文件描述符

  3. epoll_wait:根据你的要求,返回符合条件的文件描述符,也就是查。

那么显然你可以猜到,如果你写一个从网络中读取数据的程序,看起来应该是这样的

epoll = epoll_create();
// fd 是一个套接字对应的文件描述符,并且告诉它,你关心读事件
// 你可以加很多个
epoll_ctl(epoll, ADD, fd, READ)
while true {
  // 你需要可读数据的套接字,等待时间是 1000 毫秒
  fds = epoll_wait(epoll, READ, 1000)
  // 一步步处理
}

你可以进一步补充epoll是怎么把文件描述符挪到就绪列表的。

需要注意的是,epoll并不是在我发起epoll调用的时候才把文件描述符挪到就序列表的。而是在epoll创建之后,不管你有没有发起epoll_wait调用,只要文件描述符满足条件了,就会被挪到就绪列表。

发起epoll调用

因此,当你发起epoll_wait的时候,有两种情况。第一种情况是就绪列表里面有符合条件的套接字,直接给你。

第二种情况就是就绪列表里面没有符合条件的套接字,这时候传入不同的超时时间,会有不同的响应。记住关键字,-1永远阻塞,0立刻返回,正数等待直到超时。

如果在发起超时调用的时候,传入的超时时间是-1,那么调用者会被阻塞,直到有满足条件的文件描述符。如果传入的超时时间是0,那么会立刻返回,不管有没有满足条件的文件描述符。如果传入的是正数n,那么就会最多等待n毫秒,直到有数据或超时。

亮点:epoll与中断

可以刷一个亮点,就是epoll怎么知道数据来了?又或者epoll怎么知道超时了?答案是中断,也就是在操作系统基本原理里学到的中断。

每一个和IO有关的文件描述符都有一个对应的驱动,这个驱动会告诉epoll发生了什么。比如说,当有数据发送到网卡的时候,会触发一个中断。借助这个中断,网卡的驱动会告诉epoll,这里有数据了。而超时也是利用了中断,不过是时钟中断。时钟中断之后,内核会去检查发起epoll_wait的线程有没有超时,如果超时了就唤醒这个线程。调用者会得到超时响应。

这部分内容我建议你主动提起,因为很少有面试官会在面试中追问到这里。而且,你可以将比较上层的应用原理和底层的中断机制关联在一起,能体现你计算机基础很扎实。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
3月前
|
存储 缓存 关系型数据库
Django后端架构开发:缓存机制,接口缓存、文件缓存、数据库缓存与Memcached缓存
Django后端架构开发:缓存机制,接口缓存、文件缓存、数据库缓存与Memcached缓存
60 0
|
4月前
|
存储 缓存 算法
深入了解Memcached:缓存技术的利器
Memcached是一个开源的高性能分布式内存缓存系统,用于加速动态Web应用。它通过将数据库查询结果、API调用结果或其他数据缓存到内存中,减少对数据库的访问频率,从而提高应用的响应速度。本文详细介绍了Memcached的基本原理、架构、安装配置、使用方法、测试方法以及应用场景。通过Memcached,开发者可以有效提升Web应用的性能,减少数据库负载,改善用户体验。
59 5
|
3月前
|
缓存 关系型数据库 MySQL
【缓存大对决】Memcached VS MySQL查询缓存,谁才是真正的性能之王?
【8月更文挑战第24天】在现代Web应用中,缓存技术对于提升性能与响应速度至关重要。本文对比分析了Memcached与MySQL查询缓存这两种常用方案。Memcached是一款高性能分布式内存对象缓存系统,支持跨服务器共享缓存,具备灵活性与容错性,但受限于内存大小且不支持数据持久化。MySQL查询缓存内置在MySQL服务器中,简化了缓存管理,特别适用于重复查询,但功能较为单一且扩展性有限。两者各有所长,实际应用中可根据需求单独或结合使用,实现最佳性能优化。
101 0
|
4月前
|
设计模式 存储 缓存
Java面试题:结合设计模式与并发工具包实现高效缓存;多线程与内存管理优化实践;并发框架与设计模式在复杂系统中的应用
Java面试题:结合设计模式与并发工具包实现高效缓存;多线程与内存管理优化实践;并发框架与设计模式在复杂系统中的应用
52 0
|
4月前
|
存储 安全 Java
Java面试题:假设你正在开发一个Java后端服务,该服务需要处理高并发的用户请求,并且对内存使用效率有严格的要求,在多线程环境下,如何确保共享资源的线程安全?
Java面试题:假设你正在开发一个Java后端服务,该服务需要处理高并发的用户请求,并且对内存使用效率有严格的要求,在多线程环境下,如何确保共享资源的线程安全?
65 0
|
4月前
|
NoSQL 网络协议 Linux
【AKS+Redis】AKS中客户端(ioredis)遇见Azure Redis服务Failover后链接中断的可能性
在AKS中,NodeJS应用使用ioredis连接Redis时,在Redis升级或故障转移时可能出现长时间无法恢复连接的问题。这可能由于TCP重连机制,默认可能等待13分钟。为解决此问题,可以调整Linux的TCP设置(如`net.ipv4.tcp_retries2`设为5),并利用ioredis的`retryStrategy`选项自定义重连策略,减少延迟。参考[ioredis文档](https://github.com/redis/ioredis?tab=readme-ov-file#auto-reconnect)以优化重连行为。
|
5月前
|
NoSQL Redis
Redis的单线程和高性能
Redis 的单线程主要是指 Redis 的网络 I0 和键值对读写是由一个线程来完成的,这也是 Redis 对外提供键值存储服务的主要流程。 但Redis 的其他功能,比如持久化、异步删除、集群数据同步等,其实是由额外的线程执行的。
27 0
|
5月前
|
缓存 Java Spring
SpringBoot配置第三方专业缓存技术Memcached 下载 安装 整合测试 2024年5000字详解
SpringBoot配置第三方专业缓存技术Memcached 下载 安装 整合测试 2024年5000字详解
44 0
|
6月前
|
NoSQL 网络协议 关系型数据库
redis-学习笔记(redis 单线程模型)
redis-学习笔记(redis 单线程模型)
53 3
|
6月前
|
NoSQL 关系型数据库 MySQL
Redis -- 单线程模型
Redis -- 单线程模型
64 1