Redis 处理高并发
1 阻塞IO与非阻塞IO
Java在JDK1.4中引用NIO,阻塞IO与非阻塞IO的区别
在阻塞模式下,如果从数据流中读取不到指定大小的数据两,IO 就会阻塞。比如已知会有 10 个字节发送过来,但是目前只收到 4 个,还剩六个,此时就会发生阻塞。如果是非阻塞模式,虽然此时只收到 4 个字节,但是读到 4 个字节就会立即返回,不会等着,等另外 6 个字节来的时候,再去继续读取。
所以阻塞 IO 性能低于 非阻塞 IO。
如果有一个 Web 服务器,使用阻塞 IO 来处理请求,那么每一个请求都需要开启一个新的线程;但是如果使用了非阻塞 IO,基本上一个小小线程池就够用了,因为不会发生阻塞,每一个线程都能够高效利用。
2 Redis的线程模型
Redis 是单线程。单线程如何解决高并发问题的?
实际上,能够处理高并发的单线程应用不仅仅是 Redis,除了 Redis 之外,还有 NodeJS、Nginx 等等也是单线程。
Redis 虽然是单线程,但是运行很快,主要有如下几方面原因:
- Redis 中的所有数据都是基于内存的,所有的计算也都是内存级别的计算,所以快。
- Redis 是单线程的,所以有一些时间复杂度高的指令,可能会导致 Redis 卡顿,例如 keys。
- Redis 在处理并发的客户端连接时,使用了非阻塞 IO。
在使用非阻塞 IO 时,有一个问题,就是线程如何知道剩下的数据来了?
这里就涉及到一个新的概念叫做多路复用,本质上就是一个事件轮询 API。
- Redis 会给每一个客户端指令通过队列来排队进行顺序处理。
- Redis 做出响应时,也会有一个响应的队列。