单进程单线程的 Redis 如何能够高并发

发布于 2023-03-15 12:29:23 字数 1174 浏览 62 评论 0

1、基本原理

采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络IO的时间消耗)

为什么不采用多进程或多线程处理?

  • 多线程处理可能涉及到锁
  • 多线程处理会涉及到线程切换而消耗 CPU

单线程处理的缺点?

  • 无法发挥多核CPU性能,不过可以通过在单机开多个 Redis 实例来完善

2、Redis 不存在线程安全问题?

  • Redis 采用了线程封闭的方式,把任务封闭在一个线程,自然避免了线程安全问题,不过对于需要依赖多个 redis 操作的复合操作来说,依然需要锁,而且有可能是分布式锁

3、什么是多路 I/O 复用(Epoll)

网络 IO 都是通过 Socket 实现,Server 在某一个端口持续监听,客户端通过 Socket(IP+Port)与服务器建立连接(ServerSocket.accept),成功建立连接之后,就可以使用Socket中封装的InputStream和OutputStream进行IO交互了。针对每个客户端,Server都会创建一个新线程专门用于处理

默认情况下,网络IO是阻塞模式,即服务器线程在数据到来之前处于【阻塞】状态,等到数据到达,会自动唤醒服务器线程,着手进行处理。阻塞模式下,一个线程只能处理一个流的IO事件

为了提升服务器线程处理效率,有以下三种思路

  • 非阻塞【忙轮询】:采用死循环方式轮询每一个流,如果有IO事件就处理,这样可以使得一个线程可以处理多个流,但是效率不高,容易导致 CPU 空转

  • Select 代理(无差别轮询):可以观察多个流的IO事件,如果所有流都没有IO事件,则将线程进入阻塞状态,如果有一个或多个发生了 IO 事件,则唤醒线程去处理。但是还是得遍历所有的流,才能找出哪些流需要处理。如果流个数为N,则时间复杂度为O(N)

  • Epoll 代理:Select 代理有一个缺点,线程在被唤醒后轮询所有的 Stream,还是存在无效操作。 Epoll 会哪个流发生了怎样的 I/O 事件通知处理线程,因此对这些流的操作都是有意义的,复杂度降低到了 O(1)

4、其它开源软件采用的模型

  • Nginx:多进程单线程模型
  • Memcached:单进程多线程模型

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

0 文章
0 评论
84960 人气
更多

推荐作者

emdigitizer10

文章 0 评论 0

残龙傲雪

文章 0 评论 0

奢望

文章 0 评论 0

微信用户

文章 0 评论 0

又爬满兰若

文章 0 评论 0

独孤求败

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文