2024-05-02
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://www.skjava.com/mianshi/baodian/detail/4165546593

这个问题要从两个层面来回答:

  1. Redis 服务端层面
  2. Redis 客户端层面

Redis 服务端层面

Redis 本身是线程安全的,就是说在 Redis Server 上执行的指令,不需要任何同步机制,也不会存在线程安全问题。主要原因有如下几个:

  1. 单线程机制:Redis 使用的是单线程模型处理指令,也就是说,在任何时候,只有一个线程(主线程)在执行指令。虽然 Redis 6.0 增加了多线程模型,但是增加的多线程模型也只是用来处理网络 I/O 事件,对于指令的执行,依然采用单线程。
  2. 原子操作:Redis 中的大多数命令都是原子性的,这说明 Redis 每个命令都会作为一个不可分割的整体执行,没有中途被打断的可能。

这里解释下为什么 Redis 不使用多线程来处理指令:

Redis 的作者认为 CPU 并不是制约 Redis 性能表现的瓶颈所在,Redis 更多的情况是受到内存大小和网络I/O的限制,所以 Redis 核心网络模型使用单线程并没有什么问题。而且使用单线程能够简化设计和降低开发复杂度。相比多线程使用单线程具有如下几个优势:

  1. 简化设计和开发:多线程编程会引入竞态条件、死锁等问题,相对复杂。而单线程模型避免这些问题,使得 Redis 的架构更简单、直观且易于维护。此外,单线程模型消除了多线程环境下的同步、锁等成本,而且在指令的执行过程不存在线程安全的问题。
  2. 充分利用I/O多路复用:Redis 使用 I/O 多路复用机制来同时处理大量客户端连接,即使在单线程模式下,它也可以在相应时间内处理更多的请求。由于 Redis 主要是以内存为基础的数据库,因此绝大多数操作都是 CPU 绑定的,所以它的性能主要受这些操作本身的时间复杂度所限制。
  3. 原子性操作: Redis 支持原子性操作,这是单线程模型的自然优势之一。在 Redis 中,一些常见操作,如自增、自减、集合操作等,可以在单个命令中执行,而不需要多个命令之间的锁操作。

Redis 客户端层面

虽然 Redis 本身是线程安全的,但是架不住使用它的人写的代码是线程不安全的啊?比如是非同步情况下执行多个指令,或者多个客户端同时处理同一个数据而不考虑分布式锁机制,这些情况下肯定是无法保证客户端的线程安全。

阅读全文