Redis——单线程?多线程?

1.Redis是单线程还是多线程的?

Redis6.0之前是单线程的,6.0是多线程的

其实严格来说,Redis6.0之前也并非只有一个线程,只是Redis在处理客户端请求时,包括获取 (socket 读)、解析、执行、内容返回 (socket 写) 等都是由一个串行的主线程来处理,这就是所谓的“单线程”。但它的其他功能比如持久化,异步删除,集群同步都是采用额外的线程来完成的。

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

  • 使用Redis时,几乎不存在CPU成为瓶颈的情况, Redis主要受限于内存和网络。使用单线程,可维护性高。
  • Redis使用IO多路复用等技术,使得处理性能非常高。
  • 单线程机制使得 Redis 内部实现的复杂度大大降低,Hash 的惰性 Rehash、Lpush 等等 “线程不安全” 的命令都可以无锁进行。
  • 多线程模型虽然在某些方面表现优异,但是它却引入了程序执行顺序的不确定性,带来了并发读写的一系列问题,增加了系统复杂度、同时可能存在线程切换、甚至加锁解锁、死锁造成的性能损耗。

3. Redis6.0为什么要引入多线程呢?

Redis将所有数据放在内存中,内存的响应时长大约为100纳秒,对于小数据包,Redis服务器可以处理80,000到100,000 QPS(QPS:query per second),这也是Redis处理的极限了,对于80%的公司来说,单线程的Redis已经足够使用了。

但随着越来越复杂的业务场景,有些公司动不动就上亿的交易量,因此需要更大的QPS。常见的解决方案是在分布式架构中对数据进行分区并采用多个服务器,但该方案有非常大的缺点,例如要管理的Redis服务器太多,维护代价大。

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

  • 提高网络 IO 性能,但这属于优化协议栈,跟 Redis 关系不大;

  • 使用多线程充分利用多核

支持多线程是一种最有效最便捷的操作方式。所以总结起来,redis支持多线程主要就是两个原因:

  • 可以充分利用服务器 CPU 资源,目前主线程只能利用一个核

  • 多线程任务可以分摊 Redis 同步 IO 读写负荷

4. Redis6.0的多线程是默认开启的吗?

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

5. 那么使用了多线程之后,Redis性能提升如何呢?

国内有大牛测试过,GET/SET 命令在4线程 IO时性能相比单线程是几乎是翻倍了。

要说明的是,Redis使用多线程,一定是Redis实例已经占用相当大的CPU耗时的时候才建议采用,否则使用多线程没有意义。所以估计80%的公司开发人员看看就好。如果开启多线程,至少要4核的机器。

6.简单说说Redis多线程的实现机制?

Redis——单线程?多线程?_第1张图片

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

2、主线程处理完读事件之后,通过轮询将这些连接分配给这些 IO 线程

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

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

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

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

该设计有如下特点:

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

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

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

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

你可能感兴趣的:(Redis,redis,网络,多线程,数据库)