为什么Redis是单线程的(事件驱动的)

Nis*_*hat 2 multithreading event-driven single-threaded redis

我正在努力了解Redis的基础知识.一直到处都是,Redis是单线程的,它使事情成为原子.但是我无法想象它是如何在内部工作的.我有一点疑问.

我们不设计服务器单线程,如果它是IO绑定应用程序(如Node.js),其中线程在启动IO操作后获得另一个请求,并在IO操作完成后将数据返回给客户端(提供并发).但是在redis的情况下,所有数据都可以在主内存中找到,我们根本不打算进行IO操作.那么为什么Redis是单线程的?如果第一个请求需要花费很多时间会发生什么,剩下的请求将不得不保留等候?

Car*_*auf 8

TL; DR:单线程使redis更简单,redis仍然是IO绑定.

内存是I/O. Redis仍然受I/O限制.当redis处于高负载并且达到每秒最大请求时,它通常缺乏网络带宽或内存带宽,并且通常不会占用大量CPU.某些命令对此不适用,但对于大多数用例,redis将严重受网络或内存的I/O限制.

除非内存和网络速度突然提高了几个数量级,否则单线程通常不是问题.如果您需要扩展超过一个或几个线程(即:master < - > slave < - > slave setup),您已经在查看Redis Cluster.在这种情况下,如果您以某种方式CPU缺乏并希望最大化线程数,则可以为每个CPU核心设置一个集群实例.

我不太熟悉redis源代码或内部代码,但我可以看到使用单个线程如何轻松实现无锁原子操作.线程会使这更复杂,并且似乎没有提供大的优势,因为redis不受CPU限制.在redis实例之上的级别实现并发似乎是一个很好的解决方案,也是Redis Sentinel和Redis Cluster帮助的.

当redis需要很长时间时,其他请求会发生什么?

当redis完成长请求时,其他请求将被阻止.如果需要,您可以使用该client-pause命令进行测试.


Ita*_*ber 7

当然,正确答案是卡尔的.然而.

在Redis v4中,我们看到了从大多数单线程转变为选择性和谨慎多线程的开始.模块和线程安全的上下文就是其中的一个例子.另外两个是新的UNLINK命令和ASYNC模式FLUSHDB/FLUSHALL.未来的计划是将主要事件循环(例如IO绑定任务)当前正在完成的更多工作卸载到工作线程.