这个底层操作主要要分reids 6和之后的。
redis 6之后:
客户端(Java 应用‑Jedis)
- 业务代码调用
jedis.set()Java 方法 - Jedis 内部把这个方法调用封装成 RESP 协议字节数组
- 通过底层TCP Socket ,将字节写入操作系统内核的发送缓冲区
- 操作系统内核把数据包通过网络发给 Redis 服务器
- Jedis 当前线程进入阻塞,等待 Socket 读取服务端返回数据
Redis 服务端机器(操作系统内核)
- 数据包到达 Redis 服务器,存入操作系统 Socket接收缓冲区
- Redis 主线程通过
epoll多路复用,检测到此 socket 有新数据就绪 - 主线程自己不去 read 读取数据,把该连接交给其中一个 IO 线程
Redis 服务端‑IO 线程(搬运工,只做网络、协议)
- IO 线程调用 read 系统调用,从内核缓冲区读出原始字节流
- IO 线程拆解 RESP 协议,把字节还原成 SET 命令、key、value
- 将解析完毕的命令提交给 Redis 主线程,IO 线程继续处理其他客户端 socket
Redis 服务端‑主线程(单线程,真正执行业务)
- 主线程拿到解析好的 SET 命令,单线程串行执行,修改 Redis 内存哈希表
- 生成执行成功的响应,封装成 RESP 协议字节,交给 IO 线程
Redis 服务端‑IO 线程
- IO 线程调用 write 系统调用,把 RESP 响应字节写入 Socket 内核发送缓冲区
- 操作系统网络回传给 Java 应用服务器
回到 Java‑Jedis 客户端
- Java 机器内核 Socket 收到响应字节
- 原本阻塞的 Jedis 线程读到字节流
- Jedis解析 RESP 协议,把字节转为 Java 结果(OK 字符串)
- 将结果返回给我们的业务代码,方法调用结束,阻塞解除
redis 6之前:
没有上述IO线程读取数据拆解RESP协议这些操作由主线程进行执行这些操作,由于主线程以后读不过来为了提高速度,引入了IO线程。