持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情
背景:
kafka性能优化时发现,资源扩充后,出现消费QPS不平稳问题,消费延迟20s,kafka频繁rebalance现象
Rebalance
什么是rebalance?是当消费者组发生变化,或者partition发生变化时。根据上面提到的某种策略进行对消费者进行分区的分配。
发生 rebalance 的时机:
- 组成员个数发生变化。例如有新的 consumer 实例加入该消费组或者离开组,获消费者挂了
- 订阅 topic 的分区数发生变化(订阅新的主题也可以理解成分区发生变化)
Rebalance 发生时,Group 下所有 Consumer 实例都会协调在一起共同参与,Kafka 能够保证尽量达到最公平的分配。但是 Rebalance 过程对 Consumer Group 会造成比较严重的影响。在 Rebalance 的过程中 Consumer Group 下的所有消费者实例都会停止工作(Stop The World),等待 Rebalance 过程完成。
原因:
var (
randomEngine = rand.New(rand.NewSource(time.Now().UnixNano()))
)
并发调用:randomEngine.Intn(10)
rand.Rand 并发panic: index out of range, 并发低时不会出现,并发高场景才能触发
解决:
rand线程不安全,safeRander解决
并发调用:randomEngine.Intn(10)
var (
randomEngine = NewSafeRander()
)
// SafeRander is used for avoiding to use global's rand;
type SafeRander struct {
pos uint32
randers [128]*rand.Rand
locks [128]*sync.Mutex
}
// NewSafeRander .
func NewSafeRander() *SafeRander {
var randers [128]*rand.Rand
var locks [128]*sync.Mutex
for i := 0; i < 128; i++ {
randers[i] = rand.New(rand.NewSource(time.Now().UnixNano()))
locks[i] = new(sync.Mutex)
}
return &SafeRander{
randers: randers,
locks: locks,
}
}
// Intn .
func (sr *SafeRander) Intn(n int) int {
x := atomic.AddUint32(&sr.pos, 1)
x %= 128
sr.locks[x].Lock()
n = sr.randers[x].Intn(n)
sr.locks[x].Unlock()
return n
}