perrynzhou

专注于系统组件研发

0%

epoll中惊群效应解决方法

epoll中惊群效应解决方法

epoll惊群效应复现

  • 创建5个进程,父进程负责fork所有的子进程,然后等待子进程退出,每个子进程监听监听同一个端口,接受来自客户单请求

  • 客户端连接服务端的同一个端口,服务端只有一个子进程响应该请求

  • strace每个子进程的系统调用,可以发现客户端的请求仅仅只有一个子进程响应,其他的子进程都做了无效的系统调用,这种现象叫做惊群效应,假设在10W个并发链接的情况下,这种无效的系统调用非常影响请求处理的吞吐量和处理性能。子进程10012、10014、10015,出现了“accept(3, 0x7fff66a88dc0, [16]) = -1 EAGAIN (Resource temporarily unavailable)”,接受客户端请求失败,仅仅是10013接受客户端请求成功,并且处理了客户端请求。

解决方法

  • linux 内核中accept惊群问题:linux 内核accept之所以阻塞是因为条件等待,这种现象和线程池的惊群效应是一致的,2.6内核之前是通过广播方式通知,2.6内核之后采用了发送信号量,解决了accept的惊群问题。

  • epoll的惊群问题:

    • 互斥锁:在epoll_wait前后加互斥锁会导致线程或者进程挂起,在高并发的情况下,严重影响请求处理的图屯粮,这种性能损耗基本无法接受。
    • 自旋锁: 在epoll_wait前后加spinlock,spinlock是独占的,虽然不会导致线程切换,但是会导致其他的监听进程或者线程饿死,这种情况也是无法接受的。
    • 原子操作/CAS:惊群问题通用解决方法是通过原子操作,原子操作通过汇编实现。