[Redis 5] Redis的单线程与多线程

文章目录

  • 相关问题
    • Redis6.0之前的版本真的是单线程吗?
    • Redis6.0之前为什么一直不使用多线程?
    • Redis6.0 之后为何引入了多线程?
    • Redis6.0默认是否开启了多线程?
    • Redis6.0多线程开启时,线程数如何设置?
    • Redis6.0采用多线程后,性能的提升效果如何?
    • Redis6.0多线程的实现机制?
    • 开启多线程后,是否会存在线程并发安全问题?
  • 参考链接

相关问题

Redis6.0之前的版本真的是单线程吗?

  • Redis 作为一个内存服务器,它需要处理很多来自外部的网络请求,它使用 I/O 多路复用机制同时监听多个文件描述符的可读和可写状态,一旦收到网络请求就会在内存中快速处理,由于绝大多数的操作都是纯内存的,所以处理的速度会非常地快。
  • Redis在处理客户端的请求时,包括获取 (socket 读)、解析、执行、内容返回 (socket 写) 等都由一个顺序串行的主线程处理,这就是所谓的“单线程”。但如果严格来讲从Redis4.0之后并不是单线程,除了主线程外,它也有后台线程在处理一些较为缓慢的操作,例如清理脏数据、无用连接的释放、大 key 的删除等等,例如 UNLINK、FLUSHALL ASYNC、FLUSHDB ASYNC 等非阻塞的删除操作

Redis6.0之前为什么一直不使用多线程?

  • Redis 的性能瓶颈不在 CPU ,主要在内存和网络
  • 单线程编程容易并且更容易维护
  • 多线程就会存在死锁、线程上下文切换等问题,甚至会影响性能
  • 大体上来说,Redis 6.0 之前主要还是单线程处理。

Redis is single threaded. How can I exploit multiple CPU / cores?

  • It’s not very frequent that CPU becomes your bottleneck with Redis, as usually Redis is either memory or network bound. For instance, using pipelining Redis running on an average Linux system can deliver even 1 million requests per second, so if your application mainly uses O(N) or O(log(N)) commands, it is hardly going to use too much CPU.
  • However, to maximize CPU usage you can start multiple instances of Redis in the same box and treat them as different servers. At some point a single box may not be enough anyway, so if you want to use multiple CPUs you can start thinking of some way to shard earlier.
  • You can find more information about using multiple Redis instances in the Partitioning page.
  • However with Redis 4.0 we started to make Redis more threaded. For now this is limited to deleting objects in the background, and to blocking commands implemented via Redis modules. For future releases, the plan is to make Redis more and more threaded.

Redis6.0 之后为何引入了多线程?

从Redis自身角度来说,因为读写网络的read/write系统调用占用了Redis执行期间大部分CPU时间,瓶颈主要在于网络的 IO 消耗, 优化主要有两个方向:

  • 提高网络 IO 性能,典型的实现比如使用 DPDK 来替代内核网络栈的方式
  • 使用多线程充分利用多核,典型的实现比如 Memcached。

协议栈优化的这种方式跟 Redis 关系不大,支持多线程是一种最有效最便捷的操作方式。所以总结起来,redis支持多线程主要就是两个原因:

  • 可以充分利用服务器 CPU 资源,目前主线程只能利用一个核
  • 多线程任务可以分摊 Redis 同步 IO 读写负荷

虽然,Redis6.0 引入了多线程,但是 Redis 的多线程只是在网络数据的读写这类耗时操作上使用了, 执行命令仍然是单线程顺序执行。因此,你也不需要担心线程安全问题。


Redis6.0默认是否开启了多线程?

Redis6.0 的多线程默认是禁用的,只使用主线程。如需开启需要修改 redis 配置文件 redis.conf :

io-threads-do-reads yes

开启多线程后,还需要设置线程数,否则是不生效的。同样需要修改 redis 配置文件 redis.conf :

io-threads 4 #官网建议4核的机器建议设置为2或3个线程,8核的建议设置为6个线程


Redis6.0多线程开启时,线程数如何设置?

关于线程数的设置,官方有一个建议:4核的机器建议设置为2或3个线程,8核的建议设置为6个线程,线程数一定要小于机器核数。还需要注意的是,线程数并不是越大越好,官方认为超过了8个基本就没什么意义了。


Redis6.0采用多线程后,性能的提升效果如何?

Redis 作者 antirez 在 RedisConf 2019分享时曾提到:Redis 6 引入的多线程 IO 特性对性能提升至少是一倍以上。国内也有大牛曾使用unstable版本在阿里云esc进行过测试,GET/SET 命令在4线程 IO时性能相比单线程是几乎是翻倍了。


Redis6.0多线程的实现机制?

[Redis 5] Redis的单线程与多线程_第1张图片
流程简述如下:

1、主线程负责接收建立连接请求,获取 socket 放入全局等待读处理队列

2、主线程处理完读事件之后,通过 RR(Round Robin) 将这些连接分配给这些 IO 线程

3、主线程阻塞等待 IO 线程读取 socket 完毕

4、主线程通过单线程的方式执行请求命令,请求数据读取并解析完成,但并不执行

5、主线程阻塞等待 IO 线程将数据回写 socket 完毕

6、解除绑定,清空等待队列

[Redis 5] Redis的单线程与多线程_第2张图片
该设计有如下特点:

1、IO 线程要么同时在读 socket,要么同时在写,不会同时读或写

2、IO 线程只负责读写 socket 解析命令,不负责命令处理


开启多线程后,是否会存在线程并发安全问题?

从上面的实现机制可以看出,Redis的多线程部分只是用来处理网络数据的读写和协议解析,执行命令仍然是单线程顺序执行。所以我们不需要去考虑控制 key、lua、事务,LPUSH/LPOP 等等的并发及线程安全问题。




参考链接

javaGuide
Redis 6.0 新特性-多线程连环13问!
Redis官网

你可能感兴趣的:(Redis,redis,多线程)