redis相关概念解释

✅ 问题 1

我的 Redis 已经部署,我的 微服务创建连接就算一个连接吗?

微服务 什么时候算创建了一个 Redis 连接?Redis 会做什么?

一句话先回答你:

👉 是的,微服务只要 connect 成功,就算一个 Redis 连接

👉 Redis 会为这个连接创建一个 client 对象,并把 socket 纳入 epoll 监听


一、从"微服务侧"看:什么时候叫"创建连接"

1️⃣ 微服务什么时候会创建 Redis 连接?

通常是这几种时机之一:

  • 应用启动
    • Spring Bean 初始化
    • RedisTemplate / Redisson 初始化
  • 第一次访问 Redis
    • 懒加载连接
  • 连接池预热
    • 一次性建多个连接

2️⃣ 本质动作只有一个(非常关键)

无论你用的是:

  • Jedis
  • Lettuce
  • Redisson

最终都会执行一个 TCP connect

bash 复制代码
微服务 ---> Redis TCP 三次握手

TCP 三次握手完成 = Redis 认为这是一个连接


二、从 Redis 视角:一个连接发生时 Redis 做了什么?

当你的微服务完成 TCP 三次握手时:

① Redis accept() 连接
cpp 复制代码
conn_fd = accept(listen_fd)
② Redis 创建一个 client 结构体

你可以把它理解为:

bash 复制代码
client { socket_fd 输入缓冲区 输出缓冲区 状态信息 }

每一个连接 = Redis 内存里的一个 client 对象


③ Redis 把这个 socket 注册进 epoll
bash 复制代码
epoll_ctl(epfd, ADD, socket_fd, READ)

意思是:

"这个连接以后 只要有数据进来,你通知我"

👉 到这一步,这个连接正式进入 Redis 的 IO 多路复用体系


三、微服务什么时候"发信号"?Redis 什么时候工作?

✅ Redis 不会主动找客户端

✅ Redis 只响应客户端事件

常见触发点:

微服务行为 Redis 感知到什么
发送命令 socket 变为 可读
客户端断连 socket 关闭事件
Redis 写响应 socket 可写

四、总结问题 1(你可以直接记)

TCP 建立成功 = 一个 Redis 连接

一个连接 = Redis 一个 client 对象

每个 client 都被 epoll 监听

客户端发数据,Redis 才会行动


✅ 问题 2

"一个线程,同时监听多个 IO 连接"

这个线程 Redis 启动就有吗?什么时候消失?

一句话回答你:

👉 是的,Redis 启动时就创建了这个线程 👉 Redis 进程不退出,这个线程永远不会消失


一、Redis 启动时究竟创建了什么线程?

Redis 主线程 ✅(你问的就是它)

  • 唯一
  • 贯穿 Redis 生命周期
  • 负责:
    • epoll 监听
    • 读取请求
    • 执行命令
    • 写回响应

👉 这就是:

"一个线程监听多个 IO 连接"里的那个线程


二、这个线程在干什么?(事件循环)

Redis 的主线程本质是一个 死循环

cpp 复制代码
while (!server.shutdown) { epoll_wait(); 处理就绪 socket; 执行命令; }

🧠 你可以理解为:

Redis 一直在说:
"谁有事?谁有事?"


三、这个线程什么时候会"消失"?

只有一种情况

情况 结果
Redis 正常运行 不消失
Redis 崩溃 / stop 线程结束
kill -9 进程直接没了

连接断开不会销毁这个线程

空闲不会销毁这个线程


四、Redis 为什么不为每个连接创建线程?

👉 如果这样:

  • 10 万连接
  • 10 万线程
  • 频繁上下文切换

✅ Redis 的选择是:

宁愿监听,不等待


✅ 问题 2 核心总结

✅ 这个线程 Redis 启动时就存在

✅ 它是 Redis 的 心跳

✅ 它不随连接变化

✅ 它挂了,Redis 就挂了


✅ 问题 3(最重要)

从 "部署 Redis → 连接 → epoll → 使用"

每一步 Redis 都在干什么?

下面是 完整真实时间线


🔹 第一阶段:Redis 启动(此时还没客户端)

1️⃣ 创建监听 socket

cpp 复制代码
listen_fd = socket() bind() listen()

✅ 等客户端来连


2️⃣ 创建 epoll 实例

cpp 复制代码
epfd = epoll_create()

3️⃣ 把 listen_fd 加入 epoll

cpp 复制代码
epoll_ctl(epfd, ADD, listen_fd, READ)

意思是:

"有客户端来连我时,叫醒我"


4️⃣ 进入主事件循环

cpp 复制代码
while(true) { epoll_wait() }

✅ 此刻 Redis 空转但不耗 CPU


🔹 第二阶段:微服务启动,连接 Redis

1️⃣ 客户端发起 TCP 连接

bash 复制代码
CONNECT redis:6379

2️⃣ 内核通知 epoll:listen_fd 可读

✅ epoll_wait 返回


3️⃣ Redis accept 连接

cpp 复制代码
conn_fd = accept()

4️⃣ Redis 创建 client 对象

  • 分配内存
  • 初始化 buffer
  • 绑定 socket_fd

5️⃣ Redis 注册 client socket 到 epoll

cpp 复制代码
epoll_ctl(epfd, ADD, conn_fd, READ)

✅ 等客户发命令


🔹 第三阶段:微服务发送 Redis 命令

1️⃣ 客户端发送数据

bash 复制代码
SET a 1

2️⃣ socket 变为可读

  • 数据进入内核 buffer
  • epoll 被唤醒

3️⃣ Redis read 数据

cpp 复制代码
read(conn_fd, input_buf)

4️⃣ Redis 解析命令(单线程)

bash 复制代码
SET a 1

5️⃣ Redis 执行命令(内存)

bash 复制代码
dict[a] = 1

✅ 无锁

✅ O(1)


6️⃣ Redis 写入输出缓冲区

bash 复制代码
+OK

7️⃣ epoll 监听可写事件

cpp 复制代码
epoll_ctl(MOD, conn_fd, WRITE)

8️⃣ 数据写回客户端

cpp 复制代码
write(conn_fd)

🔹 第四阶段:连接空闲 / 断开

空闲

  • Redis 不管
  • epoll 继续监听

客户端关闭

  • socket 关闭
  • epoll 收到事件
  • Redis 回收 client 对象
  • 释放内存

✅ 最终"全景一句话"(非常重要)

Redis 在启动时就创建 epoll 和主线程,

所有客户端连接只是被 登记监听
谁先准备好,主线程就处理谁,永不等待。

相关推荐
Geoking.12 分钟前
Redis 的 RDB 与 AOF:持久化机制全解析
数据库·redis·缓存
鱼跃鹰飞41 分钟前
面试题:说一说redis和Memcached的区别
数据库·redis·memcached
让我上个超影吧3 小时前
天机学堂——BitMap实现签到
java·数据库·spring boot·redis·spring cloud
Carry灭霸4 小时前
【BUG】Redisson Connection refused 127.0.0.1
java·redis
无限码力4 小时前
华为OD技术面真题 - 数据库Redis - 1
redis·华为od·华为od技术面真题·华为od技术面八股·华为od技术面八股文·华为od技术面redis问题
想搞艺术的程序员4 小时前
架构破局 - Redis 不再做缓存!替代 MySQL 做主存储
redis·缓存·架构
码农水水4 小时前
米哈游Java面试被问:Shenandoah GC的Brooks Pointer实现机制
java·开发语言·jvm·spring boot·redis·安全·面试
heartbeat..4 小时前
Redis Cluster (Redis 集群模式)从入门到精通:架构解析、机制详解与运维排查
java·运维·redis·架构·nosql
澄风5 小时前
Redis ZSet+Lua脚本+SpringBoot实战:滑动窗口限流方案从原理到落地
spring boot·redis·lua
醒过来摸鱼6 小时前
redis源码deps目录
数据库·redis·缓存