您的位置:  首页 > 技术杂谈 > 正文

分布式问题系列--惊群

2021-10-25 15:00 https://my.oschina.net/lwl1989/blog/5286767 o0无忧亦无怖 次阅读 条评论

惊群

怎么理解

当你往一群鸽子中间扔一块食物,虽然最终只有一个鸽子抢到食物,但所有鸽子都会被惊动来争夺,没有抢到食物的鸽子只好回去继续睡觉, 等待下一块食物到来。这样,每扔一块食物,都会惊动所有的鸽子,即为惊群。

简单地说:就是扔一块食物,所有鸽子来抢,但最终只一个鸽子抢到了食物。

语义分析:食物只有一块,最终只有一个鸽子抢到,但是惊动了所有鸽子,每个鸽子都跑过来,消耗了每个鸽子的能量。(这个很符合达尔文的进化论,物种之间的竞争,适者生存。)

计算机中的惊群

  1. 在多进程/多线程等待同一资源时,也会出现惊群。即当某一资源可用时,多个进程/线程会惊醒,竞争资源。这就是操作系统中的惊群。

  2. 在分布式系统对同一资源进行更新的时候

惊群造成的影响

多进程/线程中:

  • 惊醒所有进程/线程,导致n-1个进程/线程做了无效的调度,上下文切换,cpu瞬时增高

  • 多个进程/线程争抢资源,所以涉及到同步问题,需对资源进行加锁保护,加解锁加大系统CPU开销

多进程/线程惊群常见分析

accept惊群

epoll惊群

nginx惊群

参考: nginx惊群处理

线程池惊群

在多线程设计中,经常会用到互斥和条件变量的问题。当一个线程解锁并通知其他线程的时候,就会出现惊群的现象。

​ pthread_mutex_lock/pthread_mutex_unlock:线程互斥锁的加锁及解锁函数。 ​ pthread_cond_wait:线程池中的消费者线程等待线程条件变量被通知; ​ pthread_cond_signal/pthread_cond_broadcast:生产者线程通知线程池中的某个或一些消费者线程池,接收处理任务; ​ 这里的惊群现象出现在3里,pthread_cond_signal,语义上看,是通知一个线程。调用此函数后,系统会唤醒在相同条件变量上等待的一个或多个线程(可参看手册)。如果通知了多个线程,则发生了惊群。

正常的用法:

  • 所有线程共用一个锁,共用一个条件变量

  • 当pthread_cond_signal通知时,就可能会出现惊群

解决惊群的方法:

  • 所有线程共用一个锁,每个线程有自已的条件变量
  • pthread_cond_signal通知时,定向通知某个线程的条件变量,不会出现惊群

业务中的惊群

缓存惊群

回想起当年在微博使用的多级cache(php+memcache+redis),memcache是为了节省网络IO做的本地缓存,miss之后从redis读取,数据变化之后会针对key对memcache notify发送消息。

惊群如何避免

总体来说,惊群是由于网络中事件的重复通知造成,从技术侧而言,最简单的方案就是对中间节点进行逻辑处理,避免掉不必要的通知。

各有各的好处,也各有各的弊端,要根据自己的需要选择合适的模式解决

加锁,性能开销

数据版本则会造成传输包成本增大

  • 0
    感动
  • 0
    路过
  • 0
    高兴
  • 0
    难过
  • 0
    搞笑
  • 0
    无聊
  • 0
    愤怒
  • 0
    同情
热度排行
友情链接