Nis*_*hat 2 multithreading event-driven single-threaded redis
我正在努力了解Redis的基础知识.一直到处都是,Redis是单线程的,它使事情成为原子.但是我无法想象它是如何在内部工作的.我有一点疑问.
我们不设计服务器单线程,如果它是IO绑定应用程序(如Node.js),其中线程在启动IO操作后获得另一个请求,并在IO操作完成后将数据返回给客户端(提供并发).但是在redis的情况下,所有数据都可以在主内存中找到,我们根本不打算进行IO操作.那么为什么Redis是单线程的?如果第一个请求需要花费很多时间会发生什么,剩下的请求将不得不保留等候?
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
命令进行测试.
当然,正确答案是卡尔的.然而.
在Redis v4中,我们看到了从大多数单线程转变为选择性和谨慎多线程的开始.模块和线程安全的上下文就是其中的一个例子.另外两个是新的UNLINK
命令和ASYNC
模式FLUSHDB/FLUSHALL
.未来的计划是将主要事件循环(例如IO绑定任务)当前正在完成的更多工作卸载到工作线程.