cch123 / blog_comment

comments of xargin.com
8 stars 0 forks source link

一种持锁被调度的情况 #178

Open cch123 opened 3 years ago

cch123 commented 3 years ago

https://xargin.com/schedule-when-holding-lock-causes-latency-spike/

leafduo commented 3 years ago

不从调度器的层面上做些特别的事情感觉很难避免这样的情况吧,只有接受了

cch123 commented 3 years ago

@leafduo 不从调度器的层面上做些特别的事情感觉很难避免这样的情况吧,只有接受了

是的,没法解决

lesismal commented 3 years ago

这时锁冲突就是会导致整个服务因为锁冲突而直接崩掉(goroutine 暴涨 OOM 之类的,或者延迟大幅上升,不可用)。

这里的goroutine 暴涨 OOM 之类的是指 goroutine 数量暴涨吗?如果是,那不能怪调度,应该是业务协程池没有控制size的锅。mosn里的那个 pool 就有这个问题,之前跟 taoyuanyuan 聊到过: https://github.com/mosn/mosn/blob/dc582f2d5086969ec9a4c59ec36a98296d523fd3/pkg/sync/workerpool.go#53

应该也不能怪 rlock 吧,14之后的调度应该是任何一行代码的地方都可能被调度:

package main

import (
    "log"
    "runtime"
    "sync/atomic"
    "time"
)

func main() {
    n := 2
    sum := uint64(0)
    runtime.GOMAXPROCS(n)
    for i := 0; i < n; i++ {
        go func() {
            for {
                atomic.AddUint64(&sum, 1)
            }
        }()
    }

    time.Sleep(time.Second)
    for {
        log.Println(atomic.LoadUint64(&sum))
        time.Sleep(time.Second)
    }
}

output:

2021/08/05 15:11:22 66565770
2021/08/05 15:11:23 128544432
2021/08/05 15:11:24 190786970
2021/08/05 15:11:25 253885126
2021/08/05 15:11:26 317599683
...
cch123 commented 3 years ago

这时锁冲突就是会导致整个服务因为锁冲突而直接崩掉(goroutine 暴涨 OOM 之类的,或者延迟大幅上升,不可用)。

这里的goroutine 暴涨 OOM 之类的是指 goroutine 数量暴涨吗?如果是,那不能怪调度,应该是业务协程池没有控制size的锅。mosn里的那个 pool 就有这个问题,之前跟 taoyuanyuan 聊到过: https://github.com/mosn/mosn/blob/dc582f2d5086969ec9a4c59ec36a98296d523fd3/pkg/sync/workerpool.go#53

应该也不能怪 rlock 吧,14之后的调度应该是任何一行代码的地方都可能被调度:

package main

import (
  "log"
  "runtime"
  "sync/atomic"
  "time"
)

func main() {
  n := 2
  sum := uint64(0)
  runtime.GOMAXPROCS(n)
  for i := 0; i < n; i++ {
      go func() {
          for {
              atomic.AddUint64(&sum, 1)
          }
      }()
  }

  time.Sleep(time.Second)
  for {
      log.Println(atomic.LoadUint64(&sum))
      time.Sleep(time.Second)
  }
}

output:

2021/08/05 15:11:22 66565770
2021/08/05 15:11:23 128544432
2021/08/05 15:11:24 190786970
2021/08/05 15:11:25 253885126
2021/08/05 15:11:26 317599683
...

这个 rlock 被调度的问题是 1.14 之前就有的问题了 恒定 qps 压测的时候,压了几个小时突然 goroutine 暴涨, 我用 fgprof 曾经看到过是抢锁的 goroutine 突然变多了 这篇只是给出一种可能性,你说的 1.14 都被调度,理论上也确实是有可能的,只不过我当时压还没用 1.14

lesismal commented 3 years ago

我觉得即使1.14之前也不应该归咎于rlock,它本身就有runtime_SemacquireMutex的逻辑

如果goroutine暴涨是由于业务层的pool没有限制,那还是要通过业务层来解决